[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')
+ 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')
+ 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)
+ 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
+ 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(58)
+ for podName in tmpPodNames:
+ mySSH.command(f'oc logs --tail=1 {podName} 2>&1', '\$', 6, silent=True, resync=True)
+ time.sleep(2)
+ if mySSH.getBefore().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 c9f0a579e1..9adead3a68 100644
--- a/ci-scripts/conf_files/benetel-5g.conf
+++ b/ci-scripts/conf_files/benetel-5g.conf
@@ -92,9 +92,9 @@ gNBs =
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 74;
zeroCorrelationZoneConfig = 13;
- preambleReceivedTargetPower = -118;
+ #preambleReceivedTargetPower = -118;
#preambleReceivedTargetPower = -104;
- #preambleReceivedTargetPower = -108;
+ preambleReceivedTargetPower = -108;
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax = 6;
#powerRampingStep
@@ -124,13 +124,13 @@ gNBs =
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0,
# pusch-ConfigCommon (up to 16 elements)
- initialULBWPk2_0 = 6; # used for UL slot
+ initialULBWPk2_0 = 2; # used for UL slot
initialULBWPmappingType_0 = 1
initialULBWPstartSymbolAndLength_0 = 55; # this is SS=0 L=12
- initialULBWPk2_1 = 6; # used for mixed slot
+ initialULBWPk2_1 = 2; # used for mixed slot
initialULBWPmappingType_1 = 1;
- initialULBWPstartSymbolAndLength_1 = 24; # this is SS=10 L=2
+ initialULBWPstartSymbolAndLength_1 = 69; # this is SS=10 L=2
initialULBWPk2_2 = 7; # used for Msg.3 during RA
initialULBWPmappingType_2 = 1;
diff --git a/ci-scripts/conf_files/channelmod_rfsimu.conf b/ci-scripts/conf_files/channelmod_rfsimu.conf
new file mode 100644
index 0000000000..9a6ded24f1
--- /dev/null
+++ b/ci-scripts/conf_files/channelmod_rfsimu.conf
@@ -0,0 +1,57 @@
+#/* configuration for channel modelisation */
+#/* To be included in main config file when */
+#/* channel modelisation is used (rfsimulator with chanmod options enabled) */
+channelmod = {
+ max_chan=10;
+ modellist="modellist_rfsimu_1";
+ modellist_rfsimu_1 = (
+ {
+ model_name = "rfsimu_channel_enB0"
+ type = "AWGN";
+ ploss_dB = 0;
+ noise_power_dB = -10;
+ forgetfact = 0;
+ offset = 0;
+ ds_tdl = 0;
+ },
+ {
+ model_name = "rfsimu_channel_ue1"
+ type = "AWGN";
+ ploss_dB = 0;
+ noise_power_dB = 0;
+ forgetfact = 0;
+ offset = 0;
+ ds_tdl = 0;
+ }
+ );
+ modellist_rfsimu_2 = (
+ {
+ model_name = "rfsimu_channel_ue0"
+ type = "AWGN";
+ ploss_dB = 0;
+ noise_power_dB = 0;
+ forgetfact = 0;
+ offset = 0;
+ ds_tdl = 0;
+ },
+ {
+ model_name = "rfsimu_channel_ue1"
+ type = "AWGN";
+ ploss_dB = 0;
+ noise_power_dB = 0;
+ forgetfact = 0;
+ offset = 0;
+ ds_tdl = 0;
+ },
+ {
+ model_name = "rfsimu_channel_ue2"
+ type = "AWGN";
+ ploss_dB = 0;
+ noise_power_dB = 0;
+ forgetfact = 0;
+ offset = 0;
+ ds_tdl = 0;
+ }
+ );
+};
+
diff --git a/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf
index 4d89ad96da..087ee37f01 100644
--- a/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf
+++ b/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf
@@ -260,7 +260,6 @@ NETWORK_CONTROLLER :
FLEXRAN_CACHE = "/mnt/oai_agent_cache";
FLEXRAN_AWAIT_RECONF = "no";
};
-
log_config :
{
global_log_level ="info";
@@ -279,3 +278,4 @@ NETWORK_CONTROLLER :
rrc_log_verbosity ="medium";
};
+@include "channelmod_rfsimu.conf"
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 0da833b3f7..f0c1caef7e 100644
--- a/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf
+++ b/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf
@@ -58,27 +58,14 @@ gNBs =
initialDLBWPsearchSpaceZero = 0;
#pdsch-ConfigCommon
#pdschTimeDomainAllocationList (up to 16 entries)
- initialDLBWPk0_0 = 0;
- #initialULBWPmappingType
- #0=typeA,1=typeB
- initialDLBWPmappingType_0 = 0;
- #this is SS=2,L=3
- initialDLBWPstartSymbolAndLength_0 = 40;
+ initialDLBWPk0_0 = 0; #for DL slot
+ initialDLBWPmappingType_0 = 0; #0=typeA,1=typeB
+ initialDLBWPstartSymbolAndLength_0 = 40; #this is SS=1,L=13
- initialDLBWPk0_1 = 0;
- initialDLBWPmappingType_1 = 0;
- #this is SS=2,L=12
- initialDLBWPstartSymbolAndLength_1 = 53;
+ initialDLBWPk0_3 = 0; #for mixed slot
+ initialDLBWPmappingType_3 = 0;
+ initialDLBWPstartSymbolAndLength_3 = 57; #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;
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 261;
diff --git a/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf
index b8a601ce41..6d08dfb5c1 100644
--- a/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf
+++ b/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf
@@ -56,27 +56,14 @@ gNBs =
initialDLBWPsearchSpaceZero = 0;
#pdsch-ConfigCommon
#pdschTimeDomainAllocationList (up to 16 entries)
- initialDLBWPk0_0 = 0;
- #initialULBWPmappingType
- #0=typeA,1=typeB
- initialDLBWPmappingType_0 = 0;
- #this is SS=1,L=13
- initialDLBWPstartSymbolAndLength_0 = 40;
+ initialDLBWPk0_0 = 0; #for DL slot
+ initialDLBWPmappingType_0 = 0; #0=typeA,1=typeB
+ initialDLBWPstartSymbolAndLength_0 = 40; #this is SS=1,L=13
- initialDLBWPk0_1 = 0;
- initialDLBWPmappingType_1 = 0;
- #this is SS=2,L=12
- initialDLBWPstartSymbolAndLength_1 = 53;
+ initialDLBWPk0_3 = 0; #for mixed slot
+ initialDLBWPmappingType_3 = 0;
+ initialDLBWPstartSymbolAndLength_3 = 57; #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
- initialDLBWPstartSymbolAndLength_3 = 57;
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 66;
@@ -132,20 +119,18 @@ gNBs =
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0,
# pusch-ConfigCommon (up to 16 elements)
- initialULBWPk2_0 = 6;
+ initialULBWPk2_0 = 6; # used for UL slot
initialULBWPmappingType_0 = 1
- # this is SS=0 L=11
- initialULBWPstartSymbolAndLength_0 = 55;
+ initialULBWPstartSymbolAndLength_0 = 55; # this is SS=0 L=12
- initialULBWPk2_1 = 6;
+ initialULBWPk2_1 = 6; # used for mixed slot
initialULBWPmappingType_1 = 1;
- # this is SS=0 L=12
- initialULBWPstartSymbolAndLength_1 = 69;
+ initialULBWPstartSymbolAndLength_1 = 69; # this is SS=10 L=2
- initialULBWPk2_2 = 7;
+ initialULBWPk2_2 = 7; # used for Msg.3 during RA
initialULBWPmappingType_2 = 1;
- # this is SS=10 L=4
- initialULBWPstartSymbolAndLength_2 = 52;
+ initialULBWPstartSymbolAndLength_2 = 52; # this is SS=10 L=4
+
msg3_DeltaPreamble = 1;
p0_NominalWithGrant =-90;
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 b1d72c2269..43e4c6b493 100644
--- a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf
+++ b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf
@@ -56,27 +56,13 @@ gNBs =
initialDLBWPsearchSpaceZero = 0;
#pdsch-ConfigCommon
#pdschTimeDomainAllocationList (up to 16 entries)
- initialDLBWPk0_0 = 0;
- #initialULBWPmappingType
- #0=typeA,1=typeB
- initialDLBWPmappingType_0 = 0;
- #this is SS=1,L=13
- initialDLBWPstartSymbolAndLength_0 = 40;
+ initialDLBWPk0_0 = 0; #for DL slot
+ initialDLBWPmappingType_0 = 0; #0=typeA,1=typeB
+ initialDLBWPstartSymbolAndLength_0 = 40; #this is SS=1,L=13
- initialDLBWPk0_1 = 0;
- initialDLBWPmappingType_1 = 0;
- #this is SS=2,L=12
- initialDLBWPstartSymbolAndLength_1 = 53;
-
- 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=5
- initialDLBWPstartSymbolAndLength_3 = 57;
+ initialDLBWPk0_1 = 0; #for mixed slot
+ initialDLBWPmappingType_1 = 0;
+ initialDLBWPstartSymbolAndLength_1 = 57; #this is SS=1,L=5
#uplinkConfigCommon
#frequencyInfoUL
@@ -132,20 +118,17 @@ gNBs =
restrictedSetConfig = 0,
# pusch-ConfigCommon (up to 16 elements)
- initialULBWPk2_0 = 6;
+ initialULBWPk2_0 = 6; # used for UL slot
initialULBWPmappingType_0 = 1
- # this is SS=0 L=11
- initialULBWPstartSymbolAndLength_0 = 55;
+ initialULBWPstartSymbolAndLength_0 = 55; # this is SS=0 L=12
- initialULBWPk2_1 = 6;
+ initialULBWPk2_1 = 6; # used for mixed slot
initialULBWPmappingType_1 = 1;
- # this is SS=0 L=12
- initialULBWPstartSymbolAndLength_1 = 69;
+ initialULBWPstartSymbolAndLength_1 = 69; # this is SS=10 L=2
- initialULBWPk2_2 = 7;
+ initialULBWPk2_2 = 7; # used for Msg.3 during RA
initialULBWPmappingType_2 = 1;
- # this is SS=10 L=4
- initialULBWPstartSymbolAndLength_2 = 52;
+ initialULBWPstartSymbolAndLength_2 = 52; # this is SS=10 L=4
msg3_DeltaPreamble = 1;
p0_NominalWithGrant =-90;
@@ -248,7 +231,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.usrpb210.conf b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf
index 7be25a24fa..846623e0c1 100644
--- a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf
+++ b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf
@@ -58,27 +58,14 @@ gNBs =
initialDLBWPsearchSpaceZero = 0;
#pdsch-ConfigCommon
#pdschTimeDomainAllocationList (up to 16 entries)
- initialDLBWPk0_0 = 0;
- #initialULBWPmappingType
- #0=typeA,1=typeB
- initialDLBWPmappingType_0 = 0;
- #this is SS=1,L=13
- initialDLBWPstartSymbolAndLength_0 = 40;
+ initialDLBWPk0_0 = 0; #for DL slot
+ initialDLBWPmappingType_0 = 0; #0=typeA,1=typeB
+ initialDLBWPstartSymbolAndLength_0 = 40; #this is SS=1,L=13
- initialDLBWPk0_1 = 0;
- initialDLBWPmappingType_1 = 0;
- #this is SS=2,L=12
- initialDLBWPstartSymbolAndLength_1 = 53;
+ initialDLBWPk0_1 = 0; #for mixed slot
+ initialDLBWPmappingType_1 = 0;
+ initialDLBWPstartSymbolAndLength_1 = 57; #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;
#uplinkConfigCommon
#frequencyInfoUL
ul_frequencyBand = 78;
@@ -133,20 +120,17 @@ gNBs =
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0,
# pusch-ConfigCommon (up to 16 elements)
- initialULBWPk2_0 = 2;
+ initialULBWPk2_0 = 2; # used for UL slot
initialULBWPmappingType_0 = 1
- # this is SS=0 L=11
- initialULBWPstartSymbolAndLength_0 = 55;
-
- initialULBWPk2_1 = 2;
- initialULBWPmappingType_1 = 1;
- # this is SS=0 L=12
- initialULBWPstartSymbolAndLength_1 = 69;
+ initialULBWPstartSymbolAndLength_0 = 55; # this is SS=0 L=12
- initialULBWPk2_2 = 7;
+ initialULBWPk2_1 = 2; # used for mixed slot
+ initialULBWPmappingType_1 = 1;
+ initialULBWPstartSymbolAndLength_1 = 69; # this is SS=10 L=2
+
+ initialULBWPk2_2 = 7; # used for Msg.3 during RA
initialULBWPmappingType_2 = 1;
- # this is SS=10 L=4
- initialULBWPstartSymbolAndLength_2 = 52;
+ initialULBWPstartSymbolAndLength_2 = 52; # this is SS=10 L=4
msg3_DeltaPreamble = 1;
p0_NominalWithGrant =-90;
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/html.py b/ci-scripts/html.py
index a0ac638573..5cdaaa0c39 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,18 +436,20 @@ 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()
@@ -562,5 +569,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 47e1265985..389e7f8614 100644
--- a/ci-scripts/main.py
+++ b/ci-scripts/main.py
@@ -44,6 +44,7 @@ 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
@@ -419,6 +420,7 @@ 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
@@ -428,7 +430,7 @@ ldpc=cls_physim.PhySim() #create an instance for LDPC test using GPU or CPU b
#-----------------------------------------------------------
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)
@@ -783,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 5bac3846c9..d787f627cd 100644
--- a/ci-scripts/ran.py
+++ b/ci-scripts/ran.py
@@ -693,8 +693,8 @@ class RANManagement():
NSA_RAPROC_PUSCH_check = 0
#dlsch and ulsch statistics (dictionary)
dlsch_ulsch_stats = {}
- #count "L1 thread not ready" msg
- L1_thread_not_ready_cnt = 0
+ #real time statistics (dictionary)
+ real_time_stats = {}
#count "problem receiving samples" msg
pb_receiving_samples_cnt = 0
@@ -856,16 +856,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 = {'dlsch_rounds','dlsch_total_bytes','ulsch_rounds','ulsch_total_bytes_scheduled'}
+ keys = {'UE ID','dlsch_rounds','dlsch_total_bytes','ulsch_rounds','ulsch_total_bytes_scheduled', 'scheduling timing stats'}
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())
- #count "L1 thread not ready" msg
- result = re.search('\[PHY\]\s+L1_thread isn\'t ready', str(line))
- if result is not None:
- L1_thread_not_ready_cnt += 1
+ #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:
+ result = re.search(k, line)
+ if result is not None:
+ #remove 1- all useless char before relevant info 2- trailing char
+ 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:
@@ -896,15 +901,10 @@ class RANManagement():
statMsg = '[RAPROC] PUSCH with TC_RNTI message check for ' + nodeB_prefix + 'NB : PASS '
htmlMsg = statMsg+'\n'
else:
- statMsg = '[RAPROC] PUSCH with TC_RNTI message check for ' + nodeB_prefix + 'NB : FAIL '
+ statMsg = '[RAPROC] PUSCH with TC_RNTI message check for ' + nodeB_prefix + 'NB : FAIL or not relevant'
htmlMsg = statMsg+'\n'
logging.debug(statMsg)
htmleNBFailureMsg += htmlMsg
- #L1 thread not ready log
- statMsg = '[PHY] L1 thread is not ready msg count = '+str(L1_thread_not_ready_cnt)
- htmlMsg = statMsg+'\n'
- logging.debug(statMsg)
- htmleNBFailureMsg += htmlMsg
#problem receiving samples log
statMsg = '[PHY] problem receiving samples msg count = '+str(pb_receiving_samples_cnt)
htmlMsg = statMsg+'\n'
@@ -919,6 +919,18 @@ class RANManagement():
logging.debug(dlsch_ulsch_stats[key])
htmleNBFailureMsg += statMsg
+ #real time statistics statistics
+ 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
+ else:
+ statMsg = 'No real time stats found in the log file\n'
+ logging.debug('No real time stats found in the log file')
+ htmleNBFailureMsg += statMsg
+
if uciStatMsgCount > 0:
statMsg = nodeB_prefix + 'NB showed ' + str(uciStatMsgCount) + ' "uci->stat" message(s)'
logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
diff --git a/ci-scripts/ran_dashboard.py b/ci-scripts/ran_dashboard.py
new file mode 100644
index 0000000000..601cda1722
--- /dev/null
+++ b/ci-scripts/ran_dashboard.py
@@ -0,0 +1,275 @@
+#/*
+# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+# * contributor license agreements. See the NOTICE file distributed with
+# * this work for additional information regarding copyright ownership.
+# * The OpenAirInterface Software Alliance licenses this file to You under
+# * the OAI Public License, Version 1.1 (the "License"); you may not use this file
+# * except in compliance with the License.
+# * You may obtain a copy of the License at
+# *
+# * http://www.openairinterface.org/?page_id=698
+# *
+# * Unless required by applicable law or agreed to in writing, software
+# * distributed under the License is distributed on an "AS IS" BASIS,
+# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# * See the License for the specific language governing permissions and
+# * limitations under the License.
+# *-------------------------------------------------------------------------------
+# * For more information about the OpenAirInterface (OAI) Software Alliance:
+# * contact@openairinterface.org
+# */
+#---------------------------------------------------------------------
+# Merge Requests Dashboard for RAN on googleSheet
+#
+# Required Python Version
+# Python 3.x
+#
+#---------------------------------------------------------------------
+
+#-----------------------------------------------------------
+# Import
+#-----------------------------------------------------------
+
+#import google spreadsheet API
+import gspread
+from oauth2client.service_account import ServiceAccountCredentials
+
+
+import subprocess
+import shlex #lexical analysis
+import json #json structures
+import datetime #now() and date formating
+from datetime import datetime
+
+#-----------------------------------------------------------
+# Class Declaration
+#-----------------------------------------------------------
+
+class gDashboard:
+ def __init__(self, creds_file, spreadsheet, worksheet): #"creds.json", 'OAI RAN Dashboard', 'MR Status'
+ self.scope = ["https://spreadsheets.google.com/feeds",'https://www.googleapis.com/auth/spreadsheets',"https://www.googleapis.com/auth/drive.file","https://www.googleapis.com/auth/drive"]
+ self.creds = ServiceAccountCredentials.from_json_keyfile_name(creds_file, self.scope)
+ self.client = gspread.authorize(self.creds)
+ #spreadsheet
+ self.ss = self.client.open(spreadsheet)
+ #worksheet
+ self.sheet = self.ss.worksheet(worksheet)
+ self.ss.del_worksheet(self.sheet) #start by deleting the old sheet
+ self.sheet = self.ss.add_worksheet(title=worksheet, rows="100", cols="20") #create a new one
+
+ self.d = {} #data dictionary
+
+
+ def fetchData(self,cmd):
+ #cmd="""curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100" """
+ process = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE)
+ output = process.stdout.readline()
+ tmp=output.decode("utf-8")
+ self.d = json.loads(tmp)
+
+
+ def gBuild(self, destinationSheetName):
+
+ #line 1 : update date/time, format dd/mm/YY H:M:S
+ now = datetime.now()
+ dt_string = "Update : " + now.strftime("%d/%m/%Y %H:%M")
+ row =[dt_string]
+ self.sheet.insert_row(row, index=1, value_input_option='RAW')
+
+ #line 2 empty
+ #line 3 is for the column names
+ i=3
+ row =["MR","Created_at","Author","Title","Assignee", "Reviewer", "CAN START","IN PROGRESS","COMPLETED","OK MERGE","Merge conflicts"]
+ self.sheet.insert_row(row, index=i, value_input_option='RAW')
+
+ #line 4 onward, MR data lines
+ for x in range(len(self.d)):
+ i=i+1
+ date_time_str = self.d[x]['created_at']
+ date_time_obj = datetime.strptime(date_time_str, '%Y-%m-%dT%H:%M:%S.%fZ')
+
+ milestone1=milestone2=milestone3=milestone4=""
+ if self.d[x]['milestone']!=None:
+ if self.d[x]['milestone']['title']=="REVIEW_CAN_START":
+ milestone1="X"
+ elif self.d[x]['milestone']['title']=="REVIEW_IN_PROGRESS":
+ milestone2="X"
+ elif self.d[x]['milestone']['title']=="REVIEW_COMPLETED_AND_APPROVED":
+ milestone3="X"
+ elif self.d[x]['milestone']['title']=="OK_TO_BE_MERGED":
+ milestone4="X"
+ else:
+ pass
+ else:
+ pass
+
+ #check if empty or not
+ if self.d[x]['assignee']!=None:
+ assignee = str(self.d[x]['assignee']['name'])
+ else:
+ assignee = ""
+
+ #check if empty or not
+ if len(self.d[x]['reviewers'])!=0:
+ reviewer = str(self.d[x]['reviewers'][0]['name'])
+ else:
+ reviewer = ""
+
+ if self.d[x]['has_conflicts']==True:
+ conflicts = "YES"
+ else:
+ conflicts = ""
+
+ #build final row to be inserted, the first column is left empty for now, will be filled afterward with hyperlinks to gitlab MR
+ row =["", str(date_time_obj.date()),str(self.d[x]['author']['name']),str(self.d[x]['title']),\
+ assignee, reviewer,\
+ milestone1,milestone2,milestone3,milestone4,conflicts]
+
+ #insert the row to worksheet
+ self.sheet.insert_row(row, index=i, value_input_option='RAW')
+
+
+ #add MR hyperlinks in a list of requests to be sent as one update batch; this to save API calls (quotas)
+ i=3
+ requests=[]
+ for x in range(len(self.d)):
+ rowIndex=i
+ colIndex=0
+ hyperlink= '\"'+"https://gitlab.eurecom.fr/oai/openairinterface5g/-/merge_requests/"+ str(self.d[x]['iid']) +'\"'
+ text= '\"'+str(self.d[x]['iid'])+'"'
+ requests.append(self.addHyperlink(hyperlink, text, destinationSheetName, rowIndex, colIndex))
+ i=i+1
+ body = {"requests": requests}
+ self.ss.batch_update(body)
+
+
+
+ def addHyperlink(self, hyperlink, text, destinationSheetName, rowIndex, colIndex):
+ sheetId = self.ss.worksheet(destinationSheetName)._properties['sheetId']
+ request =\
+ {
+ "updateCells": {
+ "rows": [
+ {
+ "values": [
+ {
+ "userEnteredValue": {
+ "formulaValue":"=HYPERLINK({},{})".format(hyperlink, text)
+ }
+ }
+ ]
+ }
+ ],
+ "fields": "userEnteredValue",
+ "start": {
+ "sheetId": sheetId,
+ "rowIndex": rowIndex,
+ "columnIndex": colIndex
+ }
+ }
+ }
+ return request
+
+
+
+ def gFormat(self,sourceSheetName,destinationSheetName): # "Formating" , "MR Status"
+ #the requests are appended in a list of requests to be sent as one update batch; this to save API calls (quotas)
+ #copy formating template
+ sourceSheetId = self.ss.worksheet(sourceSheetName)._properties['sheetId']
+ destinationSheetId = self.ss.worksheet(destinationSheetName)._properties['sheetId']
+ requests=[]
+ requests.append(
+ {
+ "copyPaste": {
+ "source": {
+ "sheetId": sourceSheetId,
+ "startRowIndex": 0,
+ "endRowIndex": 40,
+ "startColumnIndex": 0,
+ "endColumnIndex": 12
+ },
+ "destination": {
+ "sheetId": destinationSheetId,
+ "startRowIndex": 0,
+ "endRowIndex": 40,
+ "startColumnIndex": 0,
+ "endColumnIndex": 12
+ },
+ "pasteType": "PASTE_FORMAT"
+ }
+ }
+ )
+
+
+ #resize columns fit to data, except col 0
+ sheetId = self.ss.worksheet(destinationSheetName)._properties['sheetId']
+ requests.append(
+ {
+ 'autoResizeDimensions': {
+ 'dimensions': {
+ 'sheetId': sheetId,
+ 'dimension': 'COLUMNS',
+ 'startIndex': 1,
+ 'endIndex': 12
+ }
+ }
+ }
+ )
+
+
+ #resize col 0
+ sheetId = self.ss.worksheet(destinationSheetName)._properties['sheetId']
+ requests.append(
+ {
+ "updateDimensionProperties": {
+ "range": {
+ "sheetId": sheetId,
+ "dimension": "COLUMNS",
+ "startIndex": 0,
+ "endIndex": 1
+ },
+ "properties": {
+ "pixelSize": 100
+ },
+ "fields": "pixelSize"
+ }
+ }
+ )
+
+
+ #resize milestones to be cleaner
+ sheetId = self.ss.worksheet(destinationSheetName)._properties['sheetId']
+ requests.append(
+ {
+ "updateDimensionProperties": {
+ "range": {
+ "sheetId": sheetId,
+ "dimension": "COLUMNS",
+ "startIndex": 6,
+ "endIndex": 10
+ },
+ "properties": {
+ "pixelSize": 135
+ },
+ "fields": "pixelSize"
+ }
+ }
+ )
+
+ body = {"requests": requests}
+ self.ss.batch_update(body)
+
+
+
+def main():
+ my_gDashboard=gDashboard("/home/oaicicd/remi/creds.json", 'OAI RAN Dashboard', 'MR Status')
+ cmd="""curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100" """
+ my_gDashboard.fetchData(cmd)
+ my_gDashboard.gBuild("MR Status")
+ my_gDashboard.gFormat("Formating" , "MR Status")
+
+
+
+if __name__ == "__main__":
+ # execute only if run as a script
+ main()
diff --git a/ci-scripts/reportBuildLocally.sh b/ci-scripts/reportBuildLocally.sh
index b46ade903f..eab005c740 100755
--- a/ci-scripts/reportBuildLocally.sh
+++ b/ci-scripts/reportBuildLocally.sh
@@ -568,33 +568,6 @@ function report_build {
echo " Ubuntu 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 " " >> ./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 6725d2f62b..cb751c3830 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..4a0992436b 100644
--- a/ci-scripts/sshconnection.py
+++ b/ci-scripts/sshconnection.py
@@ -111,11 +111,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:
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/gnb_phytest_usrp_run.xml b/ci-scripts/xml_files/gnb_phytest_usrp_run.xml
new file mode 100644
index 0000000000..00610d430e
--- /dev/null
+++ b/ci-scripts/xml_files/gnb_phytest_usrp_run.xml
@@ -0,0 +1,53 @@
+
+
+ gNB-PHY-Test
+ Run-gNB-PHY-Test
+ tasks
+ 2
+
+090101 000001 090109
+
+
+
+
+ Initialize_eNB
+ Initialize gNB USRP
+ -O ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf --phy-test -q -U 787200 -T 106 -t 28 -D 130175 -m 28 -M 106
+ NR
+
+
+
+ IdleSleep
+ Sleep
+ 180
+
+
+
+
+ Terminate_eNB
+ Terminate gNB
+ NR
+
+
+
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/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index e723f34d2e..8bf57f460e 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -45,6 +45,8 @@ include_directories(${CONFIG_INCLUDE_DIRS})
pkg_search_module(CRYPTO libcrypto REQUIRED)
include_directories(${CRYPTO_INCLUDE_DIRS})
+#uhd 4.0 and iris installs by default in /usr/local
+include_directories("/usr/local/include/")
#use native cmake method as this package is not in pkg-config
if (${RF_BOARD} STREQUAL "OAI_USRP")
find_package(Boost REQUIRED)
@@ -52,7 +54,7 @@ if (${RF_BOARD} STREQUAL "OAI_USRP")
elseif (${RF_BOARD} STREQUAL "OAI_IRIS")
include_directories("${OPENAIR_TARGETS}/ARCH/IRIS/USERSPACE/LIB/")
- include_directories("/usr/local/include/")
+
set(HW_SOURCE ${HW_SOURCE}
${OPENAIR_TARGETS}/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp)
LINK_DIRECTORIES("/usr/local/lib")
@@ -410,6 +412,7 @@ add_boolean_option(UE_AUTOTEST_TRACE False "Activate UE autotest specific logs
add_boolean_option(UE_DEBUG_TRACE False "Activate UE debug trace")
add_boolean_option(UE_TIMING_TRACE False "Activate UE timing trace")
add_boolean_option(DEBUG_CONSOLE False "makes debugging easier, disables stdout/stderr buffering")
+add_boolean_option(NEW_GTPU False "NEW_GTP")
set (OCP_ITTI ${OPENAIR_DIR}/common/utils/ocp_itti)
add_library(ITTI
@@ -418,7 +421,6 @@ add_library(ITTI
)
add_dependencies(ITTI rrc_flag)
set(ITTI_LIB ITTI)
- set(GTPU_need_ITTI ${OPENAIR3_DIR}/GTPV1-U/gtpv1u_eNB.c)
##################################################
@@ -2233,26 +2235,21 @@ add_library(CN_UTILS
)
set(GTPV1U_DIR ${OPENAIR3_DIR}/GTPV1-U)
-set (GTPV1U_SRC
- ${RRC_DIR}/rrc_eNB_GTPV1U.c
- ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uTunnelEndPoint.c
- ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uTrxn.c
- ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uMsg.c
- ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1u.c
- ${GTPV1U_DIR}/gtpv1u_teid_pool.c
-)
-add_library(GTPV1U ${GTPV1U_SRC})
-add_dependencies(GTPV1U rrc_flag)
-#add_library (GTPV1U_OCP
-#${OPENAIR3_DIR}/ocp-gtp/gtp_itf.cpp
-#)
-#include_directories(${OPENAIR3_DIR}/ocp-gtp)
+add_library (GTPV1U_OCP
+ ${NR_RRC_DIR}/rrc_gNB_GTPV1U.c
+ ${RRC_DIR}/rrc_eNB_GTPV1U.c
+${OPENAIR3_DIR}/ocp-gtpu/gtp_itf.cpp
+)
+add_dependencies(GTPV1U_OCP rrc_flag)
+include_directories(${OPENAIR3_DIR}/ocp-gtp)
#NR case
set (NR_GTPV1U_SRC
${NR_RRC_DIR}/rrc_gNB_GTPV1U.c
${RRC_DIR}/rrc_eNB_GTPV1U.c
+ ${GTPV1U_DIR}/gtpv1u_eNB.c
+ ${GTPV1U_DIR}/gtpv1u_gNB.c
${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uTunnelEndPoint.c
${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uTrxn.c
${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uMsg.c
@@ -2262,6 +2259,12 @@ set (NR_GTPV1U_SRC
add_library(NR_GTPV1U ${NR_GTPV1U_SRC})
add_dependencies(NR_GTPV1U rrc_flag)
+if (${NEW_GTPU})
+set(GTPV1U GTPV1U_OCP)
+else()
+set(GTPV1U NR_GTPV1U)
+endif()
+
set (MME_APP_SRC
${OPENAIR3_DIR}/MME_APP/mme_app.c
${OPENAIR3_DIR}/MME_APP/mme_config.c
@@ -2800,6 +2803,7 @@ add_library(rfsimulator MODULE
${OPENAIR_TARGETS}/ARCH/rfsimulator/simulator.c
${OPENAIR_TARGETS}/ARCH/rfsimulator/apply_channelmod.c
${OPENAIR_TARGETS}/ARCH/rfsimulator/new_channel_sim.c
+ ${OPENAIR1_DIR}/PHY/TOOLS/signal_energy.c
)
target_link_libraries(rfsimulator SIMU_COMMON ${ATLAS_LIBRARIES})
@@ -2814,6 +2818,7 @@ include_directories("${OPENAIR_DIR}/common/utils/T")
if (${T_TRACER})
set(T_SOURCE
+ ${OPENAIR_DIR}/common/utils/T/T_IDs.h
${OPENAIR_DIR}/common/utils/T/T.c
${OPENAIR_DIR}/common/utils/T/local_tracer.c)
set(T_LIB "rt")
@@ -2823,8 +2828,6 @@ endif (${T_TRACER})
#This rule and the following deal with it.
add_custom_command (
OUTPUT ${OPENAIR_DIR}/common/utils/T/T_IDs.h
- COMMAND make clean
- COMMAND make -j2
COMMAND make check_vcd
WORKING_DIRECTORY ${OPENAIR_DIR}/common/utils/T
DEPENDS ${OPENAIR_DIR}/common/utils/T/T_messages.txt
@@ -2832,6 +2835,10 @@ add_custom_command (
${OPENAIR_DIR}/common/utils/LOG/vcd_signal_dumper.h
)
+execute_process (
+ COMMAND make check_vcd
+ WORKING_DIRECTORY ${OPENAIR_DIR}/common/utils/T
+)
#This rule is specifically needed to generate T files
#before anything else in a project that uses the T.
#See below, there are some 'add_dependencies' showing that.
@@ -2901,7 +2908,6 @@ add_executable(lte-softmodem
${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
${OPENAIR_DIR}/common/utils/utils.c
${OPENAIR_DIR}/common/utils/system.c
- ${GTPU_need_ITTI}
${XFORMSINTERFACE_SOURCE}
${T_SOURCE}
${CONFIG_SOURCES}
@@ -2911,7 +2917,8 @@ add_dependencies(lte-softmodem rrc_flag s1ap_flag x2_flag oai_iqplayer)
target_link_libraries (lte-softmodem
-Wl,--start-group
- RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB
+
+ RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB ${GTPV1U} SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB
PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB MISC_NFAPI_LTE_LIB LFDS7
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB}
-Wl,--end-group z dl)
@@ -2942,7 +2949,6 @@ add_executable(ocp-enb
${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
${OPENAIR_DIR}/common/utils/utils.c
${OPENAIR_DIR}/common/utils/system.c
- ${GTPU_need_ITTI}
${XFORMSINTERFACE_SOURCE}
${T_SOURCE}
${CONFIG_SOURCES}
@@ -2952,7 +2958,8 @@ add_dependencies(ocp-enb rrc_flag s1ap_flag x2_flag oai_iqplayer coding params_l
target_link_libraries (ocp-enb
-Wl,--start-group
- RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB
+
+ RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB ${GTPV1U} SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB
PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB MISC_NFAPI_LTE_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7 SIMU_COMMON
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB}
-Wl,--end-group z dl)
@@ -3022,7 +3029,8 @@ endif()
target_link_libraries (lte-uesoftmodem
-Wl,--start-group
RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP F1AP_LIB
- GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON
+
+ ${GTPV1U} SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON
PHY_UE PHY_RU LFDS L2_UE L2_LTE LFDS7 SIMU_COMMON SIMU NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB MISC_NFAPI_LTE_LIB
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${ATLAS_LIBRARIES}
-Wl,--end-group z dl)
@@ -3050,21 +3058,20 @@ add_executable(nr-softmodem
${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
${OPENAIR2_DIR}/RRC/NAS/rb_config.c
- ${OPENAIR3_DIR}/GTPV1-U/gtpv1u_gNB.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
${OPENAIR_DIR}/common/utils/utils.c
${OPENAIR_DIR}/common/utils/system.c
${OPENAIR_DIR}/common/utils/nr/nr_common.c
- ${GTPU_need_ITTI}
${XFORMSINTERFACE_SOURCE}
${T_SOURCE}
${CONFIG_SOURCES}
${SHLIB_LOADER_SOURCES}
+ ${OPENAIR2_DIR}/ENB_APP/flexran_agent_ran_api_to_fix.c
)
target_link_libraries (nr-softmodem
-Wl,--start-group
- UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS NR_GTPV1U SECU_CN SECU_OSA
+ UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS ${GTPV1U} SECU_CN SECU_OSA
${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} RRC_LIB NR_RRC_LIB
NGAP_LIB NGAP_GNB S1AP_LIB S1AP_ENB L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB ${PROTO_AGENT_LIB} ${FSPT_MSG_LIB}
@@ -3094,7 +3101,6 @@ add_executable(ocp-gnb
${OPENAIR_DIR}/common/utils/nr/nr_common.c
${OPENAIR_DIR}/common/utils/utils.c
${OPENAIR_DIR}/common/utils/system.c
- ${GTPU_need_ITTI}
${XFORMS_SOURCE_NR}
${T_SOURCE}
${CONFIG_SOURCES}
@@ -3104,7 +3110,7 @@ add_executable(ocp-gnb
target_link_libraries (ocp-gnb
-Wl,--start-group
- UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS NR_GTPV1U SECU_CN SECU_OSA
+ UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS ${GTPV1U} SECU_CN SECU_OSA
${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} RRC_LIB NR_RRC_LIB
NGAP_LIB NGAP_GNB S1AP_LIB S1AP_ENB L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB SIMU_COMMON
@@ -3183,6 +3189,17 @@ target_link_libraries (dlsim_tm4
pthread m rt ${CONFIG_LIB} ${ATLAS_LIBRARIES} ${T_LIB}
)
+add_executable(rftest
+ ${OPENAIR_DIR}/openair1/PHY/TOOLS/calibration_test.c
+ ${OPENAIR_DIR}/openair1/PHY/TOOLS/calibration_scope.c
+ ${OPENAIR_DIR}/common/utils/system.c
+ ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
+ ${OPENAIR_DIR}/executables/softmodem-common.c
+ ${CONFIG_SOURCES}
+ ${SHLIB_LOADER_SOURCES}
+)
+target_link_libraries(rftest minimal_lib PHY_NR_COMMON pthread dl m forms ${T_LIB} )
+
add_executable(polartest
${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/polartest.c
${OPENAIR_DIR}/common/utils/backtrace.c
@@ -3415,7 +3432,7 @@ add_executable(test_epc_generate_scenario
${OPENAIR3_DIR}/S1AP/s1ap_eNB_defs.h
)
target_link_libraries (test_epc_generate_scenario
- -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY LFDS ${ITTI_LIB} ${MSC_LIB} L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${CONFIG_LIB}
+ -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP ${GTPV1U} LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY LFDS ${ITTI_LIB} ${MSC_LIB} L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${CONFIG_LIB}
)
add_executable(test_epc_play_scenario
@@ -3434,7 +3451,7 @@ add_executable(test_epc_play_scenario
)
target_include_directories(test_epc_play_scenario PUBLIC /usr/local/share/asn1c)
target_link_libraries (test_epc_play_scenario
- -Wl,--start-group RRC_LIB S1AP_LIB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY_NR_COMMON PHY_COMMON PHY PHY_UE LFDS ${ITTI_LIB} ${MSC_LIB} -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${CONFIG_LIB}
+ -Wl,--start-group RRC_LIB S1AP_LIB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP ${GTPV1U} LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY_NR_COMMON PHY_COMMON PHY PHY_UE LFDS ${ITTI_LIB} ${MSC_LIB} -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${CONFIG_LIB}
)
@@ -3480,7 +3497,7 @@ if (${T_TRACER})
NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_VNF_LIB NFAPI_USER_LIB
PHY_COMMON PHY PHY_UE PHY_NR PHY_NR_COMMON PHY_NR_UE PHY_RU PHY_MEX
L2 L2_LTE L2_NR L2_LTE_NR L2_UE NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON MAC_NR MAC_UE_NR NGAP_GNB
- CN_UTILS GTPV1U NR_GTPV1U SCTP_CLIENT MME_APP UDP LIB_NAS_UE NB_IoT LFDS LFDS7 SIMU_COMMON SIMU SIMU_ETH OPENAIR0_LIB
+ CN_UTILS ${GTPV1U} SCTP_CLIENT MME_APP UDP LIB_NAS_UE NB_IoT LFDS LFDS7 SIMU_COMMON SIMU SIMU_ETH OPENAIR0_LIB
ldpc_orig ldpc_optim ldpc_optim8seg ldpc PROTO_AGENT dfts)
if (TARGET ${i})
add_dependencies(${i} generate_T)
@@ -3571,14 +3588,12 @@ add_executable(nr-ittisim
${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
${OPENAIR2_DIR}/RRC/NAS/rb_config.c
- ${OPENAIR3_DIR}/GTPV1-U/gtpv1u_gNB.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
${OPENAIR_DIR}/common/utils/utils.c
${OPENAIR_DIR}/common/utils/system.c
${OPENAIR_DIR}/common/utils/nr/nr_common.c
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
- ${GTPU_need_ITTI}
${XFORMSINTERFACE_SOURCE}
${T_SOURCE}
${CONFIG_SOURCES}
@@ -3587,7 +3602,7 @@ add_executable(nr-ittisim
target_link_libraries (nr-ittisim
-Wl,--start-group
- UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS NR_GTPV1U SECU_CN SECU_OSA
+ UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS ${GTPV1U} SECU_CN SECU_OSA
${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_SIM_LIB} RRC_LIB NR_RRC_LIB
NGAP_LIB NGAP_GNB S1AP_LIB S1AP_ENB L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB ${PROTO_AGENT_LIB} ${FSPT_MSG_LIB}
diff --git a/cmake_targets/install_external_packages.ubuntu20 b/cmake_targets/install_external_packages.ubuntu20
index 9ef79be9c2..4b1cda42f8 100755
--- a/cmake_targets/install_external_packages.ubuntu20
+++ b/cmake_targets/install_external_packages.ubuntu20
@@ -83,6 +83,8 @@ get_distribution_release() {
check_supported_distribution() {
case $(get_distribution_release) in
"ubuntu20.04") return 0 ;;
+ "ubuntu20.10") return 0 ;;
+ "ubuntu21.04") return 0 ;;
esac
return 1
}
@@ -157,8 +159,16 @@ install_protobuf_from_source(){
#cd protobuf-2.6.1/
rm -rf /tmp/protobuf-cpp-3.3.0.tar.gz* /tmp/protobuf-3.3.0
wget --tries=3 --retry-connrefused https://github.com/google/protobuf/releases/download/v3.3.0/protobuf-cpp-3.3.0.tar.gz
- tar -xzvf protobuf-cpp-3.3.0.tar.gz --owner "$USER" --group "$(groups | cut -d" " -f1)" --no-same-owner
- cd protobuf-3.3.0/ || exit
+ tar -xzvf protobuf-cpp-3.3.0.tar.gz --owner $(id -u) --group $(id -g) --no-same-owner
+ cd protobuf-3.3.0/
+ else
+ export LD_LIBRARY_PATH=/usr/local/lib #protoc needs to know where toclook for shared libs
+ rm -rf /tmp/protobuf
+ git clone --depth=1 --branch=v3.3.0 https://github.com/protocolbuffers/protobuf.git /tmp/protobuf
+ cd /tmp/protobuf
+ git submodule update --init --recursive
+ ./autogen.sh
+ fi
./configure
echo "Compiling protobuf"
make -j"$(nproc)"
@@ -198,15 +208,15 @@ install_usrp_uhd_driver_from_source(){
rm -rf /tmp/uhd
git clone https://github.com/EttusResearch/uhd.git
cd uhd || exit
- git checkout tags/v3.13.0.2
+ git checkout UHD-3.15.LTS
mkdir -p host/build
cd host/build || exit
- $CMAKE ../
+ $CMAKE ../ -GNinja
echo "Compiling UHD"
- make -j"$(nproc)"
- make test
- $SUDO make install
+ ninja
+ $SUDO ninja install
$SUDO ldconfig
+ $SUDO /usr/lib/uhd/utils/uhd_images_downloader.py
) >& "$uhd_install_log"
}
@@ -329,6 +339,7 @@ check_install_ubuntu_packages() {
$SUDO apt install -y software-properties-common
case "$(get_distribution_release)" in
"ubuntu20.04")
+ "ubuntu21.04")
specific_packages="libtasn1-6-dev libgnutls28-dev iproute2 libconfig-dev"
LAPACK_LIBNAME="liblapack.so-x86_64-linux-gnu"
LAPACK_TARGET="/usr/lib/x86_64-linux-gnu/atlas/liblapack.so"
@@ -345,7 +356,6 @@ check_install_ubuntu_packages() {
openvpn \
pkg-config \
python3-dev \
- python-pexpect \
sshfs \
swig \
tshark \
@@ -358,7 +368,6 @@ check_install_ubuntu_packages() {
iperf3 \
android-tools-adb \
wvdial \
- python-numpy \
sshpass \
nscd \
bc \
@@ -379,7 +388,6 @@ check_install_ubuntu_packages() {
git \
graphviz \
gtkwave \
- guile-2.0-dev \
iperf \
iptables \
libxtables-dev \
@@ -419,7 +427,8 @@ check_install_ubuntu_packages() {
libxpm-dev \
libboost-all-dev \
nettle-dev \
- nettle-bin
+ nettle-bin \
+ libreadline-dev
fi
$SUDO update-alternatives --set "$LAPACK_LIBNAME" "$LAPACK_TARGET"
diff --git a/cmake_targets/tools/run_enb_s1_usrp b/cmake_targets/tools/run_enb_s1_usrp
index e119126683..1a4c6b10b8 100755
--- a/cmake_targets/tools/run_enb_s1_usrp
+++ b/cmake_targets/tools/run_enb_s1_usrp
@@ -101,7 +101,6 @@ function main()
local -i run_gdb=0
local -i show_stdout=0
local exe_arguments=""
- local itti_dump_file=""
until [ -z "$1" ]
do
@@ -154,18 +153,6 @@ function main()
exe_arguments="$exe_arguments --rf-config-file=$rf_config_file"
fi
;;
- -K | --itti-dump-file)
- itti_dump_file=$2
- # can omit file name if last arg on the line
- if [ "x$itti_dump_file" = "x" ]; then
- itti_dump_file="/tmp/enb_s1_usrp_itti.log"
- shift 1;
- else
- shift 2;
- fi
- echo "setting ITTI dump file to: $itti_dump_file"
- exe_arguments="$exe_arguments -K $itti_dump_file"
- ;;
-m | --mscgen)
g_msc_dir=$2
# can omit file name if last arg on the line
diff --git a/common/config/config_cmdline.c b/common/config/config_cmdline.c
index 6d01d98c65..1df1bc16f7 100644
--- a/common/config/config_cmdline.c
+++ b/common/config/config_cmdline.c
@@ -255,7 +255,7 @@ int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix)
if ( ((strlen(oneargv) == 2) && (strcmp(oneargv + 1,cfgpath) == 0)) || /* short option, one "-" */
((strlen(oneargv) > 2) && (strcmp(oneargv + 2,cfgpath ) == 0 )) || /* long option beginning with "--" */
((strlen(oneargv) == 2) && (strcmp(oneargv + 1,cfgoptions[n].optname) == 0) && (cfgoptions[n].paramflags & PARAMFLAG_CMDLINE_NOPREFIXENABLED )) ||
- ((strlen(oneargv) > 2) && (strcmp(oneargv + 2,cfgpath ) == 0 ) && (cfgoptions[n].paramflags & PARAMFLAG_CMDLINE_NOPREFIXENABLED )) ) {
+ ((strlen(oneargv) > 2) && (strcmp(oneargv + 2, cfgoptions[n].optname) == 0 ) && (cfgoptions[n].paramflags & PARAMFLAG_CMDLINE_NOPREFIXENABLED )) ) {
char *valptr=NULL;
int ret;
config_get_if()->argv_info[i] |= CONFIG_CMDLINEOPT_PROCESSED;
diff --git a/common/config/config_load_configmodule.h b/common/config/config_load_configmodule.h
index 8baaa99bb8..0688f6531f 100644
--- a/common/config/config_load_configmodule.h
+++ b/common/config/config_load_configmodule.h
@@ -82,10 +82,12 @@ typedef struct configmodule_interface {
#ifdef CONFIG_LOADCONFIG_MAIN
configmodule_interface_t *cfgptr=NULL;
-static char config_helpstr [] = "\n lte-softmodem -O [config mode]<:dbgl[debugflags]> \n \
- debugflags can also be defined in the config_libconfig section of the config file\n \
+static char config_helpstr [] = "\n lte-softmodem -O [config mode]<:dbgl[debugflags]><:incp[path]>\n \
+ debugflags can also be defined in the config section of the config file\n \
debugflags: mask, 1->print parameters, 2->print memory allocations debug messages\n \
- 4->print command line processing debug messages\n ";
+ 4->print command line processing debug messages\n \
+ incp parameter can be used to define the include path used for config files (@include directive)\n \
+ defaults is set to the path of the main config file.\n";
#define CONFIG_SECTIONNAME "config"
#define CONFIGPARAM_DEBUGFLAGS_IDX 0
diff --git a/common/config/libconfig/config_libconfig.c b/common/config/libconfig/config_libconfig.c
index eb08a70183..17266246f0 100644
--- a/common/config/libconfig/config_libconfig.c
+++ b/common/config/libconfig/config_libconfig.c
@@ -33,8 +33,9 @@
#include
#include
+#include
+ #include
-#include
#include "config_libconfig.h"
#include "config_libconfig_private.h"
@@ -347,17 +348,35 @@ int config_libconfig_init(char *cfgP[], int numP) {
config_get_if()->numptrs=0;
memset(config_get_if()->ptrs,0,sizeof(void *) * CONFIG_MAX_ALLOCATEDPTRS);
memset(config_get_if()->ptrsAllocated, 0, sizeof(config_get_if()->ptrsAllocated));
-
+ /* search for include path parameter and set config file include path accordingly */
+ for (int i=0; isched_get_priority_max(SCHED_FIFO)) {
+ LOG_E(TMR,"Prio not possible: %d, min is %d, max: %d, forced in the range\n",
+ priority,
+ sched_get_priority_min(SCHED_OAI),
+ sched_get_priority_max(SCHED_OAI));
+ if(prioritysched_get_priority_max(SCHED_OAI))
+ priority=sched_get_priority_max(SCHED_OAI);
+ }
+ AssertFatal(priority<=sched_get_priority_max(SCHED_OAI),"");
struct sched_param sparam={0};
sparam.sched_priority = priority;
- pthread_attr_setschedparam(&attr, &sparam);
-
- pthread_create(t, &attr, func, param);
+ ret=pthread_attr_setschedparam(&attr, &sparam);
+ AssertFatal(ret==0,"ret: %d, errno: %d\n",ret, errno);
+ ret=pthread_create(t, &attr, func, param);
+ AssertFatal(ret==0,"ret: %d, errno: %d\n",ret, errno);
pthread_setname_np(*t, name);
if (affinity != -1 ) {
@@ -216,7 +233,6 @@ void threadCreate(pthread_t* t, void * (*func)(void*), void * param, char* name,
CPU_SET(affinity, &cpuset);
AssertFatal( pthread_setaffinity_np(*t, sizeof(cpu_set_t), &cpuset) == 0, "Error setting processor affinity");
}
-
pthread_attr_destroy(&attr);
}
diff --git a/common/utils/system.h b/common/utils/system.h
index a89a6c5b17..fbfd338a1a 100644
--- a/common/utils/system.h
+++ b/common/utils/system.h
@@ -46,9 +46,11 @@ void set_latency_target(void);
void configure_linux(void);
void threadCreate(pthread_t* t, void * (*func)(void*), void * param, char* name, int affinity, int priority);
-#define OAI_PRIORITY_RT_LOW sched_get_priority_min(SCHED_FIFO)
-#define OAI_PRIORITY_RT sched_get_priority_max(SCHED_FIFO)-10
-#define OAI_PRIORITY_RT_MAX sched_get_priority_max(SCHED_FIFO)
+
+#define SCHED_OAI SCHED_RR
+#define OAI_PRIORITY_RT_LOW sched_get_priority_min(SCHED_OAI)
+#define OAI_PRIORITY_RT ((sched_get_priority_min(SCHED_OAI)+sched_get_priority_max(SCHED_OAI))/2)
+#define OAI_PRIORITY_RT_MAX sched_get_priority_max(SCHED_OAI)-2
void thread_top_init(char *thread_name,
int affinity,
diff --git a/common/utils/telnetsrv/telnetsrv.c b/common/utils/telnetsrv/telnetsrv.c
index 03f7af99bc..734126721a 100644
--- a/common/utils/telnetsrv/telnetsrv.c
+++ b/common/utils/telnetsrv/telnetsrv.c
@@ -461,12 +461,12 @@ int process_command(char *buf) {
int i,j,k;
char modulename[TELNET_CMD_MAXSIZE];
char cmd[TELNET_CMD_MAXSIZE];
- char cmdb[TELNET_MAX_MSGLENGTH];
+ char *cmdb=NULL;
char *bufbck;
int rt;
memset(modulename,0,sizeof(modulename));
memset(cmd,0,sizeof(cmd));
- memset(cmdb,0,sizeof(cmdb));
+
if (strncasecmp(buf,"ex",2) == 0)
return CMDSTATUS_EXIT;
@@ -490,12 +490,10 @@ int process_command(char *buf) {
return CMDSTATUS_FOUND;
}
- memset(modulename,0,sizeof(modulename));
- memset(cmd,0,sizeof(cmd));
- memset(cmdb,0,sizeof(cmdb));
+
bufbck=strdup(buf);
rt=CMDSTATUS_NOTFOUND;
- j = sscanf(buf,"%19s %19s %19[^\t\n]",modulename,cmd,cmdb);
+ j = sscanf(buf,"%19s %19s %m[^\t\n]",modulename,cmd,&cmdb);
if (telnetparams.telnetdbg > 0)
printf("process_command: %i words, module=%s cmd=%s, parameters= %s\n",j,modulename,cmd,cmdb);
@@ -562,7 +560,7 @@ int process_command(char *buf) {
rt= CMDSTATUS_FOUND;
} /* loop */
} /* for i */
-
+ free(cmdb);
free(bufbck);
return rt;
}
@@ -702,7 +700,7 @@ void poll_telnetcmdq(void *qid, void *arg) {
*/
void exec_moduleinit(char *modname) {
void (*fptr)(void);
- char initfunc[TELNET_CMD_MAXSIZE+9];
+ char initfunc[TELNET_CMD_MAXSIZE+10];
if (strlen(modname) > TELNET_CMD_MAXSIZE) {
fprintf(stderr,"[TELNETSRV] module %s not loaded, name exceeds the %i size limit\n",
diff --git a/common/utils/threadPool/thread-pool.h b/common/utils/threadPool/thread-pool.h
index 5db1a5e34e..a32b7c3859 100644
--- a/common/utils/threadPool/thread-pool.h
+++ b/common/utils/threadPool/thread-pool.h
@@ -37,14 +37,21 @@
#else
#define THREADINIT PTHREAD_MUTEX_INITIALIZER
#endif
-#define mutexinit(mutex) AssertFatal(pthread_mutex_init(&mutex,NULL)==0,"");
-#define condinit(signal) AssertFatal(pthread_cond_init(&signal,NULL)==0,"");
-#define mutexlock(mutex) AssertFatal(pthread_mutex_lock(&mutex)==0,"");
+#define mutexinit(mutex) {int ret=pthread_mutex_init(&mutex,NULL); \
+ AssertFatal(ret==0,"ret=%d\n",ret);}
+#define condinit(signal) {int ret=pthread_cond_init(&signal,NULL); \
+ AssertFatal(ret==0,"ret=%d\n",ret);}
+#define mutexlock(mutex) {int ret=pthread_mutex_lock(&mutex); \
+ AssertFatal(ret==0,"ret=%d\n",ret);}
#define mutextrylock(mutex) pthread_mutex_trylock(&mutex)
-#define mutexunlock(mutex) AssertFatal(pthread_mutex_unlock(&mutex)==0,"");
-#define condwait(condition, mutex) AssertFatal(pthread_cond_wait(&condition, &mutex)==0,"");
-#define condbroadcast(signal) AssertFatal(pthread_cond_broadcast(&signal)==0,"");
-#define condsignal(signal) AssertFatal(pthread_cond_broadcast(&signal)==0,"");
+#define mutexunlock(mutex) {int ret=pthread_mutex_unlock(&mutex); \
+ AssertFatal(ret==0,"ret=%d\n",ret);}
+#define condwait(condition, mutex) {int ret=pthread_cond_wait(&condition, &mutex); \
+ AssertFatal(ret==0,"ret=%d\n",ret);}
+#define condbroadcast(signal) {int ret=pthread_cond_broadcast(&signal); \
+ AssertFatal(ret==0,"ret=%d\n",ret);}
+#define condsignal(signal) {int ret=pthread_cond_broadcast(&signal); \
+ AssertFatal(ret==0,"ret=%d\n",ret);}
#define tpool_nbthreads(tpool) (tpool.nbThreads)
typedef struct notifiedFIFO_elt_s {
struct notifiedFIFO_elt_s *next;
@@ -78,7 +85,7 @@ static inline notifiedFIFO_elt_t *newNotifiedFIFO_elt(int size,
ret->reponseFifo=reponseFifo;
ret->processingFunc=processingFunc;
// We set user data piece aligend 32 bytes to be able to process it with SIMD
- ret->msgData=(void *)ret+(sizeof(notifiedFIFO_elt_t)/32+1)*32;
+ ret->msgData=(void *)((uint8_t*)ret+(sizeof(notifiedFIFO_elt_t)/32+1)*32);
ret->malloced=true;
return ret;
}
diff --git a/common/utils/threadPool/thread-pool.md b/common/utils/threadPool/thread-pool.md
index a087b989fa..f2422d9822 100644
--- a/common/utils/threadPool/thread-pool.md
+++ b/common/utils/threadPool/thread-pool.md
@@ -210,8 +210,8 @@ time the worker finished the job
time the client reads the result
if you set the environement variable:
-thread-pool-measurements to a valid file name
+threadPoolMeasurements to a valid file name
These measurements will be wrote to this Linux pipe.
-A tool to read the linux fifo and display it in ascii is provided:
-see the local directory Makefile for this tool and to compile the thread pool unitary tests.
+A tool to read the linux fifo and display it in ascii is provided; compute the binay:
+in cmake building directory: make/ninja measurement_display
diff --git a/doc/SW_archi.md b/doc/SW_archi.md
index d92f802148..e5856d63bc 100644
--- a/doc/SW_archi.md
+++ b/doc/SW_archi.md
@@ -171,24 +171,31 @@ NR_sched_pusch_t (for values changing every TTI, e.g., frequency domain
allocation) and NR_sched_pusch_save_t (for values changing less frequently, at
least in FR1 [to my understanding], e.g., DMRS fields when the time domain
allocation stays between TTIs) structures. Furthermore, the preprocessor is an
-exchangeable module that might schedule differently, e.g., one user for
-phytest, multiple users in FR1, or maybe FR2: phytest is in
-nr_ul_preprocessor_phytest(), for FR1 is nr_simple_ulsch_preprocessor() [under
-development], for FR2 does not exist yet.
+exchangeable module that schedules differently based on a particular
+use-case/deployment type, e.g., one user for phytest [in
+nr_ul_preprocessor_phytest()], multiple users in FR1
+[nr_fr1_ulsch_preprocessor()], or maybe FR2 [does not exist yet]:
* calls preprocessor via pre_processor_ul(): the preprocessor is responsible
- for allocating CCEs (using allocate_nr_CCEs()). Note that we do not yet have
- scheduling requests or buffer status reports, and only one UE. E.g.,
- nr_simple_ulsch_preprocessor():
+ for allocating CCEs (using allocate_nr_CCEs()) and deciding on resource
+ allocation for the UEs including TB size. Note that we do not yet have
+ scheduling requests. What it typically does:
1) check whether the current frame/slot plus K2 is an UL slot, and return if
not.
2) Find first free start RB in vrb_map_UL, and as many free consecutive RBs
as possible.
- 3) allocate a CCE for the UE (and return if it is not possible)
- 4) Calculate DMRS stuff (nr_save_pusch_fields()) and the TBS.
- 5) Mark used resources in vrb_map_UL.
-* loop through all users: get a free HARQ PID and
- update statistics. Fill nFAPI structures directly for PUSCH, and call
- config_uldci() and fill_dci_pdu_rel15() for DCI filling and PDCCH messages.
+ 3) Either set up resource allocation directly (e.g., for a single UE,
+ phytest), or call into a function to perform actual resource allocation.
+ Currently, this is done using pf_ul() which implements a basic
+ proportional fair scheduler:
+ * for every UE, check for retransmission and allocate as necessary
+ * Calculate DMRS stuff (nr_set_pusch_semi_static())
+ * Calculate the PF coefficient and put eligible UEs into a list
+ * Allocate resources to the UE(s) with the highest coefficient
+ 4) Mark used resources in vrb_map_UL.
+* loop through all users: get a HARQ process as indicated through the
+ preprocessor, update statistics, fill nFAPI structures directly for PUSCH,
+ and call config_uldci() and fill_dci_pdu_rel15() for DCI filling and PDCCH
+ messages.
Calls nr_schedule_ue_spec(). It is divided into the "preprocessor" and the
"postprocessor": the first makes the scheduling decisions, the second fills
@@ -196,29 +203,28 @@ nFAPI structures to indicate to the PHY what it is supposed to do. To signal
which users have how many resources, the preprocessor populates the
NR_UE_sched_ctrl_t structure of affected users. In particular, the field rbSize
decides whether a user is to be allocated. Furthermore, the preprocessor is an
-exchangeable module that might schedule differently, e.g., one user for
-phytest, multiple users in FR1, or maybe FR2: phytest is in
-nr_preprocessor_phytest(), for FR1 is nr_simple_dlsch_preprocessor() [under
-development], for FR2 does not exist yet.
+exchangeable module that schedules differently based on a particular
+use-case/deployment type, e.g., one user for phytest [in
+nr_preprocessor_phytest()], multiple users in FR1
+[nr_fr1_dlsch_preprocessor()], or maybe FR2 [does not exist yet].
* calls preprocessor via pre_processor_dl(): the preprocessor is responsible
for allocating CCEs and PUCCH (using allocate_nr_CCEs() and
nr_acknack_scheduling()) and deciding on the frequency/time domain
- allocation. E.g., nr_simple_dlsch_preprocessor():
- 1) mac_rlc_status_ind() locks and checks directly inside rlc data the
- quantity of waiting data.
- 2) return from the preprocessor if there is no data and no timing advance to
- send,
- 3) otherwise, allocate a CCE for the UE (and return if it is not possible)
- 4) find a PUCCH occasion for HARQ
- 5a) check if there is a retransmission: if yes, find free resources to
- transmit using the same resources, else
- 5b) calculate the necessary RBs needed to get a TBS large enough to hold all
- data, or until no more resources are available
- 6) Mark taken resources in the vrb_map
+ allocation including the TB size. What it typically does:
+ 1) Check available resources in the vrb_map
+ 2) Checks the quantity of waiting data in RLC
+ 3) Either set up resource allocation directly (e.g., for a single UE,
+ phytest), or call into a function to perform actual resource allocation.
+ Currently, this is done using pf_dl() which implements a basic
+ proportional fair scheduler:
+ * for every UE, check for retransmission and allocate as necessary
+ * Calculate the PF coefficient and put eligible UEs into a list
+ * Allocate resources to the UE(s) with the highest coefficient
+ 4) Mark taken resources in the vrb_map
* loop through all users: check if a new TA is necessary. Then, if a user has
- allocated resources, compute its TBS, and fill nFAPI structures
- (nr_fill_nfapi_dl_pdu() to populate what should be done by the lower layers
- to make the Tx subframe). Update statistics (round, sent bytes).
+ allocated resources, update statistics (round, sent bytes), update HARQ
+ process information, and fill nFAPI structures (allocate a DCI and PDCCH
+ messages, TX_req, ...)
# RRC
RRC is a regular thread with itti loop on queue: TASK_RRC_GNB
@@ -296,6 +302,28 @@ gtp thread calls directly pdcp_data_req(), so it runs inside it's context intern
## inside other threads
gtpv1u_create_s1u_tunnel(), delete tunnel, ... functions are called inside the other threads, without mutex.
+# New GTP
+## initialization
+Coexistance until full merge with legacy GTP
+cmake new option: NEW_GTPU to use the new implementation (it changes for the entire executable)
+It is possible to use both old and new GTP in same executable because the itti task and all functions names are different
+Current status of new implementation: not tested, X2 not developped, 5G new GTP option not developped, remain issues on data coming from void: muid, enb_flag, ...
+
+ocp_gtpv1uTask(): this creates only the thread, doesn't configure anything
+gtpv1Init(): creates a listening socket to Linux for a given reception and select a local IP address
+
+newGtpuCreateTunnel() this function will replace the xxx_create_tunnel_xxx() for various cases
+This creates a outgoing context for a teid (in input), it computes and return the incoming teid that will be used for incoming packets
+These teids and in a "instance", so in a Linux socket: same teid can co-exist for different sockets
+ Remain here a lack to fill: the information given in the legacy funtions is not enough to fullfil the data needed by the callback
+stuff like enb_flag, but also mui and more important data are not given explicitly by any legacy function (gtpv1u_create_s1u_tunnel), but the legacy and the new interface to lower layer (like pdcp) require this data.
+The datamodel is still not fully understood, so this data source remain unknown
+A new parameter is the callback function: will be pdpcp_data_req() and gtpv_data_req() (x2 case) for existing implementation and later other call backs like the F1-U implementation.
+
+incoming packets
+the gtp layer retrieves the data, the teid, find out the related data: rnti, bearer and quite a lot of other parameters (not clear why, because it looks like all is statefull, so the lower layer should have the context)
+if lower layers can be stateless, it is a good idea to keep the context in the gtp layer and pass it to the callback, but the design remain obfuscated.
+
# NGAP
NGAP would be a itti thread as is S1AP (+twin thread SCTP that is almost void processing)?
About all messages are exchanged with RRC thread
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/main-ocp.c b/executables/main-ocp.c
index ae1db7195b..925861c71e 100644
--- a/executables/main-ocp.c
+++ b/executables/main-ocp.c
@@ -73,13 +73,15 @@ int sync_var=-1; //!< protected by mutex \ref sync_mutex.
int config_sync_var=-1;
volatile int oai_exit = 0;
double cpuf;
+msc_interface_t msc_interface;
+THREAD_STRUCT thread_struct;
+
uint16_t sf_ahead=4;
//uint16_t slot_ahead=6;
int otg_enabled;
uint64_t downlink_frequency[MAX_NUM_CCs][4];
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
int split73;
-int usrp_tx_thread = 0;
char * split73_config;
int split73;
AGENT_RRC_xface *agent_rrc_xface[NUM_MAX_ENB]= {0};
@@ -1318,7 +1320,7 @@ int main ( int argc, char **argv ) {
// end of CI modifications
//getchar();
- if(IS_SOFTMODEM_DOFORMS)
+ if(IS_SOFTMODEM_DOSCOPE)
load_softscope("enb", NULL);
itti_wait_tasks_end();
@@ -1327,7 +1329,7 @@ int main ( int argc, char **argv ) {
// stop threads
if (RC.nb_inst == 0 || !NODE_IS_CU(node_type)) {
- if(IS_SOFTMODEM_DOFORMS)
+ if(IS_SOFTMODEM_DOSCOPE)
end_forms();
LOG_I(ENB_APP,"stopping MODEM threads\n");
diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c
index a92f433560..8b3d6fc64e 100644
--- a/executables/nr-gnb.c
+++ b/executables/nr-gnb.c
@@ -228,16 +228,6 @@ void rx_func(void *param) {
rnti_to_remove_count = 0;
if (pthread_mutex_unlock(&rnti_to_remove_mutex)) exit(1);
- // Call the scheduler
-
- pthread_mutex_lock(&gNB->UL_INFO_mutex);
- gNB->UL_INFO.frame = frame_rx;
- gNB->UL_INFO.slot = slot_rx;
- gNB->UL_INFO.module_id = gNB->Mod_id;
- gNB->UL_INFO.CC_id = gNB->CC_id;
- gNB->if_inst->NR_UL_indication(&gNB->UL_INFO);
- pthread_mutex_unlock(&gNB->UL_INFO_mutex);
-
// RX processing
int tx_slot_type = nr_slot_select(cfg,frame_tx,slot_tx);
int rx_slot_type = nr_slot_select(cfg,frame_rx,slot_rx);
@@ -264,6 +254,18 @@ void rx_func(void *param) {
stop_meas( &softmodem_stats_rxtx_sf );
LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, frame_rx, slot_rx, frame_tx, slot_tx);
+ // Call the scheduler
+
+ start_meas(&gNB->ul_indication_stats);
+ pthread_mutex_lock(&gNB->UL_INFO_mutex);
+ gNB->UL_INFO.frame = frame_rx;
+ gNB->UL_INFO.slot = slot_rx;
+ gNB->UL_INFO.module_id = gNB->Mod_id;
+ gNB->UL_INFO.CC_id = gNB->CC_id;
+ gNB->if_inst->NR_UL_indication(&gNB->UL_INFO);
+ pthread_mutex_unlock(&gNB->UL_INFO_mutex);
+ stop_meas(&gNB->ul_indication_stats);
+
notifiedFIFO_elt_t *res;
if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT) {
@@ -323,18 +325,24 @@ static void *process_stats_thread(void *param) {
PHY_VARS_gNB *gNB = (PHY_VARS_gNB *)param;
+ reset_meas(&gNB->phy_proc_tx);
reset_meas(&gNB->dlsch_encoding_stats);
- reset_meas(&gNB->dlsch_scrambling_stats);
- reset_meas(&gNB->dlsch_modulation_stats);
+ reset_meas(&gNB->phy_proc_rx);
+ reset_meas(&gNB->ul_indication_stats);
+ reset_meas(&gNB->rx_pusch_stats);
+ reset_meas(&gNB->ulsch_decoding_stats);
wait_sync("process_stats_thread");
while(!oai_exit)
{
sleep(1);
- print_meas(&gNB->dlsch_encoding_stats, "pdsch_encoding", NULL, NULL);
- print_meas(&gNB->dlsch_scrambling_stats, "pdsch_scrambling", NULL, NULL);
- print_meas(&gNB->dlsch_modulation_stats, "pdsch_modulation", NULL, NULL);
+ print_meas(&gNB->phy_proc_tx, "L1 Tx processing", NULL, NULL);
+ print_meas(&gNB->dlsch_encoding_stats, "DLSCH encoding", NULL, NULL);
+ print_meas(&gNB->phy_proc_rx, "L1 Rx processing", NULL, NULL);
+ print_meas(&gNB->ul_indication_stats, "UL Indication", NULL, NULL);
+ print_meas(&gNB->rx_pusch_stats, "PUSCH inner-receiver", NULL, NULL);
+ print_meas(&gNB->ulsch_decoding_stats, "PUSCH decoding", NULL, NULL);
}
return(NULL);
}
@@ -347,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-ru.c b/executables/nr-ru.c
index b059c6f4e8..c068bef775 100644
--- a/executables/nr-ru.c
+++ b/executables/nr-ru.c
@@ -89,7 +89,7 @@ static int DEFBFW[] = {0x00007fff};
#include "s1ap_eNB.h"
#include "SIMULATION/ETH_TRANSPORT/proto.h"
-
+#include
#include "T.h"
@@ -119,7 +119,6 @@ uint16_t sl_ahead;
extern int emulate_rf;
extern int numerology;
-extern int usrp_tx_thread;
/*************************************************************/
/* Functions to attach and configure RRU */
@@ -1344,12 +1343,17 @@ void *ru_thread( void *param ) {
for (aa=0;aanb_rx;aa++)
memcpy((void*)RC.gNB[0]->common_vars.rxdataF[aa],
(void*)ru->common.rxdataF[aa], fp->symbols_per_slot*fp->ofdm_symbol_size*sizeof(int32_t));
-
+ if (IS_SOFTMODEM_DOSCOPE && RC.gNB[0]->scopeData)
+ ((scopeData_t*)RC.gNB[0]->scopeData)->slotFunc(ru->common.rxdataF[0],proc->tti_rx, RC.gNB[0]->scopeData);
// Do PRACH RU processing
int prach_id=find_nr_prach_ru(ru,proc->frame_rx,proc->tti_rx,SEARCH_EXIST);
uint8_t prachStartSymbol,N_dur;
if (prach_id>=0) {
+
+ T(T_GNB_PHY_PRACH_INPUT_SIGNAL, T_INT(proc->frame_rx), T_INT(proc->tti_rx), T_INT(0),
+ T_BUFFER(&ru->common.rxdata[0][fp->get_samples_slot_timestamp(proc->tti_rx-1,fp,0)]/*-ru->N_TA_offset*/, fp->get_samples_per_slot(proc->tti_rx,fp)*4*2));
+
N_dur = get_nr_prach_duration(ru->prach_list[prach_id].fmt);
/*
get_nr_prach_info_from_index(ru->config.prach_config.prach_ConfigurationIndex.value,
diff --git a/executables/nr-softmodem-common.h b/executables/nr-softmodem-common.h
index 500819e684..813ffcf8fa 100644
--- a/executables/nr-softmodem-common.h
+++ b/executables/nr-softmodem-common.h
@@ -68,11 +68,15 @@
#define CONFIG_HLP_SOFTS "Enable soft scope and L1 and L2 stats (Xforms)\n"
#define CONFIG_HLP_EXMCAL "Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n"
#define CONFIG_HLP_ITTIL "Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n"
-#define CONFIG_HLP_DLMCS "Set the maximum downlink MCS\n"
+#define CONFIG_HLP_DLMCS_PHYTEST "Set the downlink MCS for PHYTEST mode\n"
#define CONFIG_HLP_STMON "Enable processing timing measurement of lte softmodem on per subframe basis \n"
#define CONFIG_HLP_PRB "Set the PRB, valid values: 6, 25, 50, 100 \n"
#define CONFIG_HLP_MSLOTS "Skip the missed slots/subframes \n"
-#define CONFIG_HLP_ULMCS "Set the maximum uplink MCS\n"
+#define CONFIG_HLP_ULMCS_PHYTEST "Set the uplink MCS for PHYTEST mode\n"
+#define CONFIG_HLP_DLBW_PHYTEST "Set the number of PRBs used for DLSCH in PHYTEST mode\n"
+#define CONFIG_HLP_ULBW_PHYTEST "Set the number of PRBs used for ULSCH in PHYTEST mode\n"
+#define CONFIG_HLP_DLBM_PHYTEST "Bitmap for DLSCH slots (slot 0 starts at LSB)\n"
+#define CONFIG_HLP_ULBM_PHYTEST "Bitmap for ULSCH slots (slot 0 starts at LSB)\n"
#define CONFIG_HLP_TDD "Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n"
#define CONFIG_HLP_UE "Set the lte softmodem as a UE\n"
#define CONFIG_HLP_L2MONW "Enable L2 wireshark messages on localhost \n"
diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c
index 63c06563d2..8ac3a63efe 100644
--- a/executables/nr-softmodem.c
+++ b/executables/nr-softmodem.c
@@ -85,6 +85,7 @@ unsigned short config_frames[4] = {2,9,11,13};
#include "x2ap_eNB.h"
#include "ngap_gNB.h"
#include "gnb_paramdef.h"
+#include
#include "nfapi/oai_integration/vendor_ext.h"
pthread_cond_t nfapi_sync_cond;
@@ -92,11 +93,12 @@ pthread_mutex_t nfapi_sync_mutex;
int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex
extern uint8_t nfapi_mode; // Default to monolithic mode
-
+THREAD_STRUCT thread_struct;
pthread_cond_t sync_cond;
pthread_mutex_t sync_mutex;
int sync_var=-1; //!< protected by mutex \ref sync_mutex.
int config_sync_var=-1;
+msc_interface_t msc_interface;
volatile int start_gNB = 0;
volatile int oai_exit = 0;
@@ -114,7 +116,6 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
//Temp fix for inexistent NR upper layer
unsigned char NB_gNB_INST = 1;
-static char *itti_dump_file = NULL;
int UE_scan = 1;
int UE_scan_carrier = 0;
@@ -160,8 +161,6 @@ int otg_enabled;
//static NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs];
//static nfapi_nr_config_request_t *config[MAX_NUM_CCs];
-uint32_t target_dl_mcs = 28; //maximum allowed mcs
-uint32_t target_ul_mcs = 20;
uint32_t timing_advance = 0;
uint64_t num_missed_slots=0; // counter for the number of missed slots
@@ -179,7 +178,6 @@ extern void *udp_eNB_task(void *args_p);
int transmission_mode=1;
int emulate_rf = 0;
int numerology = 0;
-int usrp_tx_thread = 0;
static char *parallel_config = NULL;
@@ -809,7 +807,7 @@ if(!IS_SOFTMODEM_NOS1)
printf("RC.nb_RU:%d\n", RC.nb_RU);
// once all RUs are ready initialize the rest of the gNBs ((dependence on final RU parameters after configuration)
printf("ALL RUs ready - init gNBs\n");
- if(IS_SOFTMODEM_DOFORMS) {
+ if(IS_SOFTMODEM_DOSCOPE) {
sleep(1);
scopeParms_t p;
p.argc=&argc;
diff --git a/executables/nr-softmodem.h b/executables/nr-softmodem.h
index d6cfe6b906..928558013c 100644
--- a/executables/nr-softmodem.h
+++ b/executables/nr-softmodem.h
@@ -18,19 +18,27 @@
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define CMDLINE_PARAMS_DESC_GNB { \
- {"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \
{"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \
{"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \
{"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, i8ptr:&threequarter_fs, defintval:0, TYPE_INT8, 0}, \
- {"K" , CONFIG_HLP_ITTIL, PARAMFLAG_NOFREE, strptr:&itti_dump_file, defstrval:"/tmp/itti.dump", TYPE_STRING, 0}, \
- {"m" , CONFIG_HLP_DLMCS, 0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \
- {"t" , CONFIG_HLP_ULMCS, 0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \
+ {"m" , CONFIG_HLP_DLMCS_PHYTEST,0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \
+ {"t" , CONFIG_HLP_ULMCS_PHYTEST,0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \
+ {"M" , CONFIG_HLP_DLBW_PHYTEST,0, uptr:&target_dl_bw, defintval:0, TYPE_UINT, 0}, \
+ {"T" , CONFIG_HLP_ULBW_PHYTEST,0, uptr:&target_ul_bw, defintval:0, TYPE_UINT, 0}, \
+ {"D" , CONFIG_HLP_DLBM_PHYTEST,0, u64ptr:&dlsch_slot_bitmap, defintval:0, TYPE_UINT64, 0}, \
+ {"U" , CONFIG_HLP_ULBM_PHYTEST,0, u64ptr:&ulsch_slot_bitmap, defintval:0, TYPE_UINT64, 0}, \
{"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0, iptr:&usrp_tx_thread, defstrval:0, TYPE_INT, 0}, \
{"s" , CONFIG_HLP_SNR, 0, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0}, \
}
#include "threads_t.h"
extern threads_t threads;
+extern uint32_t target_dl_mcs;
+extern uint32_t target_ul_mcs;
+extern uint32_t target_dl_bw;
+extern uint32_t target_ul_bw;
+extern uint64_t dlsch_slot_bitmap;
+extern uint64_t ulsch_slot_bitmap;
// In nr-gnb.c
extern void init_gNB(int single_thread_flag,int wait_for_sync);
diff --git a/executables/nr-ue.c b/executables/nr-ue.c
index 2adf373196..137fcdfec3 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));
@@ -516,6 +555,7 @@ void *UE_thread(void *arg) {
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,14 +679,14 @@ 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);
@@ -659,7 +699,7 @@ void *UE_thread(void *arg) {
// 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 2854457eee..13a191a18a 100644
--- a/executables/nr-uesoftmodem.c
+++ b/executables/nr-uesoftmodem.c
@@ -88,6 +88,8 @@ unsigned short config_frames[4] = {2,9,11,13};
#include "executables/thread-common.h"
extern const char *duplex_mode[];
+msc_interface_t msc_interface;
+THREAD_STRUCT thread_struct;
// Thread variables
pthread_cond_t nfapi_sync_cond;
@@ -145,7 +147,7 @@ int chain_offset = 0;
int card_offset = 0;
uint64_t num_missed_slots = 0; // counter for the number of missed slots
int transmission_mode = 1;
-int usrp_tx_thread = 0;
+int numerology = 0;
int oaisim_flag = 0;
int emulate_rf = 0;
@@ -179,6 +181,23 @@ void print_difftimes(void) {
LOG_I(HW,"difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec);
}
+int create_tasks_nrue(uint32_t ue_nb) {
+ LOG_D(NR_RRC, "%s(ue_nb:%d)\n", __FUNCTION__, ue_nb);
+ itti_wait_ready(1);
+
+ if (ue_nb > 0) {
+ LOG_I(NR_RRC,"create TASK_RRC_NRUE \n");
+ if (itti_create_task (TASK_RRC_NRUE, rrc_nrue_task, NULL) < 0) {
+ LOG_E(NR_RRC, "Create task for RRC UE failed\n");
+ return -1;
+ }
+
+ }
+
+ itti_wait_ready(0);
+ return 0;
+}
+
void exit_function(const char *file, const char *function, const int line, const char *s) {
int CC_id;
@@ -213,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; i TO TERMINATE\n");
+
+ if (create_tasks_nrue(1) < 0) {
+ printf("cannot create ITTI tasks\n");
+ exit(-1); // need a softer mode
+ }
+
// Sleep a while before checking all parameters have been used
// Some are used directly in external threads, asynchronously
sleep(20);
diff --git a/executables/ocp-gnb.c b/executables/ocp-gnb.c
index 4ddc7870d9..326f7d277f 100644
--- a/executables/ocp-gnb.c
+++ b/executables/ocp-gnb.c
@@ -61,8 +61,6 @@ uint32_t do_forms=0;
unsigned int mmapped_dma=0;
int8_t threequarter_fs=0;
-uint32_t target_dl_mcs = 28; //maximum allowed mcs
-uint32_t target_ul_mcs = 20;
int chain_offset=0;
uint16_t sl_ahead=6;
uint16_t sf_ahead=6;
@@ -70,16 +68,15 @@ uint32_t timing_advance = 0;
int transmission_mode=1;
int emulate_rf = 0;
int numerology = 0;
-int usrp_tx_thread = 0;
int config_sync_var=-1;
pthread_mutex_t nfapi_sync_mutex;
pthread_cond_t nfapi_sync_cond;
int nfapi_sync_var=-1;
-uint8_t nfapi_mode = NFAPI_MONOLITHIC; // Default to monolithic mode
double cpuf;
+THREAD_STRUCT thread_struct;
pthread_cond_t sync_cond;
pthread_mutex_t sync_mutex;
@@ -95,7 +92,8 @@ time_stats_t nfapi_meas; // total tx time
time_stats_t softmodem_stats_rx_sf; // total rx time
// not used but needed for link
openair0_config_t openair0_cfg[MAX_CARDS];
-
+uint16_t slot_ahead=6;
+msc_interface_t msc_interface;
AGENT_RRC_xface *agent_rrc_xface[NUM_MAX_ENB];
AGENT_MAC_xface *agent_mac_xface[NUM_MAX_ENB];
int flexran_agent_start(mid_t mod_id) {
@@ -122,7 +120,6 @@ int restart_L1L2(module_id_t gnb_id) {
}
static int wait_for_sync = 0;
-static char *itti_dump_file = NULL;
static double snr_dB=20;
static int DEFBANDS[] = {7};
static int DEFENBS[] = {0};
@@ -996,7 +993,7 @@ int main( int argc, char **argv ) {
(void *)NULL, "time_meas", -1, OAI_PRIORITY_RT_LOW);
}
- if(IS_SOFTMODEM_DOFORMS) {
+ if(IS_SOFTMODEM_DOSCOPE) {
scopeParms_t tmp= {&argc, argv, &ru, RC.gNB[0]};
load_softscope("nr",&tmp);
}
diff --git a/executables/softmodem-common.c b/executables/softmodem-common.c
index 1077c0e1ac..fa6b674765 100644
--- a/executables/softmodem-common.c
+++ b/executables/softmodem-common.c
@@ -45,6 +45,8 @@
static softmodem_params_t softmodem_params;
char *parallel_config=NULL;
char *worker_config=NULL;
+msc_interface_t msc_interface;
+int usrp_tx_thread = 0;
uint8_t nfapi_mode=0;
@@ -86,7 +88,7 @@ char *get_softmodem_function(uint64_t *sofmodemfunc_mask_ptr) {
void get_common_options(uint32_t execmask) {
uint32_t online_log_messages=0;
uint32_t glog_level=0 ;
- uint32_t start_telnetsrv = 0;
+ uint32_t start_telnetsrv = 0, start_telnetclt = 0;
uint32_t noS1 = 0, nokrnmod = 0, nonbiot = 0;
uint32_t rfsim = 0, basicsim = 0, do_forms = 0;
char *logmem_filename = NULL;
@@ -95,21 +97,26 @@ void get_common_options(uint32_t execmask) {
checkedparam_t cmdline_log_CheckParams[] = CMDLINE_LOGPARAMS_CHECK_DESC;
check_execmask(execmask);
config_get( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL);
- config_set_checkfunctions(cmdline_logparams, cmdline_log_CheckParams,
- sizeof(cmdline_logparams)/sizeof(paramdef_t));
- config_get( cmdline_logparams,sizeof(cmdline_logparams)/sizeof(paramdef_t),NULL);
-
- if(config_isparamset(cmdline_logparams,CMDLINE_ONLINELOG_IDX)) {
+
+ int numparams=sizeof(cmdline_logparams)/sizeof(paramdef_t);
+ config_set_checkfunctions(cmdline_logparams, cmdline_log_CheckParams,numparams);
+ config_get( cmdline_logparams,numparams,NULL);
+
+ if(config_isparamset(cmdline_logparams,config_paramidx_fromname(cmdline_logparams,numparams, CONFIG_FLOG_OPT))) {
set_glog_onlinelog(online_log_messages);
}
- if(config_isparamset(cmdline_logparams,CMDLINE_GLOGLEVEL_IDX)) {
+ if(config_isparamset(cmdline_logparams,config_paramidx_fromname(cmdline_logparams,numparams, CONFIG_LOGL_OPT))) {
set_glog(glog_level);
}
if (start_telnetsrv) {
load_module_shlib("telnetsrv",NULL,0,NULL);
}
+
+ if (start_telnetclt) {
+ set_softmodem_optmask(SOFTMODEM_TELNETCLT_BIT);
+ }
if (logmem_filename != NULL && strlen(logmem_filename) > 0) {
log_mem_filename = &logmem_filename[0];
@@ -140,7 +147,7 @@ void get_common_options(uint32_t execmask) {
}
if (do_forms) {
- set_softmodem_optmask(SOFTMODEM_DOFORMS_BIT);
+ set_softmodem_optmask(SOFTMODEM_DOSCOPE_BIT);
}
if(parallel_config != NULL) set_parallel_conf(parallel_config);
diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h
index 7a7be1de96..9fa96462fd 100644
--- a/executables/softmodem-common.h
+++ b/executables/softmodem-common.h
@@ -73,6 +73,7 @@ extern "C"
#define CONFIG_HLP_STMON "Enable processing timing measurement of lte softmodem on per subframe basis \n"
#define CONFIG_HLP_256QAM "Use the 256 QAM mcs table for PDSCH\n"
+#define CONFIG_HLP_NONSTOP "Go back to frame sync mode after 100 consecutive PBCH failures\n"
//#define CONFIG_HLP_NUMUES "Set the number of UEs for the emulation"
#define CONFIG_HLP_MSLOTS "Skip the missed slots/subframes \n"
#define CONFIG_HLP_ULMCS "Set the maximum uplink MCS\n"
@@ -91,6 +92,7 @@ extern "C"
#define CONFIG_HLP_RFSIM "Run in rf simulator mode (also known as basic simulator)\n"
#define CONFIG_HLP_NOKRNMOD "(noS1 only): Use tun instead of namesh module \n"
#define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n"
+#define CONFIG_HLP_USRP_THREAD "having extra thead for usrp tx\n"
#define CONFIG_HLP_NFAPI "Change the nFAPI mode for NR\n"
/*-----------------------------------------------------------------------------------------------------------------------------------------------------*/
@@ -114,9 +116,11 @@ extern "C"
#define USIM_TEST softmodem_params.usim_test
#define USE_256QAM_TABLE softmodem_params.use_256qam_table
#define NFAPI softmodem_params.nfapi
+#define NON_STOP softmodem_params.non_stop
#define DEFAULT_RFCONFIG_FILE "/usr/local/etc/syriq/ue.band7.tm1.PRB100.NR40.dat";
+extern int usrp_tx_thread;
#define CMDLINE_PARAMS_DESC { \
{"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&RF_CONFIG_FILE, defstrval:NULL, TYPE_STRING, sizeof(RF_CONFIG_FILE)},\
{"split73", CONFIG_HLP_SPLIT73, 0, strptr:(char **)&SPLIT73, defstrval:NULL, TYPE_STRING, sizeof(SPLIT73)},\
@@ -144,7 +148,9 @@ extern "C"
{"nokrnmod", CONFIG_HLP_NOKRNMOD, PARAMFLAG_BOOL, uptr:&nokrnmod, defintval:0, TYPE_INT, 0}, \
{"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, uptr:&nonbiot, defuintval:0, TYPE_INT, 0}, \
{"use-256qam-table", CONFIG_HLP_256QAM, PARAMFLAG_BOOL, iptr:&USE_256QAM_TABLE, defintval:0, TYPE_INT, 0}, \
+ {"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0, iptr:&usrp_tx_thread, defstrval:0, TYPE_INT, 0}, \
{"nfapi", CONFIG_HLP_NFAPI, 0, u8ptr:&nfapi_mode, defintval:0, TYPE_UINT8, 0}, \
+ {"non-stop", CONFIG_HLP_NONSTOP, PARAMFLAG_BOOL, iptr:&NON_STOP, defintval:0, TYPE_INT, 0}, \
}
@@ -153,23 +159,22 @@ extern "C"
#define CONFIG_HLP_LOGV "Set the global log verbosity \n"
#define CONFIG_HLP_TELN "Start embedded telnet server \n"
#define CONFIG_HLP_MSC "Enable the MSC tracing utility \n"
-/*----------------------------------------------------------------------------------------------------------------------------*/
-/* command line parameters for LOG utility */
-/* optname helpstr paramflags XXXptr defXXXval type numelt */
-/*----------------------------------------------------------------------------------------------------------------------------*/
+#define CONFIG_FLOG_OPT "R"
+#define CONFIG_LOGL_OPT "g"
+/*-------------------------------------------------------------------------------------------------------------------------------------------------*/
+/* command line parameters for LOG utility */
+/* optname helpstr paramflags XXXptr defXXXval type numelt */
+/*-------------------------------------------------------------------------------------------------------------------------------------------------*/
#define START_MSC softmodem_params.start_msc
#define CMDLINE_LOGPARAMS_DESC { \
- {"R" , CONFIG_HLP_FLOG, 0, uptr:&online_log_messages, defintval:1, TYPE_INT, 0}, \
- {"g" , CONFIG_HLP_LOGL, 0, uptr:&glog_level, defintval:0, TYPE_UINT, 0}, \
- {"telnetsrv", CONFIG_HLP_TELN, PARAMFLAG_BOOL, uptr:&start_telnetsrv, defintval:0, TYPE_UINT, 0}, \
- {"msc", CONFIG_HLP_MSC, PARAMFLAG_BOOL, uptr:&START_MSC, defintval:0, TYPE_UINT, 0}, \
- {"log-mem", NULL, 0, strptr:(char **)&logmem_filename, defstrval:NULL, TYPE_STRING, 0}, \
+ {CONFIG_FLOG_OPT , CONFIG_HLP_FLOG, 0, uptr:&online_log_messages, defintval:1, TYPE_INT, 0}, \
+ {CONFIG_LOGL_OPT , CONFIG_HLP_LOGL, 0, uptr:&glog_level, defintval:0, TYPE_UINT, 0}, \
+ {"telnetsrv", CONFIG_HLP_TELN, PARAMFLAG_BOOL, uptr:&start_telnetsrv, defintval:0, TYPE_UINT, 0}, \
+ {"msc", CONFIG_HLP_MSC, PARAMFLAG_BOOL, uptr:&START_MSC, defintval:0, TYPE_UINT, 0}, \
+ {"log-mem", NULL, 0, strptr:(char **)&logmem_filename, defstrval:NULL, TYPE_STRING, 0}, \
+ {"telnetclt", NULL, 0, uptr:&start_telnetclt, defstrval:NULL, TYPE_UINT, 0}, \
}
-#define CMDLINE_ONLINELOG_IDX 0
-#define CMDLINE_GLOGLEVEL_IDX 1
-#define CMDLINE_GLOGVERBO_IDX 2
-#define CMDLINE_STARTTELN_IDX 3
/* check function for global log level */
#define CMDLINE_LOGPARAMS_CHECK_DESC { \
@@ -178,6 +183,7 @@ extern "C"
{ .s5= {NULL} } , \
{ .s5= {NULL} } , \
{ .s5= {NULL} } , \
+ { .s5= {NULL} } , \
}
/***************************************************************************************************************************************/
@@ -188,8 +194,9 @@ extern "C"
#define SOFTMODEM_RFSIM_BIT (1<<10)
#define SOFTMODEM_BASICSIM_BIT (1<<11)
#define SOFTMODEM_SIML1_BIT (1<<12)
-#define SOFTMODEM_DOFORMS_BIT (1<<15)
+#define SOFTMODEM_DOSCOPE_BIT (1<<15)
#define SOFTMODEM_RECPLAY_BIT (1<<16)
+#define SOFTMODEM_TELNETCLT_BIT (1<<17)
#define SOFTMODEM_ENB_BIT (1<<20)
#define SOFTMODEM_GNB_BIT (1<<21)
#define SOFTMODEM_4GUE_BIT (1<<22)
@@ -204,8 +211,9 @@ extern "C"
#define IS_SOFTMODEM_RFSIM ( get_softmodem_optmask() & SOFTMODEM_RFSIM_BIT)
#define IS_SOFTMODEM_BASICSIM ( get_softmodem_optmask() & SOFTMODEM_BASICSIM_BIT)
#define IS_SOFTMODEM_SIML1 ( get_softmodem_optmask() & SOFTMODEM_SIML1_BIT)
-#define IS_SOFTMODEM_DOFORMS ( get_softmodem_optmask() & SOFTMODEM_DOFORMS_BIT)
+#define IS_SOFTMODEM_DOSCOPE ( get_softmodem_optmask() & SOFTMODEM_DOSCOPE_BIT)
#define IS_SOFTMODEM_IQPLAYER ( get_softmodem_optmask() & SOFTMODEM_RECPLAY_BIT)
+#define IS_SOFTMODEM_TELNETCLT_BIT ( get_softmodem_optmask() & SOFTMODEM_TELNETCLT_BIT)
#define IS_SOFTMODEM_ENB_BIT ( get_softmodem_optmask() & SOFTMODEM_ENB_BIT)
#define IS_SOFTMODEM_GNB_BIT ( get_softmodem_optmask() & SOFTMODEM_GNB_BIT)
#define IS_SOFTMODEM_4GUE_BIT ( get_softmodem_optmask() & SOFTMODEM_4GUE_BIT)
@@ -233,6 +241,7 @@ typedef struct {
uint32_t send_dmrs_sync;
int use_256qam_table;
uint8_t nfapi;
+ int non_stop;
} softmodem_params_t;
extern uint64_t get_softmodem_optmask(void);
diff --git a/executables/thread-common.h b/executables/thread-common.h
index 6f3af3cfc0..0aaeb3c30e 100644
--- a/executables/thread-common.h
+++ b/executables/thread-common.h
@@ -3,7 +3,7 @@
#include "PHY/defs_common.h"
-THREAD_STRUCT thread_struct;
+extern THREAD_STRUCT thread_struct;
static inline void set_parallel_conf(char *parallel_conf) {
mapping config[]= {
diff --git a/nfapi/oai_integration/nfapi_pnf.c b/nfapi/oai_integration/nfapi_pnf.c
index 4ca02ed929..5ce66aad89 100644
--- a/nfapi/oai_integration/nfapi_pnf.c
+++ b/nfapi/oai_integration/nfapi_pnf.c
@@ -73,7 +73,6 @@ extern pthread_mutex_t nfapi_sync_mutex;
extern int nfapi_sync_var;
extern int sync_var;
-char uecap_xer_in;
extern void init_eNB_afterRU(void);
extern void init_UE_stub(int nb_inst,int,int);
@@ -2199,7 +2198,7 @@ void configure_nr_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_add
pnf.phys[0].udp.tx_port = vnf_p7_port;
strcpy(pnf.phys[0].udp.tx_addr, vnf_ip_addr);
strcpy(pnf.phys[0].local_addr, pnf_ip_addr);
- printf("%s() VNF:%s:%d PNF_PHY[addr:%s UDP:tx_addr:%s:%d rx:%d]\n",
+ printf("%s() VNF:%s:%d PNF_PHY[addr:%s UDP:tx_addr:%s:%u rx:%u]\n",
__FUNCTION__,config->vnf_ip_addr, config->vnf_p5_port,
pnf.phys[0].local_addr,
pnf.phys[0].udp.tx_addr, pnf.phys[0].udp.tx_port,
@@ -2250,7 +2249,7 @@ void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr,
pnf.phys[0].udp.tx_port = vnf_p7_port;
strcpy(pnf.phys[0].udp.tx_addr, vnf_ip_addr);
strcpy(pnf.phys[0].local_addr, pnf_ip_addr);
- printf("%s() VNF:%s:%d PNF_PHY[addr:%s UDP:tx_addr:%s:%d rx:%d]\n",
+ printf("%s() VNF:%s:%d PNF_PHY[addr:%s UDP:tx_addr:%s:%u rx:%u]\n",
__FUNCTION__,
config->vnf_ip_addr, config->vnf_p5_port,
pnf.phys[0].local_addr,
diff --git a/nfapi/oai_integration/nfapi_pnf.h b/nfapi/oai_integration/nfapi_pnf.h
index b3ab7cbdbc..61d4847eba 100644
--- a/nfapi/oai_integration/nfapi_pnf.h
+++ b/nfapi/oai_integration/nfapi_pnf.h
@@ -21,6 +21,7 @@
#if !defined(NFAPI_PNF_H__)
#define NFAPI_PNF_H__
+extern nfapi_ue_release_request_body_t release_rntis;
int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind);
void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port);
void configure_nr_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port);
diff --git a/nfapi/open-nFAPI/common/src/debug.c b/nfapi/open-nFAPI/common/src/debug.c
index a45d41d7d7..f53be43223 100644
--- a/nfapi/open-nFAPI/common/src/debug.c
+++ b/nfapi/open-nFAPI/common/src/debug.c
@@ -1,76 +1,76 @@
-/*
- * Copyright 2017 Cisco Systems, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-
-#define MAX_MSG_LENGTH 2096
-#define TRACE_HEADER_LENGTH 44
-
-void nfapi_trace_dbg(nfapi_trace_level_t level, const char *format, ...);
-
-// initialize the trace function to 0
-void (*nfapi_trace_g)(nfapi_trace_level_t level, const char* format, ...) = &nfapi_trace_dbg;
-
-nfapi_trace_level_t nfapi_trace_level_g = NFAPI_TRACE_INFO;
-//nfapi_trace_level_t nfapi_trace_level_g = NFAPI_TRACE_WARN;
-
-void nfapi_set_trace_level(nfapi_trace_level_t new_level)
-{
- nfapi_trace_level_g = new_level;
-}
-
-void nfapi_trace_dbg(nfapi_trace_level_t level, const char *format, ...)
-{
- char trace_buff[MAX_MSG_LENGTH + TRACE_HEADER_LENGTH];
- uint32_t num_chars;
- va_list p_args;
- struct timeval tv;
- pthread_t tid = pthread_self();
-
- (void)gettimeofday(&tv, NULL);
-
- num_chars = (uint32_t)snprintf(trace_buff, TRACE_HEADER_LENGTH, "%04u.%06u: 0x%02x: %10u: ", ((uint32_t)tv.tv_sec) & 0x1FFF, (uint32_t)tv.tv_usec, (uint32_t)level, (uint32_t)tid);
-
- if (num_chars > TRACE_HEADER_LENGTH)
- {
- printf("trace_dbg: Error, num_chars is too large: %d", num_chars);
- return;
- }
-
- va_start(p_args, format);
- if ((num_chars = (uint32_t)vsnprintf(&trace_buff[num_chars], MAX_MSG_LENGTH, format, p_args)))
- {
- if (level <= NFAPI_TRACE_WARN)
- {
- printf("%s", trace_buff);
- }
- printf("%s", trace_buff);
- }
- va_end(p_args);
-}
+/*
+ * Copyright 2017 Cisco Systems, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#define MAX_MSG_LENGTH 2096
+#define TRACE_HEADER_LENGTH 44
+
+void nfapi_trace_dbg(nfapi_trace_level_t level, const char *format, ...);
+
+// initialize the trace function to 0
+void (*nfapi_trace_g)(nfapi_trace_level_t level, const char* format, ...) = &nfapi_trace_dbg;
+
+nfapi_trace_level_t nfapi_trace_level_g = NFAPI_TRACE_INFO;
+//nfapi_trace_level_t nfapi_trace_level_g = NFAPI_TRACE_WARN;
+
+void nfapi_set_trace_level(nfapi_trace_level_t new_level)
+{
+ nfapi_trace_level_g = new_level;
+}
+
+void nfapi_trace_dbg(nfapi_trace_level_t level, const char *format, ...)
+{
+ char trace_buff[MAX_MSG_LENGTH + TRACE_HEADER_LENGTH];
+ uint32_t num_chars;
+ va_list p_args;
+ struct timeval tv;
+ pthread_t tid = pthread_self();
+
+ (void)gettimeofday(&tv, NULL);
+
+ num_chars = (uint32_t)snprintf(trace_buff, TRACE_HEADER_LENGTH, "%04u.%06u: 0x%02x: %10u: ", ((uint32_t)tv.tv_sec) & 0x1FFF, (uint32_t)tv.tv_usec, (uint32_t)level, (uint32_t)tid);
+
+ if (num_chars > TRACE_HEADER_LENGTH)
+ {
+ printf("trace_dbg: Error, num_chars is too large: %u", num_chars);
+ return;
+ }
+
+ va_start(p_args, format);
+ if ((num_chars = (uint32_t)vsnprintf(&trace_buff[num_chars], MAX_MSG_LENGTH, format, p_args)))
+ {
+ if (level <= NFAPI_TRACE_WARN)
+ {
+ printf("%s", trace_buff);
+ }
+ printf("%s", trace_buff);
+ }
+ va_end(p_args);
+}
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
index 8c2118cd3d..0436f92a8d 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
@@ -1058,12 +1058,6 @@ typedef struct {
fapi_nr_tdd_table_t tdd_table;
fapi_nr_prach_config_t prach_config;
- fapi_nr_dl_bwp_common_config_t dl_bwp_common;
- fapi_nr_dl_bwp_dedicated_config_t dl_bwp_dedicated;
-
- fapi_nr_ul_bwp_common_config_t ul_bwp_common;
- fapi_nr_ul_bwp_dedicated_config_t ul_bwp_dedicated;
-
} fapi_nr_config_request_t;
#endif
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
index 444140509c..bcb0a94ca8 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
@@ -691,7 +691,7 @@ typedef struct
typedef struct
{
uint16_t pm_idx;//Index to precoding matrix (PM) pre-stored at cell configuration. Note: If precoding is not used this parameter should be set to 0. Value: 0->65535.
- nfapi_nr_dig_bf_interface_t dig_bf_interface_list[255];//max dig_bf_interfaces
+ nfapi_nr_dig_bf_interface_t dig_bf_interface_list[1];//max dig_bf_interfaces
}nfapi_nr_tx_precoding_and_beamforming_number_of_prgs_t;
@@ -702,7 +702,7 @@ typedef struct
uint16_t prg_size;//Size in RBs of a precoding resource block group (PRG) – to which same precoding and digital beamforming gets applied. Value: 1->275
//watchout: dig_bf_interfaces here, in table 3-53 it's dig_bf_interface
uint8_t dig_bf_interfaces;//Number of STD ant ports (parallel streams) feeding into the digBF Value: 0->255
- nfapi_nr_tx_precoding_and_beamforming_number_of_prgs_t prgs_list[275];//max prg_size
+ nfapi_nr_tx_precoding_and_beamforming_number_of_prgs_t prgs_list[1];//max prg_size
}nfapi_nr_tx_precoding_and_beamforming_t;
diff --git a/nfapi/open-nFAPI/pnf_sim/src/fapi_stub.cpp b/nfapi/open-nFAPI/pnf_sim/src/fapi_stub.cpp
index 1c2f0bef80..4fe5065cea 100644
--- a/nfapi/open-nFAPI/pnf_sim/src/fapi_stub.cpp
+++ b/nfapi/open-nFAPI/pnf_sim/src/fapi_stub.cpp
@@ -278,7 +278,7 @@ void *fapi_thread_start(void *ptr) {
if(instance->tick == 1000) {
if(instance->tx_byte_count > 0) {
- printf("[FAPI] Tx rate %d bytes/sec\n", instance->tx_byte_count);
+ printf("[FAPI] Tx rate %u bytes/sec\n", instance->tx_byte_count);
instance->tx_byte_count = 0;
}
@@ -319,7 +319,7 @@ void *fapi_thread_start(void *ptr) {
millisec = now_ts.tv_nsec / 1e6;
if(last_millisec != -1 && ((last_millisec + 1 ) % 1000) != millisec) {
- printf("*** missing millisec %d %d\n", last_millisec, millisec);
+ printf("*** missing millisec %u %u\n", last_millisec, millisec);
catchup = millisec - last_millisec - 1;
}
diff --git a/openair1/PHY/CODING/3gpplte_sse.c b/openair1/PHY/CODING/3gpplte_sse.c
index 2a7b789650..fffd04ea3c 100644
--- a/openair1/PHY/CODING/3gpplte_sse.c
+++ b/openair1/PHY/CODING/3gpplte_sse.c
@@ -44,8 +44,6 @@
//#define DEBUG_TURBO_ENCODER 1
//#define CALLGRIND 1
-unsigned short threegpplte_interleaver_output;
-unsigned long long threegpplte_interleaver_tmp;
#if defined(__x86_64__) || defined(__i386__)
struct treillis {
diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c
index e1ca906b55..bc1c0dac56 100644
--- a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c
+++ b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c
@@ -798,11 +798,11 @@ uint8_t phy_threegpplte_turbo_decoder8(int16_t *y,
n is the size in bits of the coded block, with the tail */
int n2;
llr_t y8[3*(n+16)] __attribute__((aligned(16)));
- llr_t systematic0[n+16] __attribute__ ((aligned(16)));
- llr_t systematic1[n+16] __attribute__ ((aligned(16)));
- llr_t systematic2[n+16] __attribute__ ((aligned(16)));
- llr_t yparity1[n+16] __attribute__ ((aligned(16)));
- llr_t yparity2[n+16] __attribute__ ((aligned(16)));
+ llr_t systematic0[n+32] __attribute__ ((aligned(16)));
+ llr_t systematic1[n+32] __attribute__ ((aligned(16)));
+ llr_t systematic2[n+32] __attribute__ ((aligned(16)));
+ llr_t yparity1[n+32] __attribute__ ((aligned(16)));
+ llr_t yparity2[n+32] __attribute__ ((aligned(16)));
llr_t ext[n+128] __attribute__((aligned(16)));
llr_t ext2[n+128] __attribute__((aligned(16)));
llr_t alpha[(n+16)*8] __attribute__ ((aligned(16)));
@@ -811,7 +811,7 @@ uint8_t phy_threegpplte_turbo_decoder8(int16_t *y,
llr_t m10[n+16] __attribute__ ((aligned(16)));
// int *pi2_p,*pi4_p,*pi5_p,*pi6_p;
int *pi4_p,*pi5_p,*pi6_p;
- llr_t *s,*s1,*s2,*yp1,*yp2,*yp;
+ llr_t *s1,*s2,*yp1,*yp2,*yp;
unsigned int i,j,iind;//,pi;
unsigned char iteration_cnt=0;
unsigned int crc,oldcrc,crc_len;
@@ -927,7 +927,6 @@ uint8_t phy_threegpplte_turbo_decoder8(int16_t *y,
yp128 = (int8x16_t *)y8;
#endif
- s = systematic0;
s1 = systematic1;
s2 = systematic2;
yp1 = yparity1;
@@ -938,7 +937,7 @@ uint8_t phy_threegpplte_turbo_decoder8(int16_t *y,
for (i=0; i<16 ; i++ )
for (j=0; jn) {
/*
- s[n]=0;s[n+1]=0;s[n+2]=0;s[n+3]=0;
- s[n+4]=0;s[n+5]=0;s[n+6]=0;s[n+7]=0;
+ systematic0[n]=0;systematic0[n+1]=0;systematic0[n+2]=0;systematic0[n+3]=0;
+ systematic0[n+4]=0;s[n+5]=0;s[n+6]=0;s[n+7]=0;
s1[n]=0;s1[n+1]=0;s1[n+2]=0;s1[n+3]=0;
s1[n+4]=0;s1[n+5]=0;s1[n+6]=0;s1[n+7]=0;
s2[n]=0;s2[n+1]=0;s2[n+2]=0;s2[n+3]=0;
@@ -961,26 +960,26 @@ uint8_t phy_threegpplte_turbo_decoder8(int16_t *y,
// Termination
for (i=n2; i 1280, 2401 -> 2560\n");
printf("block length %d: \n", block_length);
@@ -704,25 +702,25 @@ int main(int argc, char *argv[])
printf("SNR %f, Std iterations: %f\n",SNR, dec_iter->n_iter_std);
printf("SNR %f, Max iterations: %d\n",SNR, dec_iter->n_iter_max);
printf("\n");
- printf("Encoding time mean: %15.3f us\n",(double)time_optim->diff/time_optim->trials/1000.0/cpu_freq_GHz);
- printf("Encoding time std: %15.3f us\n",sqrt((double)time_optim->diff_square/time_optim->trials/pow(1000,2)/pow(cpu_freq_GHz,2)-pow((double)time_optim->diff/time_optim->trials/1000.0/cpu_freq_GHz,2)));
- printf("Encoding time max: %15.3f us\n",(double)time_optim->max/1000.0/cpu_freq_GHz);
+ printf("Encoding time mean: %15.3f us\n",(double)time_optim->diff/time_optim->trials/1000.0/get_cpu_freq_GHz());
+ printf("Encoding time std: %15.3f us\n",sqrt((double)time_optim->diff_square/time_optim->trials/pow(1000,2)/pow(get_cpu_freq_GHz(),2)-pow((double)time_optim->diff/time_optim->trials/1000.0/get_cpu_freq_GHz(),2)));
+ printf("Encoding time max: %15.3f us\n",(double)time_optim->max/1000.0/get_cpu_freq_GHz());
printf("\n");
- printf("Decoding time mean: %15.3f us\n",(double)time_decoder->diff/time_decoder->trials/1000.0/cpu_freq_GHz);
- printf("Decoding time std: %15.3f us\n",sqrt((double)time_decoder->diff_square/time_decoder->trials/pow(1000,2)/pow(cpu_freq_GHz,2)-pow((double)time_decoder->diff/time_decoder->trials/1000.0/cpu_freq_GHz,2)));
- printf("Decoding time max: %15.3f us\n",(double)time_decoder->max/1000.0/cpu_freq_GHz);
+ printf("Decoding time mean: %15.3f us\n",(double)time_decoder->diff/time_decoder->trials/1000.0/get_cpu_freq_GHz());
+ printf("Decoding time std: %15.3f us\n",sqrt((double)time_decoder->diff_square/time_decoder->trials/pow(1000,2)/pow(get_cpu_freq_GHz(),2)-pow((double)time_decoder->diff/time_decoder->trials/1000.0/get_cpu_freq_GHz(),2)));
+ printf("Decoding time max: %15.3f us\n",(double)time_decoder->max/1000.0/get_cpu_freq_GHz());
fprintf(fd,"%f %f %f %f %f %f %f %f %f %f %f %f %d \n",
SNR,
(double)decoded_errors[i]/(double)n_trials ,
(double)errors_bit/(double)n_trials/(double)block_length/(double)n_segments ,
errors_bit_uncoded/(double)n_trials/(double)n_segments ,
- (double)time_optim->diff/time_optim->trials/1000.0/cpu_freq_GHz,
- sqrt((double)time_optim->diff_square/time_optim->trials/pow(1000,2)/pow(cpu_freq_GHz,2)-pow((double)time_optim->diff/time_optim->trials/1000.0/cpu_freq_GHz,2)),
- (double)time_optim->max/1000.0/cpu_freq_GHz,
- (double)time_decoder->diff/time_decoder->trials/1000.0/cpu_freq_GHz,
- sqrt((double)time_decoder->diff_square/time_decoder->trials/pow(1000,2)/pow(cpu_freq_GHz,2)-pow((double)time_decoder->diff/time_decoder->trials/1000.0/cpu_freq_GHz,2)),
- (double)time_decoder->max/1000.0/cpu_freq_GHz,
+ (double)time_optim->diff/time_optim->trials/1000.0/get_cpu_freq_GHz(),
+ sqrt((double)time_optim->diff_square/time_optim->trials/pow(1000,2)/pow(get_cpu_freq_GHz(),2)-pow((double)time_optim->diff/time_optim->trials/1000.0/get_cpu_freq_GHz(),2)),
+ (double)time_optim->max/1000.0/get_cpu_freq_GHz(),
+ (double)time_decoder->diff/time_decoder->trials/1000.0/get_cpu_freq_GHz(),
+ sqrt((double)time_decoder->diff_square/time_decoder->trials/pow(1000,2)/pow(get_cpu_freq_GHz(),2)-pow((double)time_decoder->diff/time_decoder->trials/1000.0/get_cpu_freq_GHz(),2)),
+ (double)time_decoder->max/1000.0/get_cpu_freq_GHz(),
dec_iter->n_iter_mean,
dec_iter->n_iter_std,
dec_iter->n_iter_max
diff --git a/openair1/PHY/CODING/TESTBENCH/polartest.c b/openair1/PHY/CODING/TESTBENCH/polartest.c
index d9adf3e24f..e43ba507ab 100644
--- a/openair1/PHY/CODING/TESTBENCH/polartest.c
+++ b/openair1/PHY/CODING/TESTBENCH/polartest.c
@@ -113,7 +113,6 @@ int main(int argc, char *argv[])
//Initiate timing. (Results depend on CPU Frequency. Therefore, might change due to performance variances during simulation.)
time_stats_t timeEncoder,timeDecoder;
opp_enabled=1;
- cpu_freq_GHz = get_cpu_freq_GHz();
reset_meas(&timeEncoder);
reset_meas(&timeDecoder);
randominit(0);
@@ -324,9 +323,9 @@ if (logFlag){
#endif
//Iteration times are in microseconds.
- timeEncoderCumulative+=(timeEncoder.diff/(cpu_freq_GHz*1000.0));
- timeDecoderCumulative+=(timeDecoder.diff/(cpu_freq_GHz*1000.0));
- if (logFlag) fprintf(logFile,",%f,%d,%u,%f,%f\n", SNR, nBitError, blockErrorState, (timeEncoder.diff/(cpu_freq_GHz*1000.0)), (timeDecoder.diff/(cpu_freq_GHz*1000.0)));
+ timeEncoderCumulative+=(timeEncoder.diff/(get_cpu_freq_GHz()*1000.0));
+ timeDecoderCumulative+=(timeDecoder.diff/(get_cpu_freq_GHz()*1000.0));
+ if (logFlag) fprintf(logFile,",%f,%d,%u,%f,%f\n", SNR, nBitError, blockErrorState, (timeEncoder.diff/(get_cpu_freq_GHz()*1000.0)), (timeDecoder.diff/(get_cpu_freq_GHz()*1000.0)));
if (nBitError<0) {
blockErrorCumulative++;
@@ -348,7 +347,7 @@ if (logFlag){
printf("[ListSize=%d] SNR=%+8.3f, BLER=%9.6f, BER=%12.9f, t_Encoder=%9.3fus, t_Decoder=%9.3fus\n",
decoderListSize, SNR, ((double)blockErrorCumulative/iterations),
((double)bitErrorCumulative / (iterations*testLength)),
- (double)timeEncoder.diff/timeEncoder.trials/(cpu_freq_GHz*1000.0),(double)timeDecoder.diff/timeDecoder.trials/(cpu_freq_GHz*1000.0));
+ (double)timeEncoder.diff/timeEncoder.trials/(get_cpu_freq_GHz()*1000.0),(double)timeDecoder.diff/timeDecoder.trials/(get_cpu_freq_GHz()*1000.0));
//(timeEncoderCumulative/iterations),timeDecoderCumulative/iterations);
if (blockErrorCumulative==0 && bitErrorCumulative==0) break;
diff --git a/openair1/PHY/CODING/TESTBENCH/smallblocktest.c b/openair1/PHY/CODING/TESTBENCH/smallblocktest.c
index 02d5dc64e0..f750d24977 100644
--- a/openair1/PHY/CODING/TESTBENCH/smallblocktest.c
+++ b/openair1/PHY/CODING/TESTBENCH/smallblocktest.c
@@ -13,7 +13,6 @@ int main(int argc, char *argv[])
{
time_stats_t timeEncoder,timeDecoder;
opp_enabled=1;
- cpu_freq_GHz = get_cpu_freq_GHz();
reset_meas(&timeEncoder);
reset_meas(&timeDecoder);
randominit(0);
@@ -141,8 +140,8 @@ int main(int argc, char *argv[])
SNR,
((double)bitErrorCumulative / (iterations*messageLength)),
((double)blockErrorCumulative/iterations),
- ((double)timeEncoder.diff/timeEncoder.trials)/(cpu_freq_GHz),
- ((double)timeDecoder.diff/timeDecoder.trials)/(cpu_freq_GHz*1000.0));
+ ((double)timeEncoder.diff/timeEncoder.trials)/(get_cpu_freq_GHz()),
+ ((double)timeDecoder.diff/timeDecoder.trials)/(get_cpu_freq_GHz()*1000.0));
blockErrorCumulative=0;
bitErrorCumulative=0;
diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c
index 785b588b9f..3226c97f87 100644
--- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c
+++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c
@@ -39,7 +39,7 @@
#include "nrLDPC_bnProc.h"
#define NR_LDPC_ENABLE_PARITY_CHECK
-#define NR_LDPC_PROFILER_DETAIL
+//#define NR_LDPC_PROFILER_DETAIL
#ifdef NR_LDPC_DEBUG_MODE
#include "nrLDPC_tools/nrLDPC_debug.h"
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c
index 0d765a18b3..57b4c28661 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_sync_time.c
@@ -37,266 +37,82 @@
// Note: this is for prototype of generate_drs_pusch (OTA synchronization of RRUs)
#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h"
-int* sync_corr_ue0 = NULL;
-int* sync_corr_ue1 = NULL;
-int* sync_corr_ue2 = NULL;
-int sync_tmp[2048*4] __attribute__((aligned(32)));
-short syncF_tmp[2048*2] __attribute__((aligned(32)));
+static struct complex16 *primary_synch0_time __attribute__((aligned(32)));
+static struct complex16 *primary_synch1_time __attribute__((aligned(32)));
+static struct complex16 *primary_synch2_time __attribute__((aligned(32)));
+static void doIdft(int size, short *in, short *out) {
+ switch (size) {
+ case 6:
+ idft(IDFT_128,in,out,1);
+ break;
-int lte_sync_time_init(LTE_DL_FRAME_PARMS *frame_parms ) // LTE_UE_COMMON *common_vars
-{
- int i,k;
+ case 25:
+ idft(IDFT_512,in,out,1);
+ break;
- sync_corr_ue0 = (int *)malloc16(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(int)*frame_parms->samples_per_tti);
- sync_corr_ue1 = (int *)malloc16(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(int)*frame_parms->samples_per_tti);
- sync_corr_ue2 = (int *)malloc16(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(int)*frame_parms->samples_per_tti);
+ case 50:
+ idft(IDFT_1024,in,out,1);
+ break;
+
+ case 75:
+ idft(IDFT_1536,in,out,1);
+ break;
- if (sync_corr_ue0) {
-#ifdef DEBUG_PHY
- LOG_D(PHY,"[openair][LTE_PHY][SYNC] sync_corr_ue allocated at %p\n", sync_corr_ue0);
-#endif
- //common_vars->sync_corr = sync_corr;
- } else {
- LOG_E(PHY,"[openair][LTE_PHY][SYNC] sync_corr_ue0 not allocated\n");
- return(-1);
+ case 100:
+ idft(IDFT_2048,in,out,1);
+ break;
+
+ default:
+ LOG_E(PHY,"Unsupported N_RB_DL %d\n",size);
+ abort();
+ break;
+ }
}
- if (sync_corr_ue1) {
-#ifdef DEBUG_PHY
- LOG_D(PHY,"[openair][LTE_PHY][SYNC] sync_corr_ue allocated at %p\n", sync_corr_ue1);
-#endif
- //common_vars->sync_corr = sync_corr;
- } else {
- LOG_E(PHY,"[openair][LTE_PHY][SYNC] sync_corr_ue1 not allocated\n");
- return(-1);
+static void copyPrimary( struct complex16 *out, struct complex16 *in, int ofdmSize) {
+ int k=ofdmSize-36;
+
+ for (int i=0; i<72; i++) {
+ out[k].r = in[i].r>>1; //we need to shift input to avoid overflow in fft
+ out[k].i = in[i].i>>1;
+ k++;
+
+ if (k >= ofdmSize) {
+ k++; // skip DC carrier
+ k-=ofdmSize;
+ }
+ }
}
- if (sync_corr_ue2) {
-#ifdef DEBUG_PHY
- LOG_D(PHY,"[openair][LTE_PHY][SYNC] sync_corr_ue allocated at %p\n", sync_corr_ue2);
-#endif
- //common_vars->sync_corr = sync_corr;
- } else {
- LOG_E(PHY,"[openair][LTE_PHY][SYNC] sync_corr_ue2 not allocated\n");
- return(-1);
- }
-
- // primary_synch0_time = (int *)malloc16((frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*sizeof(int));
- primary_synch0_time = (int16_t *)malloc16((frame_parms->ofdm_symbol_size)*sizeof(int16_t)*2);
-
- if (primary_synch0_time) {
- // bzero(primary_synch0_time,(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*sizeof(int));
- bzero(primary_synch0_time,(frame_parms->ofdm_symbol_size)*sizeof(int16_t)*2);
-#ifdef DEBUG_PHY
- LOG_D(PHY,"[openair][LTE_PHY][SYNC] primary_synch0_time allocated at %p\n", primary_synch0_time);
-#endif
- } else {
- LOG_E(PHY,"[openair][LTE_PHY][SYNC] primary_synch0_time not allocated\n");
- return(-1);
- }
-
- // primary_synch1_time = (int *)malloc16((frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*sizeof(int));
- primary_synch1_time = (int16_t *)malloc16((frame_parms->ofdm_symbol_size)*sizeof(int16_t)*2);
-
- if (primary_synch1_time) {
- // bzero(primary_synch1_time,(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*sizeof(int));
- bzero(primary_synch1_time,(frame_parms->ofdm_symbol_size)*sizeof(int16_t)*2);
-#ifdef DEBUG_PHY
- LOG_D(PHY,"[openair][LTE_PHY][SYNC] primary_synch1_time allocated at %p\n", primary_synch1_time);
-#endif
- } else {
- LOG_E(PHY,"[openair][LTE_PHY][SYNC] primary_synch1_time not allocated\n");
- return(-1);
- }
-
- // primary_synch2_time = (int *)malloc16((frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*sizeof(int));
- primary_synch2_time = (int16_t *)malloc16((frame_parms->ofdm_symbol_size)*sizeof(int16_t)*2);
-
- if (primary_synch2_time) {
- // bzero(primary_synch2_time,(frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples)*sizeof(int));
- bzero(primary_synch2_time,(frame_parms->ofdm_symbol_size)*sizeof(int16_t)*2);
-#ifdef DEBUG_PHY
- LOG_D(PHY,"[openair][LTE_PHY][SYNC] primary_synch2_time allocated at %p\n", primary_synch2_time);
-#endif
- } else {
- LOG_E(PHY,"[openair][LTE_PHY][SYNC] primary_synch2_time not allocated\n");
- return(-1);
- }
-
-
+int lte_sync_time_init(LTE_DL_FRAME_PARMS *frame_parms ) { // LTE_UE_COMMON *common_vars
+ struct complex16 syncF_tmp[2048]__attribute__((aligned(32)))= {{0}};
+ int sz=frame_parms->ofdm_symbol_size*sizeof(*primary_synch0_time);
+ AssertFatal( NULL != (primary_synch0_time = (struct complex16 *)malloc16(sz)),"");
+ bzero(primary_synch0_time,sz);
+ AssertFatal( NULL != (primary_synch1_time = (struct complex16 *)malloc16(sz)),"");
+ bzero(primary_synch1_time,sz);
+ AssertFatal( NULL != (primary_synch2_time = (struct complex16 *)malloc16(sz)),"");
+ bzero(primary_synch2_time,sz);
// generate oversampled sync_time sequences
- k=frame_parms->ofdm_symbol_size-36;
-
- for (i=0; i<72; i++) {
- syncF_tmp[2*k] = primary_synch0[2*i]>>2; //we need to shift input to avoid overflow in fft
- syncF_tmp[2*k+1] = primary_synch0[2*i+1]>>2;
- k++;
-
- if (k >= frame_parms->ofdm_symbol_size) {
- k++; // skip DC carrier
- k-=frame_parms->ofdm_symbol_size;
- }
- }
-
- switch (frame_parms->N_RB_DL) {
- case 6:
- idft(IDFT_128,(short*)syncF_tmp, /// complex input
- (short*)sync_tmp, /// complex output
- 1);
- break;
- case 25:
- idft(IDFT_512,(short*)syncF_tmp, /// complex input
- (short*)sync_tmp, /// complex output
- 1);
- break;
- case 50:
- idft(IDFT_1024,(short*)syncF_tmp, /// complex input
- (short*)sync_tmp, /// complex output
- 1);
- break;
-
- case 75:
- idft(IDFT_1536,(short*)syncF_tmp, /// complex input
- (short*)sync_tmp,
- 1); /// complex output
- break;
- case 100:
- idft(IDFT_2048,(short*)syncF_tmp, /// complex input
- (short*)sync_tmp, /// complex output
- 1);
- break;
- default:
- LOG_E(PHY,"Unsupported N_RB_DL %d\n",frame_parms->N_RB_DL);
- break;
- }
-
- for (i=0; iofdm_symbol_size; i++)
- ((int32_t*)primary_synch0_time)[i] = sync_tmp[i];
-
- k=frame_parms->ofdm_symbol_size-36;
-
- for (i=0; i<72; i++) {
- syncF_tmp[2*k] = primary_synch1[2*i]>>2; //we need to shift input to avoid overflow in fft
- syncF_tmp[2*k+1] = primary_synch1[2*i+1]>>2;
- k++;
-
- if (k >= frame_parms->ofdm_symbol_size) {
- k++; // skip DC carrier
- k-=frame_parms->ofdm_symbol_size;
- }
- }
-
- switch (frame_parms->N_RB_DL) {
- case 6:
- idft(IDFT_128,(short*)syncF_tmp, /// complex input
- (short*)sync_tmp, /// complex output
- 1);
- break;
- case 25:
- idft(IDFT_512,(short*)syncF_tmp, /// complex input
- (short*)sync_tmp, /// complex output
- 1);
- break;
- case 50:
- idft(IDFT_1024,(short*)syncF_tmp, /// complex input
- (short*)sync_tmp, /// complex output
- 1);
- break;
-
- case 75:
- idft(IDFT_1536,(short*)syncF_tmp, /// complex input
- (short*)sync_tmp, /// complex output
- 1);
- break;
- case 100:
- idft(IDFT_2048,(short*)syncF_tmp, /// complex input
- (short*)sync_tmp, /// complex output
- 1);
- break;
- default:
- LOG_E(PHY,"Unsupported N_RB_DL %d\n",frame_parms->N_RB_DL);
- break;
- }
-
- for (i=0; iofdm_symbol_size; i++)
- ((int32_t*)primary_synch1_time)[i] = sync_tmp[i];
-
- k=frame_parms->ofdm_symbol_size-36;
-
- for (i=0; i<72; i++) {
- syncF_tmp[2*k] = primary_synch2[2*i]>>2; //we need to shift input to avoid overflow in fft
- syncF_tmp[2*k+1] = primary_synch2[2*i+1]>>2;
- k++;
-
- if (k >= frame_parms->ofdm_symbol_size) {
- k++; // skip DC carrier
- k-=frame_parms->ofdm_symbol_size;
- }
- }
-
- switch (frame_parms->N_RB_DL) {
- case 6:
- idft(IDFT_128,(short*)syncF_tmp, /// complex input
- (short*)sync_tmp, /// complex output
- 1);
- break;
- case 25:
- idft(IDFT_512,(short*)syncF_tmp, /// complex input
- (short*)sync_tmp, /// complex output
- 1);
- break;
- case 50:
- idft(IDFT_1024,(short*)syncF_tmp, /// complex input
- (short*)sync_tmp, /// complex output
- 1);
- break;
-
- case 75:
- idft(IDFT_1536,(short*)syncF_tmp, /// complex input
- (short*)sync_tmp, /// complex output
- 1);
- break;
- case 100:
- idft(IDFT_2048,(short*)syncF_tmp, /// complex input
- (short*)sync_tmp, /// complex output
- 1);
- break;
- default:
- LOG_E(PHY,"Unsupported N_RB_DL %d\n",frame_parms->N_RB_DL);
- break;
- }
-
- for (i=0; iofdm_symbol_size; i++)
- ((int32_t*)primary_synch2_time)[i] = sync_tmp[i];
-
+ copyPrimary( syncF_tmp, (struct complex16 *) primary_synch0, frame_parms->ofdm_symbol_size);
+ doIdft(frame_parms->N_RB_DL, (short *)syncF_tmp,(short *)primary_synch0_time);
+ copyPrimary( syncF_tmp, (struct complex16 *) primary_synch1, frame_parms->ofdm_symbol_size);
+ doIdft(frame_parms->N_RB_DL, (short *)syncF_tmp,(short *)primary_synch1_time);
+ copyPrimary( syncF_tmp, (struct complex16 *) primary_synch2, frame_parms->ofdm_symbol_size);
+ doIdft(frame_parms->N_RB_DL, (short *)syncF_tmp,(short *)primary_synch2_time);
if ( LOG_DUMPFLAG(DEBUG_LTEESTIM)){
LOG_M("primary_sync0.m","psync0",primary_synch0_time,frame_parms->ofdm_symbol_size,1,1);
LOG_M("primary_sync1.m","psync1",primary_synch1_time,frame_parms->ofdm_symbol_size,1,1);
LOG_M("primary_sync2.m","psync2",primary_synch2_time,frame_parms->ofdm_symbol_size,1,1);
}
+
return (1);
}
-void lte_sync_time_free(void)
-{
- if (sync_corr_ue0) {
- LOG_D(PHY,"Freeing sync_corr_ue (%p)...\n",sync_corr_ue0);
- free(sync_corr_ue0);
- }
-
- if (sync_corr_ue1) {
- LOG_D(PHY,"Freeing sync_corr_ue (%p)...\n",sync_corr_ue1);
- free(sync_corr_ue1);
- }
-
- if (sync_corr_ue2) {
- LOG_D(PHY,"Freeing sync_corr_ue (%p)...\n",sync_corr_ue2);
- free(sync_corr_ue2);
- }
-
+void lte_sync_time_free(void) {
if (primary_synch0_time) {
LOG_D(PHY,"Freeing primary_sync0_time ...\n");
free(primary_synch0_time);
@@ -312,126 +128,81 @@ void lte_sync_time_free(void)
free(primary_synch2_time);
}
- sync_corr_ue0 = NULL;
- sync_corr_ue1 = NULL;
- sync_corr_ue2 = NULL;
primary_synch0_time = NULL;
primary_synch1_time = NULL;
primary_synch2_time = NULL;
}
-static inline int abs32(int x)
-{
+static inline int abs32(int x) {
return (((int)((short*)&x)[0])*((int)((short*)&x)[0]) + ((int)((short*)&x)[1])*((int)((short*)&x)[1]));
}
+static inline double absF(struct complexd x) {
+ return x.r*x.r+x.i*x.i;
+}
+
+#define complexNull(c) bzero((void*) &(c), sizeof(c))
#define SHIFT 17
int lte_sync_time(int **rxdata, ///rx data in time domain
LTE_DL_FRAME_PARMS *frame_parms,
- int *eNB_id)
-{
+ int *eNB_id) {
// perform a time domain correlation using the oversampled sync sequence
-
unsigned int n, ar, s, peak_pos, peak_val, sync_source;
int result,result2;
- int sync_out[3] = {0,0,0},sync_out2[3] = {0,0,0};
- int tmp[3] = {0,0,0};
+ struct complexd sync_out[3]= {{0}}, sync_out2[3]= {{0}};
int length = LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti>>1;
-
- //LOG_D(PHY,"[SYNC TIME] Calling sync_time.\n");
- AssertFatal(sync_corr_ue0 != NULL,
- "sync_corr_ue0 not yet allocated! Exiting.\n");
- AssertFatal(sync_corr_ue1 != NULL,
- "sync_corr_ue0 not yet allocated! Exiting.\n");
- AssertFatal(sync_corr_ue2 != NULL,
- "sync_corr_ue0 not yet allocated! Exiting.\n");
-
peak_val = 0;
peak_pos = 0;
sync_source = 0;
-
for (n=0; nofdm_symbol_size-frame_parms->nb_prefix_samples)) {
if (n<(length-frame_parms->ofdm_symbol_size)) {
-
//calculate dot product of primary_synch0_time and rxdata[ar][n] (ar=0..nb_ant_rx) and store the sum in temp[n];
for (ar=0; arnb_antennas_rx; ar++) {
-
- result = dot_product((short*)primary_synch0_time, (short*) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, SHIFT);
- result2 = dot_product((short*)primary_synch0_time, (short*) &(rxdata[ar][n+length]), frame_parms->ofdm_symbol_size, SHIFT);
-
- ((short*)sync_corr_ue0)[2*n] += ((short*) &result)[0];
- ((short*)sync_corr_ue0)[2*n+1] += ((short*) &result)[1];
- ((short*)sync_corr_ue0)[2*(length+n)] += ((short*) &result2)[0];
- ((short*)sync_corr_ue0)[(2*(length+n))+1] += ((short*) &result2)[1];
- ((short*)sync_out)[0] += ((short*) &result)[0];
- ((short*)sync_out)[1] += ((short*) &result)[1];
- ((short*)sync_out2)[0] += ((short*) &result2)[0];
- ((short*)sync_out2)[1] += ((short*) &result2)[1];
+ result = dot_product((short *)primary_synch0_time, (short *) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, SHIFT);
+ result2 = dot_product((short *)primary_synch0_time, (short *) &(rxdata[ar][n+length]), frame_parms->ofdm_symbol_size, SHIFT);
+ sync_out[0].r += ((short *) &result)[0];
+ sync_out[0].i += ((short *) &result)[1];
+ sync_out2[0].r += ((short *) &result2)[0];
+ sync_out2[0].i += ((short *) &result2)[1];
}
for (ar=0; arnb_antennas_rx; ar++) {
- result = dot_product((short*)primary_synch1_time, (short*) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, SHIFT);
- result2 = dot_product((short*)primary_synch1_time, (short*) &(rxdata[ar][n+length]), frame_parms->ofdm_symbol_size, SHIFT);
- ((short*)sync_corr_ue1)[2*n] += ((short*) &result)[0];
- ((short*)sync_corr_ue1)[2*n+1] += ((short*) &result)[1];
- ((short*)sync_corr_ue1)[2*(length+n)] += ((short*) &result2)[0];
- ((short*)sync_corr_ue1)[(2*(length+n))+1] += ((short*) &result2)[1];
-
- ((short*)sync_out)[2] += ((short*) &result)[0];
- ((short*)sync_out)[3] += ((short*) &result)[1];
- ((short*)sync_out2)[2] += ((short*) &result2)[0];
- ((short*)sync_out2)[3] += ((short*) &result2)[1];
+ result = dot_product((short *)primary_synch1_time, (short *) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, SHIFT);
+ result2 = dot_product((short *)primary_synch1_time, (short *) &(rxdata[ar][n+length]), frame_parms->ofdm_symbol_size, SHIFT);
+ sync_out[1].r += ((short *) &result)[0];
+ sync_out[1].i += ((short *) &result)[1];
+ sync_out2[1].r += ((short *) &result2)[0];
+ sync_out2[1].i += ((short *) &result2)[1];
}
for (ar=0; arnb_antennas_rx; ar++) {
-
- result = dot_product((short*)primary_synch2_time, (short*) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, SHIFT);
- result2 = dot_product((short*)primary_synch2_time, (short*) &(rxdata[ar][n+length]), frame_parms->ofdm_symbol_size, SHIFT);
- ((short*)sync_corr_ue2)[2*n] += ((short*) &result)[0];
- ((short*)sync_corr_ue2)[2*n+1] += ((short*) &result)[1];
- ((short*)sync_corr_ue2)[2*(length+n)] += ((short*) &result2)[0];
- ((short*)sync_corr_ue2)[(2*(length+n))+1] += ((short*) &result2)[1];
- ((short*)sync_out)[4] += ((short*) &result)[0];
- ((short*)sync_out)[5] += ((short*) &result)[1];
- ((short*)sync_out2)[4] += ((short*) &result2)[0];
- ((short*)sync_out2)[5] += ((short*) &result2)[1];
+ result = dot_product((short *)primary_synch2_time, (short *) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, SHIFT);
+ result2 = dot_product((short *)primary_synch2_time, (short *) &(rxdata[ar][n+length]), frame_parms->ofdm_symbol_size, SHIFT);
+ sync_out[2].r += ((short *) &result)[0];
+ sync_out[2].i += ((short *) &result)[1];
+ sync_out2[2].r += ((short *) &result2)[0];
+ sync_out2[2].i += ((short *) &result2)[1];
}
-
}
// calculate the absolute value of sync_corr[n]
- sync_corr_ue0[n] = abs32(sync_corr_ue0[n]);
- sync_corr_ue0[n+length] = abs32(sync_corr_ue0[n+length]);
- sync_corr_ue1[n] = abs32(sync_corr_ue1[n]);
- sync_corr_ue1[n+length] = abs32(sync_corr_ue1[n+length]);
- sync_corr_ue2[n] = abs32(sync_corr_ue2[n]);
- sync_corr_ue2[n+length] = abs32(sync_corr_ue2[n+length]);
-
for (s=0; s<3; s++) {
- tmp[s] = (abs32(sync_out[s])>>1) + (abs32(sync_out2[s])>>1);
+ double tmp = absF(sync_out[s]) + absF(sync_out2[s]);
- if (tmp[s]>peak_val) {
- peak_val = tmp[s];
+ if (tmp>peak_val) {
+ peak_val = tmp;
peak_pos = n;
sync_source = s;
/*
@@ -443,42 +214,22 @@ int lte_sync_time(int **rxdata, ///rx data in time domain
}
*eNB_id = sync_source;
-
- LOG_I(PHY,"[UE] lte_sync_time: Sync source = %d, Peak found at pos %d, val = %d (%d dB)\n",sync_source,peak_pos,peak_val,dB_fixed(peak_val)/2);
-
-
- if ( LOG_DUMPFLAG(DEBUG_LTEESTIM)){
- static int debug_cnt;
- if (debug_cnt == 0) {
- LOG_M("sync_corr0_ue.m","synccorr0",sync_corr_ue0,2*length,1,2);
- LOG_M("sync_corr1_ue.m","synccorr1",sync_corr_ue1,2*length,1,2);
- LOG_M("sync_corr2_ue.m","synccorr2",sync_corr_ue2,2*length,1,2);
- LOG_M("rxdata0.m","rxd0",rxdata[0],length<<1,1,1);
- // exit(-1);
- } else {
- debug_cnt++;
- }
-}
+ LOG_I(PHY,"[UE] lte_sync_time: Sync source = %d, Peak found at pos %d, val = %d (%d dB)\n",sync_source,peak_pos,peak_val/2,dB_fixed(peak_val/2)/2);
return(peak_pos);
}
-int ru_sync_time_init(RU_t *ru) // LTE_UE_COMMON *common_vars
-{
+int ru_sync_time_init(RU_t *ru) { // LTE_UE_COMMON *common_vars
/*
int16_t dmrs[2048];
int16_t *dmrsp[2] = {dmrs,NULL};
*/
-
int32_t dmrs[ru->frame_parms->ofdm_symbol_size*14] __attribute__((aligned(32)));
//int32_t *dmrsp[2] = {&dmrs[(3-ru->frame_parms->Ncp)*ru->frame_parms->ofdm_symbol_size],NULL};
int32_t *dmrsp[2] = {&dmrs[0],NULL};
-
generate_ul_ref_sigs();
-
- ru->dmrssync = (int16_t*)malloc16_clear(ru->frame_parms->ofdm_symbol_size*2*sizeof(int16_t));
- ru->dmrs_corr = (uint64_t*)malloc16_clear(ru->frame_parms->samples_per_tti*10*sizeof(uint64_t));
-
+ ru->dmrssync = (int16_t *)malloc16_clear(ru->frame_parms->ofdm_symbol_size*2*sizeof(int16_t));
+ ru->dmrs_corr = (uint64_t *)malloc16_clear(ru->frame_parms->samples_per_tti*10*sizeof(uint64_t));
generate_drs_pusch(NULL,
NULL,
ru->frame_parms,
@@ -491,35 +242,39 @@ int ru_sync_time_init(RU_t *ru) // LTE_UE_COMMON *common_vars
0);
switch (ru->frame_parms->N_RB_DL) {
- case 6:
- idft(IDFT_128,(int16_t*)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]),
- ru->dmrssync, /// complex output
- 1);
- break;
- case 25:
- idft(IDFT_512,(int16_t*)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]),
- ru->dmrssync, /// complex output
- 1);
- break;
- case 50:
- idft(IDFT_1024,(int16_t*)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]),
- ru->dmrssync, /// complex output
- 1);
- break;
-
- case 75:
- idft(IDFT_1536,(int16_t*)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]),
- ru->dmrssync,
- 1); /// complex output
- break;
- case 100:
- idft(IDFT_2048,(int16_t*)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]),
- ru->dmrssync, /// complex output
- 1);
- break;
- default:
- AssertFatal(1==0,"Unsupported N_RB_DL %d\n",ru->frame_parms->N_RB_DL);
- break;
+ case 6:
+ idft(IDFT_128,(int16_t *)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]),
+ ru->dmrssync, /// complex output
+ 1);
+ break;
+
+ case 25:
+ idft(IDFT_512,(int16_t *)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]),
+ ru->dmrssync, /// complex output
+ 1);
+ break;
+
+ case 50:
+ idft(IDFT_1024,(int16_t *)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]),
+ ru->dmrssync, /// complex output
+ 1);
+ break;
+
+ case 75:
+ idft(IDFT_1536,(int16_t *)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]),
+ ru->dmrssync,
+ 1); /// complex output
+ break;
+
+ case 100:
+ idft(IDFT_2048,(int16_t *)(&dmrsp[0][3*ru->frame_parms->ofdm_symbol_size]),
+ ru->dmrssync, /// complex output
+ 1);
+ break;
+
+ default:
+ AssertFatal(1==0,"Unsupported N_RB_DL %d\n",ru->frame_parms->N_RB_DL);
+ break;
}
return(0);
@@ -527,10 +282,11 @@ int ru_sync_time_init(RU_t *ru) // LTE_UE_COMMON *common_vars
void ru_sync_time_free(RU_t *ru) {
-
AssertFatal(ru->dmrssync!=NULL,"ru->dmrssync is NULL\n");
free(ru->dmrssync);
- if (ru->dmrs_corr) free(ru->dmrs_corr);
+
+ if (ru->dmrs_corr)
+ free(ru->dmrs_corr);
}
//#define DEBUG_PHY
@@ -539,10 +295,8 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain
LTE_DL_FRAME_PARMS *frame_parms,
uint32_t length,
uint32_t *peak_val_out,
- uint32_t *sync_corr_eNB)
-{
+ uint32_t *sync_corr_eNB) {
// perform a time domain correlation using the oversampled sync sequence
-
unsigned int n, ar, peak_val, peak_pos;
uint64_t mean_val;
int result;
@@ -556,21 +310,21 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain
}
switch (eNB_id) {
- case 0:
- primary_synch_time = (short*)primary_synch0_time;
- break;
+ case 0:
+ primary_synch_time = (short *)primary_synch0_time;
+ break;
- case 1:
- primary_synch_time = (short*)primary_synch1_time;
- break;
+ case 1:
+ primary_synch_time = (short *)primary_synch1_time;
+ break;
- case 2:
- primary_synch_time = (short*)primary_synch2_time;
- break;
+ case 2:
+ primary_synch_time = (short *)primary_synch2_time;
+ break;
- default:
- LOG_E(PHY,"[SYNC TIME] Illegal eNB_id!\n");
- return (-1);
+ default:
+ LOG_E(PHY,"[SYNC TIME] Illegal eNB_id!\n");
+ return (-1);
}
peak_val = 0;
@@ -578,21 +332,16 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain
mean_val = 0;
for (n=0; nofdm_symbol_size-frame_parms->nb_prefix_samples)) {
-
//calculate dot product of primary_synch0_time and rxdata[ar][n] (ar=0..nb_ant_rx) and store the sum in temp[n];
for (ar=0; arnb_antennas_rx; ar++) {
-
- result = dot_product((short*)primary_synch_time, (short*) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, SHIFT);
+ result = dot_product((short *)primary_synch_time, (short *) &(rxdata[ar][n]), frame_parms->ofdm_symbol_size, SHIFT);
//((short*)sync_corr)[2*n] += ((short*) &result)[0];
//((short*)sync_corr)[2*n+1] += ((short*) &result)[1];
sync_corr_eNB[n] += abs32(result);
-
}
-
}
/*
@@ -610,7 +359,6 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain
}
mean_val/=length;
-
*peak_val_out = peak_val;
if (peak_val <= (40*(uint32_t)mean_val)) {
@@ -620,88 +368,91 @@ int lte_sync_time_eNB(int32_t **rxdata, ///rx data in time domain
LOG_I(PHY,"[SYNC TIME] Peak found at pos %u, val = %u, mean_val = %"PRIu64"\n",peak_pos,peak_val,mean_val);
return(peak_pos);
}
-
}
-static inline int64_t abs64(int64_t x)
-{
- return (((int64_t)((int32_t*)&x)[0])*((int64_t)((int32_t*)&x)[0]) + ((int64_t)
-((int32_t*)&x)[1])*((int64_t)((int32_t*)&x)[1]));
+static inline int64_t abs64(int64_t x) {
+ return (((int64_t)((int32_t *)&x)[0])*((int64_t)((int32_t *)&x)[0]) + ((int64_t)
+ ((int32_t *)&x)[1])*((int64_t)((int32_t *)&x)[1]));
}
int ru_sync_time(RU_t *ru,
int64_t *lev,
- int64_t *avg)
-{
+ int64_t *avg) {
LTE_DL_FRAME_PARMS *frame_parms = ru->frame_parms;
RU_CALIBRATION *calibration = &ru->calibration;
-
// perform a time domain correlation using the oversampled sync sequence
-
int length = LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti;
-
// circular copy of beginning to end of rxdata buffer. Note: buffer should be big enough upon calling this function
- for (int ar=0;arnb_rx;ar++) memcpy((void*)&ru->common.rxdata[ar][2*length],
- (void*)&ru->common.rxdata[ar][0],
- frame_parms->ofdm_symbol_size);
-
+ for (int ar=0; arnb_rx; ar++)
+ memcpy((void *)&ru->common.rxdata[ar][2*length],
+ (void *)&ru->common.rxdata[ar][0],
+ frame_parms->ofdm_symbol_size);
+
int32_t maxlev0=0;
int maxpos0=0;
int64_t avg0=0;
int64_t result;
int64_t dmrs_corr;
-
int maxval=0;
- for (int i=0;i<2*(frame_parms->ofdm_symbol_size);i++) {
+
+ for (int i=0; i<2*(frame_parms->ofdm_symbol_size); i++) {
maxval = max(maxval,ru->dmrssync[i]);
maxval = max(maxval,-ru->dmrssync[i]);
}
if (ru->state == RU_CHECK_SYNC) {
- for (int i=0;i<2*(frame_parms->ofdm_symbol_size);i++) {
- maxval = max(maxval,calibration->drs_ch_estimates_time[0][i]);
- maxval = max(maxval,-calibration->drs_ch_estimates_time[0][i]);
- }
+ for (int i=0; i<2*(frame_parms->ofdm_symbol_size); i++) {
+ maxval = max(maxval,calibration->drs_ch_estimates_time[0][i]);
+ maxval = max(maxval,-calibration->drs_ch_estimates_time[0][i]);
+ }
}
int shift = log2_approx(maxval);
for (int n=0; nnb_rx; ar++) {
-
result = dot_product64(ru->dmrssync,
- (int16_t*) &ru->common.rxdata[ar][n],
- frame_parms->ofdm_symbol_size,
- shift);
-
- if (ru->state == RU_CHECK_SYNC) {
- result = dot_product64((int16_t*) &calibration->drs_ch_estimates_time[ar],
- (int16_t*) &ru->common.rxdata[ar][n],
+ (int16_t *) &ru->common.rxdata[ar][n],
frame_parms->ofdm_symbol_size,
shift);
+
+ if (ru->state == RU_CHECK_SYNC) {
+ result = dot_product64((int16_t *) &calibration->drs_ch_estimates_time[ar],
+ (int16_t *) &ru->common.rxdata[ar][n],
+ frame_parms->ofdm_symbol_size,
+ shift);
}
+
dmrs_corr += abs64(result);
}
- if (ru->dmrs_corr != NULL) ru->dmrs_corr[n] = dmrs_corr;
+
+ if (ru->dmrs_corr != NULL)
+ ru->dmrs_corr[n] = dmrs_corr;
// tmpi holds ++...+
+ if (dmrs_corr>maxlev0) {
+ maxlev0 = dmrs_corr;
+ maxpos0 = n;
+ }
- if (dmrs_corr>maxlev0) { maxlev0 = dmrs_corr; maxpos0 = n; }
avg0 += dmrs_corr;
}
- avg0/=(length/4);
+ avg0/=(length/4);
int dmrsoffset = frame_parms->samples_per_tti + (3*frame_parms->ofdm_symbol_size)+(3*frame_parms->nb_prefix_samples) + frame_parms->nb_prefix_samples0;
-
- if ((int64_t)maxlev0 > (10*avg0)) {*lev = maxlev0; *avg=avg0; return((length+maxpos0-dmrsoffset)%length);}
+
+ if ((int64_t)maxlev0 > (10*avg0)) {
+ *lev = maxlev0;
+ *avg=avg0;
+ return((length+maxpos0-dmrsoffset)%length);
+ }
return(-1);
}
diff --git a/openair1/PHY/LTE_REFSIG/lte_gold.c b/openair1/PHY/LTE_REFSIG/lte_gold.c
index c5e48d8364..596760541b 100644
--- a/openair1/PHY/LTE_REFSIG/lte_gold.c
+++ b/openair1/PHY/LTE_REFSIG/lte_gold.c
@@ -56,7 +56,7 @@ void lte_gold(LTE_DL_FRAME_PARMS *frame_parms,uint32_t lte_gold_table[20][2][14]
(((1+(Nid_cell<<1))*(1 + (((frame_parms->Ncp==0)?4:3)*l) + (7*(1+ns))))<<10); //cinit
//x2 = frame_parms->Ncp + (Nid_cell<<1) + (1+(Nid_cell<<1))*(1 + (3*l) + (7*(1+ns))); //cinit
//n = 0
- x1 = 1+ (1<<31);
+ x1 = 1+ (1U<<31);
x2=x2 ^ ((x2 ^ (x2>>1) ^ (x2>>2) ^ (x2>>3))<<31);
// skip first 50 double words (1600 bits)
@@ -103,7 +103,7 @@ void lte_gold_ue_spec(uint32_t lte_gold_uespec_table[2][20][2][21],uint16_t Nid_
//x2 = frame_parms->Ncp + (Nid_cell<<1) + (1+(Nid_cell<<1))*(1 + (3*l) + (7*(1+ns))); //cinit
//n = 0
// printf("cinit (ns %d, l %d) => %d\n",ns,l,x2);
- x1 = 1+ (1<<31);
+ x1 = 1+ (1U<<31);
x2=x2 ^ ((x2 ^ (x2>>1) ^ (x2>>2) ^ (x2>>3))<<31);
// skip first 50 double words (1600 bits)
@@ -143,7 +143,7 @@ void lte_gold_ue_spec_port5(uint32_t lte_gold_uespec_port5_table[20][38],uint16_
//x2 = frame_parms->Ncp + (Nid_cell<<1) + (1+(Nid_cell<<1))*(1 + (3*l) + (7*(1+ns))); //cinit
//n = 0
//printf("cinit (ns %d, l %d) => %d\n",ns,l,x2);
- x1 = 1+ (1<<31);
+ x1 = 1+ (1U<<31);
x2=x2 ^ ((x2 ^ (x2>>1) ^ (x2>>2) ^ (x2>>3))<<31);
//skip first 50 double words (1600 bits)
diff --git a/openair1/PHY/LTE_REFSIG/lte_gold_mbsfn.c b/openair1/PHY/LTE_REFSIG/lte_gold_mbsfn.c
index b057f6a403..78f0fd93fe 100644
--- a/openair1/PHY/LTE_REFSIG/lte_gold_mbsfn.c
+++ b/openair1/PHY/LTE_REFSIG/lte_gold_mbsfn.c
@@ -59,7 +59,7 @@ void lte_gold_mbsfn(LTE_DL_FRAME_PARMS *frame_parms,uint32_t lte_gold_mbsfn_tabl
//n = 0
// printf("cinit (sfn %d, l %d) => %d\n",sfn,l,x2);
// Initializing the Sequence
- x1 = 1+ (1<<31);
+ x1 = 1+ (1U<<31);
x2=x2 ^ ((x2 ^ (x2>>1) ^ (x2>>2) ^ (x2>>3))<<31);
// skip first 50 double words (1600 bits)
// printf("n=0 : x1 %x, x2 %x\n",x1,x2);
@@ -90,7 +90,7 @@ void lte_gold_mbsfn_khz_1dot25(LTE_DL_FRAME_PARMS *frame_parms,uint32_t lte_gold
for (sfn=0; sfn<10; sfn++) {
x2 = (Nid_mbsfn) + (((1+(Nid_mbsfn<<1))*(1 + (7*(1+sfn))))<<9); //cinit
- x1 = 1+ (1<<31);
+ x1 = 1+ (1U<<31);
x2=x2 ^ ((x2 ^ (x2>>1) ^ (x2>>2) ^ (x2>>3))<<31);
for (n=1; n<50; n++) {
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c b/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c
index d48164e07d..b03f59fb78 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c
@@ -121,7 +121,7 @@ void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms,
for (n=0; n<(1+(G>>5)); n++) {
#ifdef DEBUG_SCRAMBLING
- for (int k=0; k<32; k++) printf("scrambling %d : %d xor %d = %d\n",k+(n<<5),e[k],(s>>k)&1,e[k]^((s>>k)&1));
+ for (int k=0; k<32; k++) printf("scrambling %d : %x xor %x = %d\n",k+(n<<5),e[k],(s>>k)&1,e[k]^((s>>k)&1));
#endif
e[0] = (e[0]) ^ (s&1);
diff --git a/openair1/PHY/LTE_TRANSPORT/lte_gold_generic.c b/openair1/PHY/LTE_TRANSPORT/lte_gold_generic.c
index b249052cbf..a23f8db4f2 100644
--- a/openair1/PHY/LTE_TRANSPORT/lte_gold_generic.c
+++ b/openair1/PHY/LTE_TRANSPORT/lte_gold_generic.c
@@ -41,7 +41,7 @@ extern inline uint32_t lte_gold_generic(uint32_t *x1, uint32_t *x2, uint8_t res
{
// Init value for x1: x1(0) = 1, x1(n) = 0, n=1,2,...,30
// x1(31) = [x1(3) + x1(0)]mod2 = 1
- *x1 = 1 + (1<<31);
+ *x1 = 1 + (1U<<31);
// Init value for x2: cinit = sum_{i=0}^30 x2*2^i
// x2(31) = [x2(3) + x2(2) + x2(1) + x2(0)]mod2
// = (*x2>>3) ^ (*x2>>2) + (*x2>>1) + *x2
diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
index 92fe777201..476d7028b1 100644
--- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
+++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
@@ -374,7 +374,7 @@ static inline unsigned int lte_gold_unscram(unsigned int *x1, unsigned int *x2,
int n;
if (reset) {
- *x1 = 1+ (1<<31);
+ *x1 = 1+ (1U<<31);
*x2=*x2 ^ ((*x2 ^ (*x2>>1) ^ (*x2>>2) ^ (*x2>>3))<<31);
// skip first 50 double words (1600 bits)
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/srs_modulation.c b/openair1/PHY/LTE_UE_TRANSPORT/srs_modulation.c
index e6960273c7..9c0edb467c 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/srs_modulation.c
+++ b/openair1/PHY/LTE_UE_TRANSPORT/srs_modulation.c
@@ -170,6 +170,7 @@ int32_t generate_srs(LTE_DL_FRAME_PARMS *frame_parms,
Msc_RS = msrsb * 6;
k0 = ( ( (int16_t)(frame_parms->N_RB_UL>>1) - (int16_t)(msrs0>>1) ) * 12 ) + kTC;
+ AssertFatal(msrsb,"divide by 0");
nb = (4*n_RRC/msrsb)%Nb;
for (b=0; b<=Bsrs; b++) {
diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
index 967868f803..625519b953 100644
--- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
+++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
@@ -61,6 +61,8 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
debug_ch_est = fopen("debug_ch_est.txt","w");
#endif
+ //uint16_t Nid_cell = (eNB_offset == 0) ? gNB->frame_parms.Nid_cell : gNB->measurements.adj_cell_id[eNB_offset-1];
+
uint8_t nushift;
int **ul_ch_estimates = gNB->pusch_vars[ul_id]->ul_ch_estimates;
int **rxdataF = gNB->common_vars.rxdataF;
@@ -128,7 +130,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
//------------------generate DMRS------------------//
if (pusch_pdu->transform_precoding == transform_precoder_disabled) {
- nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], 1000, 0, nb_rb_pusch, pusch_pdu->rb_start*NR_NB_SC_PER_RB, pusch_pdu->dmrs_config_type);
+ nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], 1000, 0, nb_rb_pusch, (pusch_pdu->bwp_start + pusch_pdu->rb_start)*NR_NB_SC_PER_RB, pusch_pdu->dmrs_config_type);
}
else { // if transform precoding or SC-FDMA is enabled in Uplink
diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.c b/openair1/PHY/NR_REFSIG/dmrs_nr.c
index 03a37e2b27..2e270318f8 100644
--- a/openair1/PHY/NR_REFSIG/dmrs_nr.c
+++ b/openair1/PHY/NR_REFSIG/dmrs_nr.c
@@ -150,7 +150,7 @@ void pseudo_random_sequence_optimised(unsigned int size, uint32_t *c, uint32_t c
unsigned int n,x1,x2;
/* init of m-sequences */
- x1 = 1+ (1<<31);
+ x1 = 1+ (1U<<31);
x2 = cinit;
x2=x2 ^ ((x2 ^ (x2>>1) ^ (x2>>2) ^ (x2>>3))<<31);
diff --git a/openair1/PHY/NR_REFSIG/nr_gen_mod_table.c b/openair1/PHY/NR_REFSIG/nr_gen_mod_table.c
index b0f9e6d03c..9ed2bd949f 100644
--- a/openair1/PHY/NR_REFSIG/nr_gen_mod_table.c
+++ b/openair1/PHY/NR_REFSIG/nr_gen_mod_table.c
@@ -21,6 +21,18 @@
#include "nr_refsig.h"
#include "nr_mod_table.h"
+short nr_qpsk_mod_table[8];
+
+int32_t nr_16qam_mod_table[16];
+#if defined(__SSE2__)
+__m128i nr_qpsk_byte_mod_table[2048];
+#endif
+
+int64_t nr_16qam_byte_mod_table[1024];
+
+int64_t nr_64qam_mod_table[4096];
+
+int32_t nr_256qam_mod_table[512];
void nr_generate_modulation_table() {
float sqrt2 = 0.70711;
diff --git a/openair1/PHY/NR_REFSIG/nr_mod_table.h b/openair1/PHY/NR_REFSIG/nr_mod_table.h
index aa8b99f584..2c6964fe96 100644
--- a/openair1/PHY/NR_REFSIG/nr_mod_table.h
+++ b/openair1/PHY/NR_REFSIG/nr_mod_table.h
@@ -29,16 +29,16 @@
#define NR_MOD_TABLE_QAM64_OFFSET 23
#define NR_MOD_TABLE_QAM256_OFFSET 87
-short nr_qpsk_mod_table[8];
+extern short nr_qpsk_mod_table[8];
-int32_t nr_16qam_mod_table[16];
+extern int32_t nr_16qam_mod_table[16];
#if defined(__SSE2__)
-__m128i nr_qpsk_byte_mod_table[2048];
+extern __m128i nr_qpsk_byte_mod_table[2048];
#endif
-int64_t nr_16qam_byte_mod_table[1024];
+extern int64_t nr_16qam_byte_mod_table[1024];
-int64_t nr_64qam_mod_table[4096];
+extern int64_t nr_64qam_mod_table[4096];
-int32_t nr_256qam_mod_table[512];
+extern int32_t nr_256qam_mod_table[512];
#endif
diff --git a/openair1/PHY/NR_REFSIG/pss_nr.h b/openair1/PHY/NR_REFSIG/pss_nr.h
index 19b9736bcb..b32d48a2e9 100644
--- a/openair1/PHY/NR_REFSIG/pss_nr.h
+++ b/openair1/PHY/NR_REFSIG/pss_nr.h
@@ -120,8 +120,7 @@ EXTERN int64_t *pss_corr_ue[NUMBER_PSS_SEQUENCE]
;
/* profiling structure */
-EXTERN double cpuf;
-time_stats_t generic_time[TIME_LAST];
+EXTERN time_stats_t generic_time[TIME_LAST];
#ifndef DEFINE_HEADER_ONLY
diff --git a/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h b/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h
index 44d30da8f3..43ec0c03dc 100644
--- a/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h
+++ b/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h
@@ -58,7 +58,7 @@
#define INDEX_SB_LESS_32 (4) /* index of dftsizes array for which subcarrier number is less than 36 */
-const uint16_t ul_allocated_re[SRS_SB_CONF] /* number of uplink allocated resource elements */
+EXTERN const uint16_t ul_allocated_re[SRS_SB_CONF] /* number of uplink allocated resource elements */
/* this table is derivated from TS 38.211 Table 6.4.1.4.3-1: SRS bandwidth configuration which gives m_SRS_b then all possible values of sequence length is */
/* M_sc_b_SRS = m_SRS_b * N_SC_RB/K_TC with K_TC = 2 or K_TC = 4 as specified in TS 38.211 6.4.1.4.3 */
#ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H
@@ -82,7 +82,7 @@ m_SRS_b 224 116, 240 256 264 272 144 152 160 168 176 184
;
/* table of largest prime number lower than uplink allocated resource elements "ul_allocated_re" */
-const uint16_t ref_ul_primes[SRS_SB_CONF]
+EXTERN const uint16_t ref_ul_primes[SRS_SB_CONF]
#ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H
= {
/* 6, 12, 18, 24, 30, 36, 48, 60, 72, 84, 96, 108, 120, 132, 144, 156, 168, 180, 192, 204, 216, 228, 240, */
@@ -101,10 +101,10 @@ const uint16_t ref_ul_primes[SRS_SB_CONF]
;
/* Low-PAPR base sequence; see TS 38.211 clause 5.2.2 */
-int16_t *rv_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][SRS_SB_CONF];
+EXTERN int16_t *rv_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][SRS_SB_CONF];
/* 38.211 table Table 5.2.2.2-1: Definition of phi(n) for M_ZC = 6 */
-const char phi_M_ZC_6[6*U_GROUP_NUMBER]
+EXTERN const char phi_M_ZC_6[6*U_GROUP_NUMBER]
#ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H
= {
/* 0 1 2 3 4 5 */
@@ -142,7 +142,7 @@ const char phi_M_ZC_6[6*U_GROUP_NUMBER]
#endif
;
/* Table 5.2.2.2-2: Definition of phi ( n ) for M ZC = 12 */
-const char phi_M_ZC_12[12*U_GROUP_NUMBER]
+EXTERN const char phi_M_ZC_12[12*U_GROUP_NUMBER]
#ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H
= {
/* 0 1 2 3 4 5 6 7 8 9 10 11 */
@@ -181,7 +181,7 @@ const char phi_M_ZC_12[12*U_GROUP_NUMBER]
;
/* Table 5.2.2.2-3: Definition of phi (n ) for M_ZC = 18 */
-const char phi_M_ZC_18[18*U_GROUP_NUMBER]
+EXTERN const char phi_M_ZC_18[18*U_GROUP_NUMBER]
#ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H
= {
/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 */
@@ -220,7 +220,7 @@ const char phi_M_ZC_18[18*U_GROUP_NUMBER]
;
/* Table 5.2.2.2-4: Definition of phi (n ) for M_ZC = 24 */
-const char phi_M_ZC_24[24*U_GROUP_NUMBER]
+EXTERN const char phi_M_ZC_24[24*U_GROUP_NUMBER]
#ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H
= {
/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 */
@@ -260,10 +260,10 @@ const char phi_M_ZC_24[24*U_GROUP_NUMBER]
/************** FUNCTION ******************************************/
-int16_t *base_sequence_36_or_larger(unsigned int M_ZC, unsigned int u, unsigned int v, unsigned int scaling, unsigned int if_dmrs_seq);
+EXTERN int16_t *base_sequence_36_or_larger(unsigned int M_ZC, unsigned int u, unsigned int v, unsigned int scaling, unsigned int if_dmrs_seq);
-int16_t *base_sequence_less_than_36(unsigned int M_ZC, unsigned int u, unsigned int scaling);
+EXTERN int16_t *base_sequence_less_than_36(unsigned int M_ZC, unsigned int u, unsigned int scaling);
/*!
\brief This function generate the sounding reference symbol (SRS) for the uplink.
@param tables of srs
@@ -278,7 +278,7 @@ void free_ul_reference_signal_sequences(void);
#define MAX_INDEX_DMRS_UL_ALLOCATED_REs 53
-const uint16_t dmrs_ul_allocated_res[MAX_INDEX_DMRS_UL_ALLOCATED_REs]
+EXTERN const uint16_t dmrs_ul_allocated_res[MAX_INDEX_DMRS_UL_ALLOCATED_REs]
/* Number of possible DMRS REs based on PRBs allocated for PUSCH. Array has values until 273 RBs (100Mhz BW)
Number of PUSCH RBs allocated should be able to be expressed as 2topowerofn*3topowerofn*5tothepowerofn
According to 3GPP spec 38.211 section 6.3.1.4
@@ -307,7 +307,7 @@ const uint16_t dmrs_ul_allocated_res[MAX_INDEX_DMRS_UL_ALLOCATED_REs]
/* Table of largest prime number N_ZC < possible DMRS REs M_ZC, this array has values until 100Mhz
According to 3GPP spec 38.211 section 5.2.2.1
Table used in calculating DMRS low papr type1 sequence for transform precoding */
-const uint16_t dmrs_ref_ul_primes[MAX_INDEX_DMRS_UL_ALLOCATED_REs]
+EXTERN const uint16_t dmrs_ref_ul_primes[MAX_INDEX_DMRS_UL_ALLOCATED_REs]
#ifdef INIT_VARIABLES_LOWPAPR_SEQUENCES_NR_H
= {
/*DMRS REs 6, 12, 18, 24, 30, 36, 48, 54, 60, 72, 90, 96, */
@@ -331,8 +331,8 @@ const uint16_t dmrs_ref_ul_primes[MAX_INDEX_DMRS_UL_ALLOCATED_REs]
;
/// PUSCH DMRS for transform precoding
-int16_t *gNB_dmrs_lowpaprtype1_sequence[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs];
-int16_t *dmrs_lowpaprtype1_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs];
+EXTERN int16_t *gNB_dmrs_lowpaprtype1_sequence[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs];
+EXTERN int16_t *dmrs_lowpaprtype1_ul_ref_sig[U_GROUP_NUMBER][V_BASE_SEQUENCE_NUMBER][MAX_INDEX_DMRS_UL_ALLOCATED_REs];
int16_t get_index_for_dmrs_lowpapr_seq(int16_t num_dmrs_res);
void generate_lowpapr_typ1_refsig_sequences(unsigned int scaling);
void free_gnb_lowpapr_sequences(void);
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c
index b7de182ab7..3f6eb00bcb 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dci.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c
@@ -97,7 +97,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
cset_start_symb = pdcch_pdu_rel15->StartSymbolIndex;
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_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
index 35c4698761..2d43fb5aed 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
@@ -152,7 +152,7 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
else {
nb_re_dmrs = 4*rel15->numDmrsCdmGrpsNoData;
}
- n_dmrs = (rel15->rbSize+rel15->rbStart)*nb_re_dmrs;
+ n_dmrs = (rel15->BWPStart+rel15->rbStart+rel15->rbSize)*nb_re_dmrs;
uint16_t dmrs_symbol_map = rel15->dlDmrsSymbPos;//single DMRS: 010000100 Double DMRS 110001100
uint8_t dmrs_len = get_num_dmrs(rel15->dlDmrsSymbPos);
@@ -266,6 +266,7 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
#endif
/// DMRS QPSK modulation
+ // TODO: performance improvement, we can skip the modulation of DMRS symbols outside the bandwidth part
for (int l=rel15->StartSymbolIndex; lStartSymbolIndex+rel15->NrOfSymbols; l++) {
if (rel15->dlDmrsSymbPos & (1 << l)) {
nr_modulation(pdsch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs[l]); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
@@ -318,11 +319,24 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
/// DMRS QPSK modulation
uint8_t k_prime=0;
uint16_t n=0;
- if ((dmrs_symbol_map & (1 << l))){ //DMRS time occasion
- if (dmrs_Type == NFAPI_NR_DMRS_TYPE1) // another if condition to be included to check pdsch config type (reference of k)
- dmrs_idx = rel15->rbStart*6;
- else
- dmrs_idx = rel15->rbStart*4;
+
+ if ((dmrs_symbol_map & (1 << l))){ // DMRS time occasion
+ // The reference point for is subcarrier 0 of the lowest-numbered resource block in CORESET 0 if the corresponding
+ // PDCCH is associated with CORESET 0 and Type0-PDCCH common search space and is addressed to SI-RNTI
+ // 3GPP TS 38.211 V15.8.0 Section 7.4.1.1.2 Mapping to physical resources
+ if (rel15->rnti==SI_RNTI) {
+ if (dmrs_Type==NFAPI_NR_DMRS_TYPE1) {
+ dmrs_idx = rel15->rbStart*6;
+ } else {
+ dmrs_idx = rel15->rbStart*4;
+ }
+ } else {
+ if (dmrs_Type == NFAPI_NR_DMRS_TYPE1) {
+ dmrs_idx = (rel15->rbStart+rel15->BWPStart)*6;
+ } else {
+ dmrs_idx = (rel15->rbStart+rel15->BWPStart)*4;
+ }
+ }
}
// Update l_prime in the case of double DMRS config
@@ -507,7 +521,7 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
gNB->common_vars.beam_id[0][slot*frame_parms->symbols_per_slot+j] = rel15->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx;
}
else {
- LOG_W(PHY,"beam index for PDSCH allocation already taken\n");
+ LOG_D(PHY,"beam index for PDSCH allocation already taken\n");
}
}// dlsch loop
diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c
index 8248de7416..34c647810d 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_prach.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c
@@ -774,7 +774,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
else {
preamble_shift -= NCS;
-
+
if (preamble_shift < 0)
preamble_shift+=N_ZC;
}
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
index edca81d501..c1bca8d2a0 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
@@ -326,7 +326,7 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
#endif
uint8_t is_dmrs_re;
- start_re = (frame_parms->first_carrier_offset + (pusch_pdu->rb_start * NR_NB_SC_PER_RB))%frame_parms->ofdm_symbol_size;
+ start_re = (frame_parms->first_carrier_offset + (pusch_pdu->rb_start + pusch_pdu->bwp_start) * NR_NB_SC_PER_RB)%frame_parms->ofdm_symbol_size;
nb_re_pusch = NR_NB_SC_PER_RB * pusch_pdu->rb_size;
#ifdef __AVX2__
int nb_re_pusch2 = nb_re_pusch + (nb_re_pusch&7);
@@ -1178,7 +1178,7 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
}
- bwp_start_subcarrier = (rel15_ul->rb_start*NR_NB_SC_PER_RB + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size;
+ bwp_start_subcarrier = ((rel15_ul->rb_start + rel15_ul->bwp_start)*NR_NB_SC_PER_RB + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size;
dmrs_symbol_flag = ((rel15_ul->ul_dmrs_symb_pos)>>symbol)&0x01;
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
index 76a48f38ae..909d0b8954 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
@@ -657,6 +657,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
uint8_t eNB_offset,
+ bool is_SI,
unsigned char Ns,
unsigned short p,
unsigned char symbol,
@@ -694,7 +695,10 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
#endif
// generate pilot for gNB port number 1000+p
- uint16_t rb_offset = (bwp_start_subcarrier - ue->frame_parms.first_carrier_offset) / 12 - BWPStart;
+ uint16_t rb_offset = (bwp_start_subcarrier - ue->frame_parms.first_carrier_offset) / 12;
+ if (is_SI) {
+ rb_offset -= BWPStart;
+ }
uint8_t config_type = ue->dmrs_DownlinkConfig.pdsch_dmrs_type;
int8_t delta = get_delta(p, config_type);
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
index 6c461ef448..1466fabe5d 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
@@ -70,6 +70,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
uint8_t eNB_offset,
+ bool is_SI,
unsigned char Ns,
unsigned short p,
unsigned char symbol,
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_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
index 35c4a6e8cb..35baef1792 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
@@ -52,7 +52,7 @@
* set as command line argument, see lte-softmodem.c
* default value: 0
*/
-int16_t nr_dlsch_demod_shift = 0;
+int32_t nr_dlsch_demod_shift = 0;
//int16_t interf_unaw_shift = 13;
//#define DEBUG_HARQ
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
index 3d8c975a5c..60b87fae08 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
@@ -137,7 +137,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
uint8_t mod_order = pusch_pdu->qam_mod_order;
uint16_t rnti = pusch_pdu->rnti;
uint8_t cdm_grps_no_data = pusch_pdu->num_dmrs_cdm_grps_no_data;
- uint16_t start_sc = frame_parms->first_carrier_offset + start_rb*NR_NB_SC_PER_RB;
+ uint16_t start_sc = frame_parms->first_carrier_offset + (start_rb+pusch_pdu->bwp_start)*NR_NB_SC_PER_RB;
if (start_sc >= frame_parms->ofdm_symbol_size)
start_sc -= frame_parms->ofdm_symbol_size;
@@ -195,7 +195,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
/////////////////////////DMRS Modulation/////////////////////////
///////////
uint32_t ***pusch_dmrs = UE->nr_gold_pusch_dmrs[slot];
- uint16_t n_dmrs = (start_rb+nb_rb)*((dmrs_type == pusch_dmrs_type1) ? 6:4);
+ uint16_t n_dmrs = (pusch_pdu->bwp_start + start_rb + nb_rb)*((dmrs_type == pusch_dmrs_type1) ? 6:4);
int16_t mod_dmrs[n_dmrs<<1] __attribute((aligned(16)));
///////////
////////////////////////////////////////////////////////////////////////
@@ -355,16 +355,17 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
if (pusch_pdu->transform_precoding == transform_precoder_disabled){
if (dmrs_type == pusch_dmrs_type1)
- dmrs_idx = start_rb*6;
+ dmrs_idx = (pusch_pdu->bwp_start + start_rb)*6;
else
- dmrs_idx = start_rb*4;
-
- // Perform this on gold sequence, not required when SC FDMA operation is done,
+ dmrs_idx = (pusch_pdu->bwp_start + start_rb)*4;
+
+ // TODO: performance improvement, we can skip the modulation of DMRS symbols outside the bandwidth part
+ // Perform this on gold sequence, not required when SC FDMA operation is done,
nr_modulation(pusch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
} else {
- dmrs_idx = 0;
- }
+ dmrs_idx = 0;
+ }
} else if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
diff --git a/openair1/PHY/TOOLS/calibration_scope.c b/openair1/PHY/TOOLS/calibration_scope.c
new file mode 100644
index 0000000000..da1acb5175
--- /dev/null
+++ b/openair1/PHY/TOOLS/calibration_scope.c
@@ -0,0 +1,387 @@
+#include
+#include
+#include "executables/softmodem-common.h"
+#include "executables/nr-softmodem-common.h"
+#include
+#include
+
+#define TPUT_WINDOW_LENGTH 100
+#define ScaleZone 4
+
+const FL_COLOR rx_antenna_colors[4] = {FL_RED,FL_BLUE,FL_GREEN,FL_YELLOW};
+const FL_COLOR water_colors[4] = {FL_BLUE,FL_GREEN,FL_YELLOW,FL_RED};
+
+typedef struct {
+ int16_t r;
+ int16_t i;
+} scopeSample_t;
+#define SquaredNorm(VaR) ((VaR).r*(VaR).r+(VaR).i*(VaR).i)
+typedef struct {
+ void ** samplesRx;
+ openair0_device *rfdevice;
+} calibData_t;
+
+typedef struct OAIgraph {
+ FL_OBJECT *graph;
+ FL_OBJECT *text;
+ float maxX;
+ float maxY;
+ float minX;
+ float minY;
+ int x;
+ int y;
+ int w;
+ int h;
+ int waterFallh;
+ double *waterFallAvg;
+ boolean_t initDone;
+ int iteration;
+ void (*funct) (struct OAIgraph *graph, calibData_t *);
+} OAIgraph_t;
+
+
+/* Forms and Objects */
+typedef struct {
+ calibData_t * context;
+ FL_FORM *phy_scope;
+ OAIgraph_t graph[20];
+ FL_OBJECT *button_0;
+} OAI_phy_scope_t;
+
+typedef struct {
+ FL_FORM *stats_form;
+ void *vdata;
+ char *cdata;
+ long ldata;
+ FL_OBJECT *stats_text;
+ FL_OBJECT *stats_button;
+} FD_stats_form;
+
+static void drawsymbol(FL_OBJECT *obj, int id,
+ FL_POINT *p, int n, int w, int h) {
+ fl_points( p, n, FL_YELLOW);
+}
+
+#define WATERFALL 10000
+
+static void commonGraph(OAIgraph_t *graph, int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor) {
+ if (type==WATERFALL) {
+ graph->waterFallh=h-15;
+ graph->waterFallAvg=malloc(sizeof(*graph->waterFallAvg) * graph->waterFallh);
+
+ for (int i=0; i< graph->waterFallh; i++)
+ graph->waterFallAvg[i]=0;
+
+ graph->graph=fl_add_canvas(FL_NORMAL_CANVAS, x, y, w, graph->waterFallh, label);
+ graph->text=fl_add_text(FL_NORMAL_TEXT, x, y+graph->waterFallh, w, 15, label);
+ fl_set_object_lcolor(graph->text,FL_WHITE);
+ fl_set_object_color(graph->text, FL_BLACK, FL_BLACK);
+ fl_set_object_lalign(graph->text, FL_ALIGN_CENTER );
+ } else {
+ graph->graph=fl_add_xyplot(type, x, y, w, h, label);
+ fl_set_object_lcolor(graph->graph, FL_WHITE ); // Label color
+ fl_set_object_color(graph->graph, FL_BLACK, pointColor);
+
+ for (int i=0; i< FL_MAX_XYPLOTOVERLAY; i++)
+ fl_set_xyplot_symbol(graph->graph, i, drawsymbol);
+ }
+
+ graph->x=x;
+ graph->y=y;
+ graph->w=w;
+ graph->h=h;
+ graph->maxX=0;
+ graph->maxY=0;
+ graph->minX=0;
+ graph->minY=0;
+ graph->initDone=false;
+ graph->iteration=0;
+}
+
+static OAIgraph_t calibrationCommonGraph( void (*funct) (OAIgraph_t *graph, calibData_t *context),
+ int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor) {
+ OAIgraph_t graph;
+ commonGraph(&graph, type, x, y, w, h, label, pointColor);
+ graph.funct=funct;
+ return graph;
+}
+
+
+static void setRange(OAIgraph_t *graph, float minX, float maxX, float minY, float maxY) {
+ if ( maxX > graph->maxX || minX < graph->minX ||
+ abs(maxX-graph->maxX)>abs(graph->maxX)/2 ||
+ abs(maxX-graph->maxX)>abs(graph->maxX)/2 ) {
+ graph->maxX/=2;
+ graph->minX/=2;
+ graph->maxX=max(graph->maxX,maxX);
+ graph->minX=min(graph->minX,minX);
+ fl_set_xyplot_xbounds(graph->graph, graph->minX*1.2, graph->maxX*1.2);
+ }
+
+ if ( maxY > graph->maxY || minY < graph->minY ||
+ abs(maxY-graph->maxY)>abs(graph->maxY)/2 ||
+ abs(maxY-graph->maxY)>abs(graph->maxY)/2 ) {
+ graph->maxY/=2;
+ graph->minY/=2;
+ graph->maxY=max(graph->maxY,maxY);
+ graph->minY=min(graph->minY,minY);
+ fl_set_xyplot_ybounds(graph->graph, graph->minY*1.2, graph->maxY*1.2);
+ }
+}
+
+static void oai_xygraph_getbuff(OAIgraph_t *graph, float **x, float **y, int len, int layer) {
+ float *old_x;
+ float *old_y;
+ int old_len=-1;
+
+ if (graph->iteration >1)
+ fl_get_xyplot_data_pointer(graph->graph, layer, &old_x, &old_y, &old_len);
+
+ if (old_len != len) {
+ LOG_W(HW,"allocating graph of %d scope\n", len);
+ float values[len];
+ float time[len];
+
+ // make time in case we will use it
+ for (int i=0; igraph,time,values,len,"","","");
+ else
+ fl_add_xyplot_overlay(graph->graph,layer,time,values,len,rx_antenna_colors[layer]);
+
+ fl_get_xyplot_data_pointer(graph->graph, layer, &old_x, &old_y, &old_len);
+ AssertFatal(old_len==len,"");
+ }
+
+ *x=old_x;
+ *y=old_y;
+}
+
+static void oai_xygraph(OAIgraph_t *graph, float *x, float *y, int len, int layer, boolean_t NoAutoScale) {
+ fl_redraw_object(graph->graph);
+
+ if ( NoAutoScale && graph->iteration%NoAutoScale == 0) {
+ float maxX=0, maxY=0, minX=0, minY=0;
+
+ for (int k=0; kiteration++;
+}
+
+static void genericWaterFall (OAIgraph_t *graph, scopeSample_t *values, const int datasize, const int divisions, const char *label) {
+ if ( values == NULL )
+ return;
+ fl_winset(FL_ObjWin(graph->graph));
+ const int samplesPerPixel=datasize/graph->w;
+ int displayPart=graph->waterFallh-ScaleZone;
+ int row=graph->iteration%displayPart;
+ double avg=0;
+
+ for (int i=0; i < displayPart; i++)
+ avg+=graph->waterFallAvg[i];
+
+ avg/=displayPart;
+ graph->waterFallAvg[row]=0;
+
+ for (int pix=0; pixw; pix++) {
+ scopeSample_t *end=values+(pix+1)*samplesPerPixel;
+ end-=2;
+ AssertFatal(end <= values+datasize,"diff : %ld", end-values+datasize);
+ double val=0;
+
+ for (scopeSample_t *s=values+(pix)*samplesPerPixel;
+ s waterFallAvg[row]+=val/graph->w;
+ int col=0;
+
+ if (val > avg*2 )
+ col=1;
+
+ if (val > avg*10 )
+ col=2;
+
+ if (val > avg*100 )
+ col=3;
+
+ fl_point(pix, graph->iteration%displayPart, water_colors[col]);
+ }
+
+ if (graph->initDone==false) {
+ for ( int i=0; i < graph->waterFallh; i++ )
+ for ( int j = 0 ; j < graph->w ; j++ )
+ fl_point(j, i, FL_BLACK);
+
+ for ( int i=1; iwaterFallh; j++)
+ fl_point(i*(graph->w/divisions),j, FL_WHITE);
+
+ graph->initDone=true;
+ }
+
+ fl_set_object_label_f(graph->text, "%s, avg I/Q pow: %4.1f", label, sqrt(avg));
+ graph->iteration++;
+}
+
+static void genericPowerPerAntena(OAIgraph_t *graph, const int nb_ant, const scopeSample_t **data, const int len) {
+ float *values, *time;
+ oai_xygraph_getbuff(graph, &time, &values, len, 0);
+
+ for (int ant=0; antsamplesRx[0],
+ 0, 0,
+ "X axis:one frame in time");
+}
+static void gNBfreqWaterFall (OAIgraph_t *graph, calibData_t *context) {
+ //use 1st antenna
+ genericWaterFall(graph, (scopeSample_t *)context->samplesRx[0],
+ 0, 0,
+ "X axis:one frame in time");
+}
+static void timeResponse (OAIgraph_t *graph, calibData_t *context) {
+ #if 0
+ const int len=2*phy_vars_gnb->frame_parms.ofdm_symbol_size;
+ float *values, *time;
+ oai_xygraph_getbuff(graph, &time, &values, len, 0);
+ const int ant=0; // display antenna 0 for each UE
+
+ for (int ue=0; uepusch_vars[ue]->ul_ch_estimates_time[ant];
+
+ if (data != NULL) {
+ for (int i=0; iframe_parms;
+ int sz=frame_parms->N_RB_UL*12*frame_parms->symbols_per_slot;
+
+ for (int ue=0; uepusch_vars[ue]->rxdataF_comp[0];
+ float *I, *Q;
+ oai_xygraph_getbuff(graph, &I, &Q, sz, ue);
+
+ if (pusch_comp) {
+ for (int k=0; kcontext=context;
+ // Define form
+ fdui->phy_scope = fl_bgn_form( FL_NO_BOX, 800, 800 );
+ // This the whole UI box
+ obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 800, "" );
+ fl_set_object_color( obj, FL_BLACK, FL_WHITE );
+ int curY=0,x,y,w,h;
+ // Received signal
+ fdui->graph[0] = calibrationCommonGraph( gNBWaterFall, WATERFALL, 0, curY, 400, 100,
+ "Received Signal (Time-Domain, one frame)", FL_RED );
+
+ // Time-domain channel response
+ //fdui->graph[1] = calibrationCommonGraph( timeResponse, FL_NORMAL_XYPLOT, 410, curY, 400, 100, "SRS Frequency Response (samples, abs)", FL_RED );
+ fl_get_object_bbox(fdui->graph[0].graph,&x, &y,&w, &h);
+ curY+=h;
+ // Frequency-domain channel response
+ fdui->graph[1] = calibrationCommonGraph( gNBfreqWaterFall, WATERFALL, 0, curY, 800, 100,
+ "Channel Frequency domain (RE, one frame)", FL_RED );
+ fl_get_object_bbox(fdui->graph[1].graph,&x, &y,&w, &h);
+ curY+=h+20;
+ // LLR of PUSCH
+ //fdui->graph[3] = calibrationCommonGraph( puschLLR, FL_POINTS_XYPLOT, 0, curY, 500, 200, "PUSCH Log-Likelihood Ratios (LLR, mag)", FL_YELLOW );
+ // I/Q PUSCH comp
+ fdui->graph[2] = calibrationCommonGraph( puschIQ, FL_POINTS_XYPLOT, 500, curY, 300, 200,
+ "PUSCH I/Q of MF Output", FL_YELLOW );
+ fl_get_object_bbox(fdui->graph[2].graph,&x, &y,&w, &h);
+ curY+=h;
+ //fl_get_object_bbox(fdui->graph[6].graph,&x, &y,&w, &h);
+ curY+=h;
+ fdui->graph[3].graph=NULL;
+ fl_end_form( );
+ fdui->phy_scope->fdui = fdui;
+ fl_show_form (fdui->phy_scope, FL_PLACE_HOTSPOT, FL_FULLBORDER, "LTE UL SCOPE gNB");
+ return fdui;
+}
+
+void calibrationScope(OAI_phy_scope_t *form) {
+ int i=0;
+
+ while (form->graph[i].graph) {
+ form->graph[i].funct(form->graph+i, form->context);
+ i++;
+ }
+
+ //fl_check_forms();
+}
+
+static void *scopeThread(void *arg) {
+ calibData_t * context = (calibData_t *)arg;
+ size_t stksize=0;
+ pthread_attr_t atr;
+ pthread_attr_init(&atr);
+ pthread_attr_getstacksize(&atr, &stksize);
+ pthread_attr_setstacksize(&atr,32*1024*1024 );
+ sleep(3); // no clean interthread barriers
+ int fl_argc=1;
+ char *name="Calibration-scope";
+ fl_initialize (&fl_argc, &name, NULL, 0, 0);
+ OAI_phy_scope_t *form = createScopeCalibration(context);
+
+ while (!oai_exit) {
+ calibrationScope(form);
+ usleep(99*1000);
+ }
+
+ return NULL;
+}
+
+void CalibrationInitScope(void ** samplesRx,openair0_device *rfdevice) {
+ pthread_t forms_thread;
+ calibData_t * tmp=(calibData_t *) malloc(sizeof(*tmp));
+ tmp->samplesRx=samplesRx;
+ tmp->rfdevice=rfdevice;
+ threadCreate(&forms_thread, scopeThread, (void*) tmp, "scope", -1, OAI_PRIORITY_RT_LOW);
+}
diff --git a/openair1/PHY/TOOLS/calibration_scope.h b/openair1/PHY/TOOLS/calibration_scope.h
new file mode 100644
index 0000000000..052a1a6b6e
--- /dev/null
+++ b/openair1/PHY/TOOLS/calibration_scope.h
@@ -0,0 +1,5 @@
+#ifndef CALIB_SCOPE_H
+#define CALIB_SCOPE_H
+
+void CalibrationInitScope(void ** samplesRx,openair0_device *rfdevice);
+#endif
diff --git a/openair1/PHY/TOOLS/calibration_test.c b/openair1/PHY/TOOLS/calibration_test.c
new file mode 100644
index 0000000000..982ca9d254
--- /dev/null
+++ b/openair1/PHY/TOOLS/calibration_test.c
@@ -0,0 +1,330 @@
+#include
+#include
+#include
+#include
+#include
+
+
+volatile int oai_exit=false;
+unsigned int mmapped_dma=0;
+int single_thread_flag;
+uint32_t timing_advance;
+int8_t threequarter_fs;
+int usrp_tx_thread;
+uint64_t downlink_frequency[MAX_NUM_CCs][4];
+int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
+int opp_enabled;
+static double snr_dB=20;
+THREAD_STRUCT thread_struct;
+#include
+
+int read_recplayconfig(recplay_conf_t **recplay_conf, recplay_state_t **recplay_state) {return 0;}
+void nfapi_setmode(nfapi_mode_t nfapi_mode) {}
+void set_taus_seed(unsigned int seed_init){};
+
+int main(int argc, char **argv) {
+ ///static configuration for NR at the moment
+ if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == NULL) {
+ exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
+ }
+ set_softmodem_sighandler();
+ setvbuf(stdout, NULL, _IONBF, 0);
+ setvbuf(stderr, NULL, _IONBF, 0);
+ logInit();
+ paramdef_t cmdline_params[] = CMDLINE_PARAMS_DESC_GNB ;
+
+ CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP);
+ get_common_options(SOFTMODEM_GNB_BIT );
+ config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL);
+ CONFIG_CLEARRTFLAG(CONFIG_NOEXITONHELP);
+ configure_linux();
+
+
+ int N_RB=50;
+ int subCarrierFreq=30e3;
+ int sampling_rate=30.72e6;
+ int DFT=2048;
+ int TxAdvanceInDFTSize=12;
+ int antennas=1;
+ uint64_t freq=3619.200e6;
+ int rxGain=90;
+ int txGain=90;
+ int filterBand=40e6;
+ char * usrp_addrs="type=b200";
+
+ openair0_config_t openair0_cfg= {
+ //! Module ID for this configuration
+ .Mod_id=0,
+ //! device log level
+ .log_level=0,
+ //! duplexing mode
+ .duplex_mode=0,
+ //! number of downlink resource blocks
+ .num_rb_dl=N_RB,
+ //! number of samples per frame
+ .samples_per_frame=0,
+ //! the sample rate for both transmit and receive.
+ .sample_rate=sampling_rate,
+ //device is doing mmapped DMA transfers
+ .mmapped_dma=0,
+ //! offset in samples between TX and RX paths
+ .tx_sample_advance=0,
+ //! samples per packet on the fronthaul interface
+ .samples_per_packet=1024,
+ //! number of RX channels (=RX antennas)
+ .rx_num_channels=antennas,
+ //! number of TX channels (=TX antennas)
+ .tx_num_channels=antennas,
+ //! \brief Center frequency in Hz for RX.
+ //! index: [0..rx_num_channels[
+ .rx_freq={freq,freq,freq,freq},
+ //! \brief Center frequency in Hz for TX.
+ //! index: [0..rx_num_channels[ !!! see lte-ue.c:427 FIXME iterates over rx_num_channels
+ .tx_freq={freq,freq,freq,freq},
+ //! \brief memory
+ //! \brief Pointer to Calibration table for RX gains
+ .rx_gain_calib_table=NULL,
+ //! mode for rxgain (ExpressMIMO2)
+ .rxg_mode={0},
+ //! \brief Gain for RX in dB.
+ //! index: [0..rx_num_channels]
+ .rx_gain={rxGain,rxGain,rxGain,rxGain},
+ //! \brief Gain offset (for calibration) in dB
+ //! index: [0..rx_num_channels]
+ .rx_gain_offset={0},
+ //! gain for TX in dB
+ .tx_gain={txGain,txGain,txGain,txGain},
+ //! RX bandwidth in Hz
+ .rx_bw=filterBand,
+ //! TX bandwidth in Hz
+ .tx_bw=filterBand,
+ //! clock source
+ .clock_source=external,//internal gpsdo external
+ //! timing_source
+ .time_source=internal, //internal gpsdo external
+ //! Manual SDR IP address
+ //#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
+ .sdr_addrs=usrp_addrs,
+ //! Auto calibration flag
+ .autocal={0},
+ //! rf devices work with x bits iqs when oai have its own iq format
+ //! the two following parameters are used to convert iqs
+ .iq_txshift=0,
+ .iq_rxrescale=0,
+ //! Configuration file for LMS7002M
+ .configFilename="",
+ //! remote IP/MAC addr for Ethernet interface
+ .remote_addr="",
+ //! remote port number for Ethernet interface
+ .remote_port=0,
+ //! local IP/MAC addr for Ethernet interface (eNB/BBU, UE)
+ .my_addr=0,
+ //! local port number for Ethernet interface (eNB/BBU, UE)
+ .my_port=0,
+ //! record player configuration, definition in record_player.h
+ .recplay_mode=0,
+ .recplay_conf=NULL,
+ //! number of samples per tti
+ .samples_per_tti=0,
+ //! check for threequarter sampling rate
+ .threequarter_fs=0,
+ };
+ //-----------------------
+ openair0_device rfdevice= {
+ /*!tx write thread*/
+ //.write_thread={0},
+ /*!brief Module ID of this device */
+ .Mod_id=0,
+ /*!brief Component Carrier ID of this device */
+ .CC_id=0,
+ /*!brief Type of this device */
+ .type=NONE_DEV,
+ /*!brief Transport protocol type that the device supports (in case I/Q samples need to be transported) */
+ .transp_type=NONE_TP,
+ /*!brief Type of the device's host (RAU/RRU) */
+ .host_type=MIN_HOST_TYPE,
+ /* !brief RF frontend parameters set by application */
+ .openair0_cfg=NULL, //set by device_init
+ /* !brief ETH params set by application */
+ .eth_params=NULL,
+ //! record player data, definition in record_player.h
+ .recplay_state=NULL,
+ /* !brief Indicates if device already initialized */
+ .is_init=0,
+ /*!brief Can be used by driver to hold internal structure*/
+ .priv=NULL,
+ /* Functions API, which are called by the application*/
+ /*! \brief Called to start the transceiver. Return 0 if OK, < 0 if error
+ @param device pointer to the device structure specific to the RF hardware target
+ */
+ .trx_start_func=NULL,
+
+ /*! \brief Called to configure the device
+ @param device pointer to the device structure specific to the RF hardware target
+ */
+ .trx_config_func=NULL,
+
+ /*! \brief Called to send a request message between RAU-RRU on control port
+ @param device pointer to the device structure specific to the RF hardware target
+ @param msg pointer to the message structure passed between RAU-RRU
+ @param msg_len length of the message
+ */
+ .trx_ctlsend_func=NULL,
+
+ /*! \brief Called to receive a reply message between RAU-RRU on control port
+ @param device pointer to the device structure specific to the RF hardware target
+ @param msg pointer to the message structure passed between RAU-RRU
+ @param msg_len length of the message
+ */
+ .trx_ctlrecv_func=NULL,
+
+ /*! \brief Called to send samples to the RF target
+ @param device pointer to the device structure specific to the RF hardware target
+ @param timestamp The timestamp at whicch the first sample MUST be sent
+ @param buff Buffer which holds the samples (2 dimensional)
+ @param nsamps number of samples to be sent
+ @param number of antennas
+ @param flags flags must be set to TRUE if timestamp parameter needs to be applied
+ */
+ .trx_write_func=NULL,
+
+ /*! \brief Called to send samples to the RF target
+ @param device pointer to the device structure specific to the RF hardware target
+ @param timestamp The timestamp at whicch the first sample MUST be sent
+ @param buff Buffer which holds the samples (1 dimensional)
+ @param nsamps number of samples to be sent
+ @param antenna_id index of the antenna if the device has multiple anteannas
+ @param flags flags must be set to TRUE if timestamp parameter needs to be applied
+ */
+ .trx_write_func2=NULL,
+
+ /*! \brief Receive samples from hardware.
+ * Read \ref nsamps samples from each channel to buffers. buff[0] is the array for
+ * the first channel. *ptimestamp is the time at which the first sample
+ * was received.
+ * \param device the hardware to use
+ * \param[out] ptimestamp the time at which the first sample was received.
+ * \param[out] buff An array of pointers to buffers for received samples. The buffers must be large enough to hold the number of samples \ref nsamps.
+ * \param nsamps Number of samples. One sample is 2 byte I + 2 byte Q => 4 byte.
+ * \param num_antennas number of antennas from which to receive samples
+ * \returns the number of sample read
+ */
+
+ .trx_read_func=NULL,
+
+ /*! \brief Receive samples from hardware, this version provides a single antenna at a time and returns.
+ * Read \ref nsamps samples from each channel to buffers. buff[0] is the array for
+ * the first channel. *ptimestamp is the time at which the first sample
+ * was received.
+ * \param device the hardware to use
+ * \param[out] ptimestamp the time at which the first sample was received.
+ * \param[out] buff A pointers to a buffer for received samples. The buffer must be large enough to hold the number of samples \ref nsamps.
+ * \param nsamps Number of samples. One sample is 2 byte I + 2 byte Q => 4 byte.
+ * \param antenna_id Index of antenna from which samples were received
+ * \returns the number of sample read
+ */
+ .trx_read_func2=NULL,
+
+ /*! \brief print the device statistics
+ * \param device the hardware to use
+ * \returns 0 on success
+ */
+ /*! \brief print the device statistics
+ * \param device the hardware to use
+ * \returns 0 on success
+ */
+ .trx_get_stats_func=NULL,
+
+ /*! \brief Reset device statistics
+ * \param device the hardware to use
+ * \returns 0 in success
+ */
+ .trx_reset_stats_func=NULL,
+
+ /*! \brief Terminate operation of the transceiver -- free all associated resources
+ * \param device the hardware to use
+ */
+ .trx_end_func=NULL,
+
+ /*! \brief Stop operation of the transceiver
+ */
+ .trx_stop_func=NULL,
+
+ /* Functions API related to UE*/
+
+ /*! \brief Set RX feaquencies
+ * \param device the hardware to use
+ * \param openair0_cfg RF frontend parameters set by application
+ * \param exmimo_dump_config dump EXMIMO configuration
+ * \returns 0 in success
+ */
+ .trx_set_freq_func=NULL,
+
+ /*! \brief Set gains
+ * \param device the hardware to use
+ * \param openair0_cfg RF frontend parameters set by application
+ * \returns 0 in success
+ */
+ .trx_set_gains_func=NULL,
+
+ /*! \brief RRU Configuration callback
+ * \param idx RU index
+ * \param arg pointer to capabilities or configuration
+ */
+ .configure_rru=NULL,
+ /*! \brief Pointer to generic RRU private information
+ */
+ .thirdparty_priv=NULL,
+ .thirdparty_init=NULL,
+ /*! \brief Callback for Third-party RRU Cleanup routine
+ \param device the hardware configuration to use
+ */
+ .thirdparty_cleanup=NULL,
+
+ /*! \brief Callback for Third-party start streaming routine
+ \param device the hardware configuration to use
+ */
+ .thirdparty_startstreaming=NULL,
+
+ /*! \brief RRU Configuration callback
+ * \param idx RU index
+ * \param arg pointer to capabilities or configuration
+ */
+ .trx_write_init=NULL,
+ /* \brief Get internal parameter
+ * \param id parameter to get
+ * \return a pointer to the parameter
+ */
+ .get_internal_parameter=NULL,
+ };
+
+ openair0_device_load(&rfdevice,&openair0_cfg);
+
+ void ** samplesRx = (void **)malloc16(antennas* sizeof(struct complex16 *) );
+ void ** samplesTx = (void **)malloc16(antennas* sizeof(struct complex16 *) );
+
+ for (int i=0; ilte_phy_scope_enb, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
- if (otg_enabled) {
+ if (0) {
fl_set_button(form_enb[CC_id][UE_id]->button_0,1);
fl_set_object_label(form_enb[CC_id][UE_id]->button_0,"DL Traffic ON");
} else {
diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c
index acd22bc78d..d28bb1b8ba 100644
--- a/openair1/PHY/TOOLS/lte_phy_scope.c
+++ b/openair1/PHY/TOOLS/lte_phy_scope.c
@@ -27,7 +27,6 @@
#include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h"
#define TPUT_WINDOW_LENGTH 100
-int otg_enabled;
FL_COLOR rx_antenna_colors[4] = {FL_RED,FL_BLUE,FL_GREEN,FL_YELLOW};
@@ -57,11 +56,9 @@ static void ia_receiver_on_off( FL_OBJECT *button, long arg) {
static void dl_traffic_on_off( FL_OBJECT *button, long arg) {
if (fl_get_button(button)) {
fl_set_object_label(button, "DL Traffic ON");
- otg_enabled = 1;
fl_set_object_color(button, FL_GREEN, FL_GREEN);
} else {
fl_set_object_label(button, "DL Traffic OFF");
- otg_enabled = 0;
fl_set_object_color(button, FL_RED, FL_RED);
}
}
@@ -131,7 +128,6 @@ FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void ) {
fdui->button_0 = fl_add_button( FL_PUSH_BUTTON, 20, 600, 240, 40, "" );
fl_set_object_lalign(fdui->button_0, FL_ALIGN_CENTER );
fl_set_button(fdui->button_0,0);
- otg_enabled = 0;
fl_set_object_label(fdui->button_0, "DL Traffic OFF");
fl_set_object_color(fdui->button_0, FL_RED, FL_RED);
fl_set_object_callback(fdui->button_0, dl_traffic_on_off, 0 );
@@ -153,7 +149,6 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
int16_t **chest_t;
int16_t **chest_f;
int16_t *pusch_llr;
- int32_t *pusch_comp;
int32_t *pucch1_comp;
int32_t *pucch1_thres;
int32_t *pucch1ab_comp;
@@ -184,12 +179,11 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
chest_f_abs = (float *) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float));
llr = (float *) calloc(coded_bits_per_codeword,sizeof(float)); // init to zero
bit = malloc(coded_bits_per_codeword*sizeof(float));
-
- rxsig_t = (int16_t**) phy_vars_enb->RU_list[0]->common.rxdata;
+ rxsig_t = (int16_t **) phy_vars_enb->RU_list[0]->common.rxdata;
chest_t = (int16_t **) phy_vars_enb->srs_vars[UE_id].srs_ch_estimates;
chest_f = (int16_t **) phy_vars_enb->pusch_vars[UE_id]->drs_ch_estimates;
pusch_llr = (int16_t *) phy_vars_enb->pusch_vars[UE_id]->llr;
- pusch_comp = (int32_t *) phy_vars_enb->pusch_vars[UE_id]->rxdataF_comp[0];
+ int16_t *pusch_comp= (int16_t *) phy_vars_enb->pusch_vars[UE_id]->rxdataF_comp[0];
pucch1_comp = (int32_t *) phy_vars_enb->pucch1_stats[UE_id];
pucch1_thres = (int32_t *) phy_vars_enb->pucch1_stats_thres[UE_id];
pucch1ab_comp = (int32_t *) phy_vars_enb->pucch1ab_stats[UE_id];
diff --git a/openair1/PHY/TOOLS/lte_phy_scope_tm4.c b/openair1/PHY/TOOLS/lte_phy_scope_tm4.c
index d44f8e325b..a9caf8713b 100644
--- a/openair1/PHY/TOOLS/lte_phy_scope_tm4.c
+++ b/openair1/PHY/TOOLS/lte_phy_scope_tm4.c
@@ -32,8 +32,7 @@ float tput_time_ue[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
float tput_ue[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
float tput_ue_max[NUMBER_OF_UE_MAX] = {0};
-static void ia_receiver_on_off( FL_OBJECT *button, long arg)
-{
+static void ia_receiver_on_off( FL_OBJECT *button, long arg) {
if (fl_get_button(button)) {
fl_set_object_label(button, "IA Receiver ON");
// PHY_vars_UE_g[0][0]->use_ia_receiver = 1;
@@ -45,8 +44,7 @@ static void ia_receiver_on_off( FL_OBJECT *button, long arg)
}
}
-static void dl_traffic_on_off( FL_OBJECT *button, long arg)
-{
+static void dl_traffic_on_off( FL_OBJECT *button, long arg) {
if (fl_get_button(button)) {
fl_set_object_label(button, "DL Traffic ON");
otg_enabled = 1;
@@ -58,9 +56,7 @@ static void dl_traffic_on_off( FL_OBJECT *button, long arg)
}
}
-static void sic_receiver_on_off( FL_OBJECT *button, long arg)
-{
-
+static void sic_receiver_on_off( FL_OBJECT *button, long arg) {
if (fl_get_button(button)) {
fl_set_object_label(button, "SIC Receiver ON");
use_sic_receiver = 1;
@@ -72,8 +68,7 @@ static void sic_receiver_on_off( FL_OBJECT *button, long arg)
}
}
-FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void )
-{
+FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void ) {
FL_OBJECT *obj;
FD_lte_phy_scope_enb *fdui = fl_malloc( sizeof *fdui );
// Define form
@@ -145,8 +140,7 @@ FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void )
void phy_scope_eNB(FD_lte_phy_scope_enb *form,
PHY_VARS_eNB *phy_vars_enb,
- int UE_id)
-{
+ int UE_id) {
int eNB_id = 0;
int i,i2,arx,atx,ind,k;
LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_enb->frame_parms;
@@ -176,24 +170,27 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
int coded_bits_per_codeword = 0;
uint8_t harq_pid; // in TDD config 3 it is sf-2, i.e., can be 0,1,2
int mcs = 0;
+
// choose max MCS to compute coded_bits_per_codeword
if (phy_vars_enb->ulsch[UE_id]!=NULL) {
for (harq_pid=0; harq_pid<3; harq_pid++) {
mcs = cmax(phy_vars_enb->ulsch[UE_id]->harq_processes[harq_pid]->mcs,mcs);
}
}
+
coded_bits_per_codeword = frame_parms->N_RB_UL*12*get_Qm(mcs)*frame_parms->symbols_per_tti;
- chest_f_abs = (float*) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float));
- llr = (float*) calloc(coded_bits_per_codeword,sizeof(float)); // init to zero
+ chest_f_abs = (float *) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float));
+ llr = (float *) calloc(coded_bits_per_codeword,sizeof(float)); // init to zero
bit = malloc(coded_bits_per_codeword*sizeof(float));
- rxsig_t = (int16_t**) phy_vars_enb->common_vars.rxdata[eNB_id];
- chest_t = (int16_t**) phy_vars_enb->pusch_vars[UE_id]->drs_ch_estimates_time[eNB_id];
- chest_f = (int16_t**) phy_vars_enb->pusch_vars[UE_id]->drs_ch_estimates[eNB_id];
- pusch_llr = (int16_t*) phy_vars_enb->pusch_vars[UE_id]->llr;
- pusch_comp = (int16_t*) phy_vars_enb->pusch_vars[UE_id]->rxdataF_comp[eNB_id][0];
- pucch1_comp = (int32_t*) phy_vars_enb->pucch1_stats[UE_id];
- pucch1_thres = (int32_t*) phy_vars_enb->pucch1_stats_thres[UE_id];
- pucch1ab_comp = (int32_t*) phy_vars_enb->pucch1ab_stats[UE_id];
+ rxsig_t = (int16_t **) phy_vars_enb->common_vars.rxdata[eNB_id];
+ chest_t = (int16_t **) phy_vars_enb->pusch_vars[UE_id]->drs_ch_estimates_time[eNB_id];
+ chest_f = (int16_t **) phy_vars_enb->pusch_vars[UE_id]->drs_ch_estimates[eNB_id];
+ pusch_llr = (int16_t *) phy_vars_enb->pusch_vars[UE_id]->llr;
+ pusch_comp = (int16_t *) phy_vars_enb->pusch_vars[UE_id]->rxdataF_comp[eNB_id][0];
+ pucch1_comp = (int32_t *) phy_vars_enb->pucch1_stats[UE_id];
+ pucch1_thres = (int32_t *) phy_vars_enb->pucch1_stats_thres[UE_id];
+ pucch1ab_comp = (int32_t *) phy_vars_enb->pucch1ab_stats[UE_id];
+
// Received signal in time domain of receive antenna 0
if (rxsig_t != NULL) {
if (rxsig_t[0] != NULL) {
@@ -201,48 +198,61 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
rxsig_t_dB[0][i] = 10*log10(1.0+(float) ((rxsig_t[0][2*i])*(rxsig_t[0][2*i])+(rxsig_t[0][2*i+1])*(rxsig_t[0][2*i+1])));
time[i] = (float) i;
}
+
fl_set_xyplot_data(form->rxsig_t,time,rxsig_t_dB[0],FRAME_LENGTH_COMPLEX_SAMPLES,"","","");
}
+
for (arx=1; arxrxsig_t,arx,time,rxsig_t_dB[arx],FRAME_LENGTH_COMPLEX_SAMPLES,rx_antenna_colors[arx]);
}
}
}
+
// Channel Impulse Response
if (chest_t != NULL) {
ymax = 0;
+
if (chest_t[0] !=NULL) {
for (i=0; i<(frame_parms->ofdm_symbol_size); i++) {
- i2 = (i+(frame_parms->ofdm_symbol_size>>1))%frame_parms->ofdm_symbol_size;
- time2[i] = (float)(i-(frame_parms->ofdm_symbol_size>>1));
+ i2 = (i+(frame_parms->ofdm_symbol_size>>1))%frame_parms->ofdm_symbol_size;
+ time2[i] = (float)(i-(frame_parms->ofdm_symbol_size>>1));
chest_t_abs[0][i] = 10*log10((float) (1+chest_t[0][2*i2]*chest_t[0][2*i2]+chest_t[0][2*i2+1]*chest_t[0][2*i2+1]));
+
if (chest_t_abs[0][i] > ymax)
ymax = chest_t_abs[0][i];
}
+
fl_set_xyplot_data(form->chest_t,time2,chest_t_abs[0],(frame_parms->ofdm_symbol_size),"","","");
}
+
for (arx=1; arxofdm_symbol_size>>3); i++) {
chest_t_abs[arx][i] = 10*log10((float) (1+chest_t[arx][2*i]*chest_t[arx][2*i]+chest_t[arx][2*i+1]*chest_t[arx][2*i+1]));
+
if (chest_t_abs[arx][i] > ymax)
ymax = chest_t_abs[arx][i];
}
+
fl_add_xyplot_overlay(form->chest_t,arx,time,chest_t_abs[arx],(frame_parms->ofdm_symbol_size>>3),rx_antenna_colors[arx]);
fl_set_xyplot_overlay_type(form->chest_t,arx,FL_DASHED_XYPLOT);
}
}
+
// Avoid flickering effect
// fl_get_xyplot_ybounds(form->chest_t,&ymin,&ymax);
fl_set_xyplot_ybounds(form->chest_t,0,ymax);
}
+
// Channel Frequency Response
if (chest_f != NULL) {
ind = 0;
+
for (atx=0; atxchest_f,0,nb_antennas_rx*nb_antennas_tx*nsymb_ce);
fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*frame_parms->symbols_per_tti,3);
fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR);
fl_set_xyplot_data(form->chest_f,freq,chest_f_abs,nsymb_ce,"","","");
+
for (arx=1; arxchest_f,1,&freq[arx*nsymb_ce],&chest_f_abs[arx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
}
+
// other tx antennas
if (nb_antennas_tx > 1) {
if (nb_antennas_rx > 1) {
@@ -279,17 +292,21 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
}
}
}
+
// PUSCH LLRs
if (pusch_llr != NULL) {
for (i=0; ipusch_llr,bit,llr,coded_bits_per_codeword,"","","");
}
+
// PUSCH I/Q of MF Output
if (pusch_comp!=NULL) {
ind=0;
+
for (k=0; ksymbols_per_tti; k++) {
for (i=0; i<12*frame_parms->N_RB_UL; i++) {
I[ind] = pusch_comp[(2*frame_parms->N_RB_UL*12*k)+2*i];
@@ -297,8 +314,10 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
ind++;
}
}
+
fl_set_xyplot_data(form->pusch_comp,I,Q,ind,"","","");
}
+
// PUSCH I/Q of MF Output
if (pucch1ab_comp!=NULL) {
for (ind=0; ind<10240; ind++) {
@@ -308,6 +327,7 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
B_pucch[ind] = ind;
C_pucch[ind] = (float)pucch1_thres[ind];
}
+
fl_set_xyplot_data(form->pucch_comp,I_pucch,Q_pucch,10240,"","","");
fl_set_xyplot_data(form->pucch_comp1,B_pucch,A_pucch,1024,"","","");
fl_add_xyplot_overlay(form->pucch_comp1,1,B_pucch,C_pucch,1024,FL_RED);
@@ -315,6 +335,7 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
fl_set_xyplot_xbounds(form->pucch_comp,-5000,5000);
fl_set_xyplot_ybounds(form->pucch_comp1,0,80);
}
+
// PUSCH Throughput
memmove( tput_time_enb[UE_id], &tput_time_enb[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) );
memmove( tput_enb[UE_id], &tput_enb[UE_id][1], (TPUT_WINDOW_LENGTH-1)*sizeof(float) );
@@ -329,509 +350,564 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form,
free(chest_f_abs);
}
-FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void )
-{
- FL_OBJECT *obj;
- FD_lte_phy_scope_ue *fdui = fl_malloc( sizeof *fdui );
- // Define form
- fdui->lte_phy_scope_ue = fl_bgn_form( FL_NO_BOX, 800, 1000 );
- // This the whole UI box
- obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 1000, "" );
- fl_set_object_color( obj, FL_BLACK, FL_BLACK );
- // Received signal
- fdui->rxsig_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 20, 370, 100, "Received Signal (Time-Domain, dB)" );
- fl_set_object_boxtype( fdui->rxsig_t, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->rxsig_t, FL_BLACK, FL_RED );
- fl_set_object_lcolor( fdui->rxsig_t, FL_WHITE ); // Label color
- fl_set_xyplot_ybounds(fdui->rxsig_t,30,70);
- // Time-domain channel response
- fdui->chest_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 410, 20, 370, 100, "Channel Impulse Response (samples, abs)" );
- fl_set_object_boxtype( fdui->chest_t, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->chest_t, FL_BLACK, FL_RED );
- fl_set_object_lcolor( fdui->chest_t, FL_WHITE ); // Label color
- // Frequency-domain channel response
- fdui->chest_f = fl_add_xyplot( FL_IMPULSE_XYPLOT, 20, 140, 760, 100, "Channel Frequency Response (RE, dB)" );
- fl_set_object_boxtype( fdui->chest_f, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->chest_f, FL_BLACK, FL_RED );
- fl_set_object_lcolor( fdui->chest_f, FL_WHITE ); // Label color
- fl_set_xyplot_ybounds( fdui->chest_f,30,70);
- /*
- // LLR of PBCH
- fdui->pbch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 260, 500, 100, "PBCH Log-Likelihood Ratios (LLR, mag)" );
- fl_set_object_boxtype( fdui->pbch_llr, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pbch_llr, FL_BLACK, FL_GREEN );
- fl_set_object_lcolor( fdui->pbch_llr, FL_WHITE ); // Label color
- fl_set_xyplot_symbolsize( fdui->pbch_llr,2);
- fl_set_xyplot_xgrid( fdui->pbch_llr,FL_GRID_MAJOR);
- fl_set_xyplot_xbounds( fdui->pbch_llr,0,1920);
- // I/Q PBCH comp
- fdui->pbch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 260, 240, 100, "PBCH I/Q of MF Output" );
- fl_set_object_boxtype( fdui->pbch_comp, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pbch_comp, FL_BLACK, FL_GREEN );
- fl_set_object_lcolor( fdui->pbch_comp, FL_WHITE ); // Label color
- fl_set_xyplot_symbolsize( fdui->pbch_comp,2);
- fl_set_xyplot_xbounds( fdui->pbch_comp,-100,100);
- fl_set_xyplot_ybounds( fdui->pbch_comp,-100,100);
- // LLR of PDCCH
- fdui->pdcch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 380, 500, 100, "PDCCH Log-Likelihood Ratios (LLR, mag)" );
- fl_set_object_boxtype( fdui->pdcch_llr, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pdcch_llr, FL_BLACK, FL_CYAN );
- fl_set_object_lcolor( fdui->pdcch_llr, FL_WHITE ); // Label color
- fl_set_xyplot_symbolsize( fdui->pdcch_llr,2);
- // I/Q PDCCH comp
- fdui->pdcch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 380, 240, 100, "PDCCH I/Q of MF Output" );
- fl_set_object_boxtype( fdui->pdcch_comp, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pdcch_comp, FL_BLACK, FL_CYAN );
- fl_set_object_lcolor( fdui->pdcch_comp, FL_WHITE ); // Label color
- fl_set_xyplot_symbolsize( fdui->pdcch_comp,2);
- fl_set_xyplot_xgrid( fdui->pdcch_llr,FL_GRID_MAJOR);
- */
- int offset=240;
- // LLR of PDSCH
- fdui->pdsch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 500-offset, 500, 200, "PDSCH Log-Likelihood Ratios (LLR, mag)" );
- fl_set_object_boxtype( fdui->pdsch_llr, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pdsch_llr, FL_BLACK, FL_YELLOW );
- fl_set_object_lcolor( fdui->pdsch_llr, FL_WHITE ); // Label color
- fl_set_xyplot_symbolsize( fdui->pdsch_llr,2);
- fl_set_xyplot_xgrid( fdui->pdsch_llr,FL_GRID_MAJOR);
- // I/Q PDSCH comp
- fdui->pdsch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 500-offset, 240, 200, "PDSCH I/Q of MF Output" );
- fl_set_object_boxtype( fdui->pdsch_comp, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pdsch_comp, FL_BLACK, FL_YELLOW );
- fl_set_object_lcolor( fdui->pdsch_comp, FL_WHITE ); // Label color
- fl_set_xyplot_symbolsize( fdui->pdsch_comp,2);
- // LLR of PDSCH
- fdui->pdsch_llr1 = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 720-offset, 500, 200, "PDSCH Log-Likelihood Ratios (LLR, mag)" );
- fl_set_object_boxtype( fdui->pdsch_llr1, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pdsch_llr1, FL_BLACK, FL_YELLOW );
- fl_set_object_lcolor( fdui->pdsch_llr1, FL_WHITE ); // Label color
- fl_set_xyplot_symbolsize( fdui->pdsch_llr1,2);
- fl_set_xyplot_xgrid( fdui->pdsch_llr1,FL_GRID_MAJOR);
- // I/Q PDSCH comp
- fdui->pdsch_comp1 = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 720-offset, 240, 200, "PDSCH I/Q of MF Output" );
- fl_set_object_boxtype( fdui->pdsch_comp1, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pdsch_comp1, FL_BLACK, FL_YELLOW );
- fl_set_object_lcolor( fdui->pdsch_comp1, FL_WHITE ); // Label color
- fl_set_xyplot_symbolsize( fdui->pdsch_comp1,2);
- /*
- // Throughput on PDSCH
- fdui->pdsch_tput = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 720, 500, 100, "PDSCH Throughput [frame]/[kbit/s]" );
- fl_set_object_boxtype( fdui->pdsch_tput, FL_EMBOSSED_BOX );
- fl_set_object_color( fdui->pdsch_tput, FL_BLACK, FL_WHITE );
- fl_set_object_lcolor( fdui->pdsch_tput, FL_WHITE ); // Label color
- */
- // Generic UE Button
- fdui->button_0 = fl_add_button( FL_PUSH_BUTTON, 540, 720, 240, 40, "" );
- fl_set_object_lalign(fdui->button_0, FL_ALIGN_CENTER );
- //use_sic_receiver = 0;
- fl_set_button(fdui->button_0,0);
- fl_set_object_label(fdui->button_0, "SIC Receiver OFF");
- fl_set_object_color(fdui->button_0, FL_RED, FL_RED);
- fl_set_object_callback(fdui->button_0, sic_receiver_on_off, 0 );
- fl_hide_object(fdui->button_0);
-
- fl_end_form( );
- fdui->lte_phy_scope_ue->fdui = fdui;
- return fdui;
+FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void ) {
+ FL_OBJECT *obj;
+ FD_lte_phy_scope_ue *fdui = fl_malloc( sizeof *fdui );
+ // Define form
+ fdui->lte_phy_scope_ue = fl_bgn_form( FL_NO_BOX, 800, 1000 );
+ // This the whole UI box
+ obj = fl_add_box( FL_BORDER_BOX, 0, 0, 800, 1000, "" );
+ fl_set_object_color( obj, FL_BLACK, FL_BLACK );
+ // Received signal
+ fdui->rxsig_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 20, 370, 100, "Received Signal (Time-Domain, dB)" );
+ fl_set_object_boxtype( fdui->rxsig_t, FL_EMBOSSED_BOX );
+ fl_set_object_color( fdui->rxsig_t, FL_BLACK, FL_RED );
+ fl_set_object_lcolor( fdui->rxsig_t, FL_WHITE ); // Label color
+ fl_set_xyplot_ybounds(fdui->rxsig_t,30,70);
+ // Time-domain channel response
+ fdui->chest_t = fl_add_xyplot( FL_NORMAL_XYPLOT, 410, 20, 370, 100, "Channel Impulse Response (samples, abs)" );
+ fl_set_object_boxtype( fdui->chest_t, FL_EMBOSSED_BOX );
+ fl_set_object_color( fdui->chest_t, FL_BLACK, FL_RED );
+ fl_set_object_lcolor( fdui->chest_t, FL_WHITE ); // Label color
+ // Frequency-domain channel response
+ fdui->chest_f = fl_add_xyplot( FL_IMPULSE_XYPLOT, 20, 140, 760, 100, "Channel Frequency Response (RE, dB)" );
+ fl_set_object_boxtype( fdui->chest_f, FL_EMBOSSED_BOX );
+ fl_set_object_color( fdui->chest_f, FL_BLACK, FL_RED );
+ fl_set_object_lcolor( fdui->chest_f, FL_WHITE ); // Label color
+ fl_set_xyplot_ybounds( fdui->chest_f,30,70);
+ /*
+ // LLR of PBCH
+ fdui->pbch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 260, 500, 100, "PBCH Log-Likelihood Ratios (LLR, mag)" );
+ fl_set_object_boxtype( fdui->pbch_llr, FL_EMBOSSED_BOX );
+ fl_set_object_color( fdui->pbch_llr, FL_BLACK, FL_GREEN );
+ fl_set_object_lcolor( fdui->pbch_llr, FL_WHITE ); // Label color
+ fl_set_xyplot_symbolsize( fdui->pbch_llr,2);
+ fl_set_xyplot_xgrid( fdui->pbch_llr,FL_GRID_MAJOR);
+ fl_set_xyplot_xbounds( fdui->pbch_llr,0,1920);
+ // I/Q PBCH comp
+ fdui->pbch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 260, 240, 100, "PBCH I/Q of MF Output" );
+ fl_set_object_boxtype( fdui->pbch_comp, FL_EMBOSSED_BOX );
+ fl_set_object_color( fdui->pbch_comp, FL_BLACK, FL_GREEN );
+ fl_set_object_lcolor( fdui->pbch_comp, FL_WHITE ); // Label color
+ fl_set_xyplot_symbolsize( fdui->pbch_comp,2);
+ fl_set_xyplot_xbounds( fdui->pbch_comp,-100,100);
+ fl_set_xyplot_ybounds( fdui->pbch_comp,-100,100);
+ // LLR of PDCCH
+ fdui->pdcch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 380, 500, 100, "PDCCH Log-Likelihood Ratios (LLR, mag)" );
+ fl_set_object_boxtype( fdui->pdcch_llr, FL_EMBOSSED_BOX );
+ fl_set_object_color( fdui->pdcch_llr, FL_BLACK, FL_CYAN );
+ fl_set_object_lcolor( fdui->pdcch_llr, FL_WHITE ); // Label color
+ fl_set_xyplot_symbolsize( fdui->pdcch_llr,2);
+ // I/Q PDCCH comp
+ fdui->pdcch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 380, 240, 100, "PDCCH I/Q of MF Output" );
+ fl_set_object_boxtype( fdui->pdcch_comp, FL_EMBOSSED_BOX );
+ fl_set_object_color( fdui->pdcch_comp, FL_BLACK, FL_CYAN );
+ fl_set_object_lcolor( fdui->pdcch_comp, FL_WHITE ); // Label color
+ fl_set_xyplot_symbolsize( fdui->pdcch_comp,2);
+ fl_set_xyplot_xgrid( fdui->pdcch_llr,FL_GRID_MAJOR);
+ */
+ int offset=240;
+ // LLR of PDSCH
+ fdui->pdsch_llr = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 500-offset, 500, 200, "PDSCH Log-Likelihood Ratios (LLR, mag)" );
+ fl_set_object_boxtype( fdui->pdsch_llr, FL_EMBOSSED_BOX );
+ fl_set_object_color( fdui->pdsch_llr, FL_BLACK, FL_YELLOW );
+ fl_set_object_lcolor( fdui->pdsch_llr, FL_WHITE ); // Label color
+ fl_set_xyplot_symbolsize( fdui->pdsch_llr,2);
+ fl_set_xyplot_xgrid( fdui->pdsch_llr,FL_GRID_MAJOR);
+ // I/Q PDSCH comp
+ fdui->pdsch_comp = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 500-offset, 240, 200, "PDSCH I/Q of MF Output" );
+ fl_set_object_boxtype( fdui->pdsch_comp, FL_EMBOSSED_BOX );
+ fl_set_object_color( fdui->pdsch_comp, FL_BLACK, FL_YELLOW );
+ fl_set_object_lcolor( fdui->pdsch_comp, FL_WHITE ); // Label color
+ fl_set_xyplot_symbolsize( fdui->pdsch_comp,2);
+ // LLR of PDSCH
+ fdui->pdsch_llr1 = fl_add_xyplot( FL_POINTS_XYPLOT, 20, 720-offset, 500, 200, "PDSCH Log-Likelihood Ratios (LLR, mag)" );
+ fl_set_object_boxtype( fdui->pdsch_llr1, FL_EMBOSSED_BOX );
+ fl_set_object_color( fdui->pdsch_llr1, FL_BLACK, FL_YELLOW );
+ fl_set_object_lcolor( fdui->pdsch_llr1, FL_WHITE ); // Label color
+ fl_set_xyplot_symbolsize( fdui->pdsch_llr1,2);
+ fl_set_xyplot_xgrid( fdui->pdsch_llr1,FL_GRID_MAJOR);
+ // I/Q PDSCH comp
+ fdui->pdsch_comp1 = fl_add_xyplot( FL_POINTS_XYPLOT, 540, 720-offset, 240, 200, "PDSCH I/Q of MF Output" );
+ fl_set_object_boxtype( fdui->pdsch_comp1, FL_EMBOSSED_BOX );
+ fl_set_object_color( fdui->pdsch_comp1, FL_BLACK, FL_YELLOW );
+ fl_set_object_lcolor( fdui->pdsch_comp1, FL_WHITE ); // Label color
+ fl_set_xyplot_symbolsize( fdui->pdsch_comp1,2);
+ /*
+ // Throughput on PDSCH
+ fdui->pdsch_tput = fl_add_xyplot( FL_NORMAL_XYPLOT, 20, 720, 500, 100, "PDSCH Throughput [frame]/[kbit/s]" );
+ fl_set_object_boxtype( fdui->pdsch_tput, FL_EMBOSSED_BOX );
+ fl_set_object_color( fdui->pdsch_tput, FL_BLACK, FL_WHITE );
+ fl_set_object_lcolor( fdui->pdsch_tput, FL_WHITE ); // Label color
+ */
+ // Generic UE Button
+ fdui->button_0 = fl_add_button( FL_PUSH_BUTTON, 540, 720, 240, 40, "" );
+ fl_set_object_lalign(fdui->button_0, FL_ALIGN_CENTER );
+ //use_sic_receiver = 0;
+ fl_set_button(fdui->button_0,0);
+ fl_set_object_label(fdui->button_0, "SIC Receiver OFF");
+ fl_set_object_color(fdui->button_0, FL_RED, FL_RED);
+ fl_set_object_callback(fdui->button_0, sic_receiver_on_off, 0 );
+ fl_hide_object(fdui->button_0);
+ fl_end_form( );
+ fdui->lte_phy_scope_ue->fdui = fdui;
+ return fdui;
}
void phy_scope_UE(FD_lte_phy_scope_ue *form,
PHY_VARS_UE *phy_vars_ue,
int eNB_id,
int UE_id,
- uint8_t subframe)
-{
- int i,arx,atx,ind,k;
- LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
- int nsymb_ce = frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti;
- uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
- uint8_t nb_antennas_tx = frame_parms->nb_antenna_ports_eNB;
- int16_t **rxsig_t;
- int16_t **chest_t;
- int16_t **chest_f;
- int16_t *pdsch_llr,*pdsch_llr1;
- int16_t *pdsch_comp,*pdsch_comp1;
- int16_t *pdsch_mag0,*pdsch_mag1,*pdsch_magb0,*pdsch_magb1;
- int8_t *pdcch_llr;
- int16_t *pdcch_comp;
- int8_t *pbch_llr;
- int16_t *pbch_comp;
- float Re,Im,ymax=1;
- int num_pdcch_symbols=3;
- float *llr0, *bit0, *llr1, *bit1, *chest_f_abs, llr_pbch[1920], bit_pbch[1920], *llr_pdcch, *bit_pdcch;
- float *I, *Q;
- float rxsig_t_dB[nb_antennas_rx][FRAME_LENGTH_COMPLEX_SAMPLES];
- float **chest_t_abs;
- float time[FRAME_LENGTH_COMPLEX_SAMPLES];
- float freq[nsymb_ce*nb_antennas_rx*nb_antennas_tx];
- int frame = phy_vars_ue->proc.proc_rxtx[0].frame_rx;
- uint32_t total_dlsch_bitrate = phy_vars_ue->bitrate[eNB_id];
- int coded_bits_per_codeword0=0,coded_bits_per_codeword1=1;
- int mod0,mod1;
- int mcs0 = 0;
- int mcs1=0;
- unsigned char harq_pid = 0;
- int beamforming_mode = phy_vars_ue->transmission_mode[eNB_id]>6 ? phy_vars_ue->transmission_mode[eNB_id] : 0;
- if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]!=NULL) {
- harq_pid = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->current_harq_pid;
- if (harq_pid>=8)
- return;
- mcs0 = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->mcs;
- // Button 0
- /*
- if(!phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->dl_power_off) {
- // we are in TM5
- fl_show_object(form->button_0);
- }
- */
- }
- fl_show_object(form->button_0);
- if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]!=NULL) {
- harq_pid = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->current_harq_pid;
- if (harq_pid>=8)
- return;
- mcs1 = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->mcs;
- }
- if (phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]!=NULL) {
- num_pdcch_symbols = phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->num_pdcch_symbols;
- }
- // coded_bits_per_codeword = frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
- if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]!=NULL) {
- mod0 = get_Qm(mcs0);
- coded_bits_per_codeword0 = get_G(frame_parms,
- phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->nb_rb,
- phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even,
- get_Qm(mcs0),
- phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->Nl,
- num_pdcch_symbols,
- frame,
- subframe,
- beamforming_mode);
- } else {
- coded_bits_per_codeword0 = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
- mod0=0;
- }
- if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]!=NULL) {
- mod1 = get_Qm(mcs1);
- coded_bits_per_codeword1 = get_G(frame_parms,
- phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->nb_rb,
- phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->rb_alloc_even,
- get_Qm(mcs1),
- phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->Nl,
- num_pdcch_symbols,
- frame,
- subframe,
- beamforming_mode);
- } else {
- coded_bits_per_codeword1 = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
- mod1=0;
- }
- I = (float*) calloc(nsymb_ce*2,sizeof(float));
- Q = (float*) calloc(nsymb_ce*2,sizeof(float));
- chest_t_abs = (float**) malloc(nb_antennas_rx*sizeof(float*));
- for (arx=0;arxofdm_symbol_size,sizeof(float));
- }
- chest_f_abs = (float*) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float));
- //llr0 = (float*) calloc(coded_bits_per_codeword0,sizeof(float)); // Cppcheck returns "invalidFunctionArg" error.
- llr0 = (float*) malloc(coded_bits_per_codeword0*sizeof(float));
- memset((void *)llr0, 0,coded_bits_per_codeword0*sizeof(float)); // init to zero
- bit0 = malloc(coded_bits_per_codeword0*sizeof(float));
+ uint8_t subframe) {
+ int i,arx,atx,ind,k;
+ LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
+ int nsymb_ce = frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti;
+ uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx;
+ uint8_t nb_antennas_tx = frame_parms->nb_antenna_ports_eNB;
+ int16_t **rxsig_t;
+ int16_t **chest_t;
+ int16_t **chest_f;
+ int16_t *pdsch_llr,*pdsch_llr1;
+ int16_t *pdsch_comp,*pdsch_comp1;
+ int16_t *pdsch_mag0,*pdsch_mag1,*pdsch_magb0,*pdsch_magb1;
+ int8_t *pdcch_llr;
+ int16_t *pdcch_comp;
+ int8_t *pbch_llr;
+ int16_t *pbch_comp;
+ float Re,Im,ymax=1;
+ int num_pdcch_symbols=3;
+ float *llr0, *bit0, *llr1, *bit1, *chest_f_abs, llr_pbch[1920], bit_pbch[1920], *llr_pdcch, *bit_pdcch;
+ float *I, *Q;
+ float rxsig_t_dB[nb_antennas_rx][FRAME_LENGTH_COMPLEX_SAMPLES];
+ float **chest_t_abs;
+ float time[FRAME_LENGTH_COMPLEX_SAMPLES];
+ float freq[nsymb_ce*nb_antennas_rx*nb_antennas_tx];
+ int frame = phy_vars_ue->proc.proc_rxtx[0].frame_rx;
+ uint32_t total_dlsch_bitrate = phy_vars_ue->bitrate[eNB_id];
+ int coded_bits_per_codeword0=0,coded_bits_per_codeword1=1;
+ int mod0,mod1;
+ int mcs0 = 0;
+ int mcs1=0;
+ unsigned char harq_pid = 0;
+ int beamforming_mode = phy_vars_ue->transmission_mode[eNB_id]>6 ? phy_vars_ue->transmission_mode[eNB_id] : 0;
- //llr1 = (float*) calloc(coded_bits_per_codeword1,sizeof(float)); // Cppcheck returns "invalidFunctionArg" error.
- llr1 = (float*) malloc(coded_bits_per_codeword1*sizeof(float));
- memset((void *)llr1, 0,coded_bits_per_codeword1*sizeof(float)); // init to zero
- bit1 = malloc(coded_bits_per_codeword1*sizeof(float));
- llr_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); // init to zero
- bit_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float));
- rxsig_t = (int16_t**) phy_vars_ue->common_vars.rxdata;
- chest_t = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id];
- chest_f = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id];
- pbch_llr = (int8_t*) phy_vars_ue->pbch_vars[eNB_id]->llr;
- pbch_comp = (int16_t*) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0];
- pdcch_llr = (int8_t*) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr;
- pdcch_comp = (int16_t*) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp[0];
- pdsch_llr = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[0]; // stream 0
- pdsch_llr1 = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[1]; // stream 1
- pdsch_comp = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp0[0];
- //pdsch_comp = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_ext[0];
- //pdsch_comp1 = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_ext[1];
- pdsch_comp1 = (int16_t*) (phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp1[0][0])[0];
- //pdsch_comp1 = (int16_t*) (phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[0][0])[0];
- pdsch_mag0 = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag0[0];
- pdsch_mag1 = (int16_t*) (phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag1[0][0])[0];
- pdsch_magb0 = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_magb0[0];
- pdsch_magb1 = (int16_t*) (phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_magb1[0][0])[0];
- fl_freeze_form(form->lte_phy_scope_ue);
- // Received signal in time domain of receive antenna 0
- if (rxsig_t != NULL) {
- if (rxsig_t[0] != NULL) {
- for (i=0; irxsig_t,time,rxsig_t_dB[0],FRAME_LENGTH_COMPLEX_SAMPLES,"","","");
- }
- for (arx=1;arxrxsig_t,arx,time,rxsig_t_dB[arx],FRAME_LENGTH_COMPLEX_SAMPLES,rx_antenna_colors[arx]);
- }
- }
+ if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]!=NULL) {
+ harq_pid = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->current_harq_pid;
+
+ if (harq_pid>=8)
+ return;
+
+ mcs0 = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->mcs;
+ // Button 0
+ /*
+ if(!phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->dl_power_off) {
+ // we are in TM5
+ fl_show_object(form->button_0);
+ }
+ */
+ }
+
+ fl_show_object(form->button_0);
+
+ if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]!=NULL) {
+ harq_pid = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->current_harq_pid;
+
+ if (harq_pid>=8)
+ return;
+
+ mcs1 = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->mcs;
+ }
+
+ if (phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]!=NULL) {
+ num_pdcch_symbols = phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->num_pdcch_symbols;
+ }
+
+ // coded_bits_per_codeword = frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
+ if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]!=NULL) {
+ mod0 = get_Qm(mcs0);
+ coded_bits_per_codeword0 = get_G(frame_parms,
+ phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->nb_rb,
+ phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even,
+ get_Qm(mcs0),
+ phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->Nl,
+ num_pdcch_symbols,
+ frame,
+ subframe,
+ beamforming_mode);
+ } else {
+ coded_bits_per_codeword0 = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
+ mod0=0;
+ }
+
+ if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]!=NULL) {
+ mod1 = get_Qm(mcs1);
+ coded_bits_per_codeword1 = get_G(frame_parms,
+ phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->nb_rb,
+ phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->rb_alloc_even,
+ get_Qm(mcs1),
+ phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->Nl,
+ num_pdcch_symbols,
+ frame,
+ subframe,
+ beamforming_mode);
+ } else {
+ coded_bits_per_codeword1 = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
+ mod1=0;
+ }
+
+ I = (float *) calloc(nsymb_ce*2,sizeof(float));
+ Q = (float *) calloc(nsymb_ce*2,sizeof(float));
+ chest_t_abs = (float **) malloc(nb_antennas_rx*sizeof(float *));
+
+ for (arx=0; arxofdm_symbol_size,sizeof(float));
+ }
+
+ chest_f_abs = (float *) calloc(nsymb_ce*nb_antennas_rx*nb_antennas_tx,sizeof(float));
+ //llr0 = (float*) calloc(coded_bits_per_codeword0,sizeof(float)); // Cppcheck returns "invalidFunctionArg" error.
+ llr0 = (float *) malloc(coded_bits_per_codeword0*sizeof(float));
+ memset((void *)llr0, 0,coded_bits_per_codeword0*sizeof(float)); // init to zero
+ bit0 = malloc(coded_bits_per_codeword0*sizeof(float));
+ //llr1 = (float*) calloc(coded_bits_per_codeword1,sizeof(float)); // Cppcheck returns "invalidFunctionArg" error.
+ llr1 = (float *) malloc(coded_bits_per_codeword1*sizeof(float));
+ memset((void *)llr1, 0,coded_bits_per_codeword1*sizeof(float)); // init to zero
+ bit1 = malloc(coded_bits_per_codeword1*sizeof(float));
+ llr_pdcch = (float *) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); // init to zero
+ bit_pdcch = (float *) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float));
+ rxsig_t = (int16_t **) phy_vars_ue->common_vars.rxdata;
+ chest_t = (int16_t **) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id];
+ chest_f = (int16_t **) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id];
+ pbch_llr = (int8_t *) phy_vars_ue->pbch_vars[eNB_id]->llr;
+ pbch_comp = (int16_t *) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0];
+ pdcch_llr = (int8_t *) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr;
+ pdcch_comp = (int16_t *) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp[0];
+ pdsch_llr = (int16_t *) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[0]; // stream 0
+ pdsch_llr1 = (int16_t *) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[1]; // stream 1
+ pdsch_comp = (int16_t *) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp0[0];
+ //pdsch_comp = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_ext[0];
+ //pdsch_comp1 = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_ext[1];
+ pdsch_comp1 = (int16_t *) (phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp1[0][0])[0];
+ //pdsch_comp1 = (int16_t*) (phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[0][0])[0];
+ pdsch_mag0 = (int16_t *) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag0[0];
+ pdsch_mag1 = (int16_t *) (phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag1[0][0])[0];
+ pdsch_magb0 = (int16_t *) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_magb0[0];
+ pdsch_magb1 = (int16_t *) (phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_magb1[0][0])[0];
+ fl_freeze_form(form->lte_phy_scope_ue);
+
+ // Received signal in time domain of receive antenna 0
+ if (rxsig_t != NULL) {
+ if (rxsig_t[0] != NULL) {
+ for (i=0; irxsig_t,time,rxsig_t_dB[0],FRAME_LENGTH_COMPLEX_SAMPLES,"","","");
}
+
+ for (arx=1; arxrxsig_t,arx,time,rxsig_t_dB[arx],FRAME_LENGTH_COMPLEX_SAMPLES,rx_antenna_colors[arx]);
+ }
+ }
+ }
+
// Channel Impulse Response (still repeated format)
if (chest_t != NULL) {
ymax = 0;
+
if (chest_t[0] !=NULL) {
for (i=0; i<(frame_parms->ofdm_symbol_size>>3); i++) {
chest_t_abs[0][i] = (float) (chest_t[0][4*i]*chest_t[0][4*i]+chest_t[0][4*i+1]*chest_t[0][4*i+1]);
+
if (chest_t_abs[0][i] > ymax)
ymax = chest_t_abs[0][i];
}
+
fl_set_xyplot_data(form->chest_t,time,chest_t_abs[0],(frame_parms->ofdm_symbol_size>>3),"","","");
}
+
for (arx=1; arxofdm_symbol_size>>3); i++) {
chest_t_abs[arx][i] = (float) (chest_t[arx][4*i]*chest_t[arx][4*i]+chest_t[arx][4*i+1]*chest_t[arx][4*i+1]);
+
if (chest_t_abs[arx][i] > ymax)
ymax = chest_t_abs[arx][i];
}
+
fl_add_xyplot_overlay(form->chest_t,arx,time,chest_t_abs[arx],(frame_parms->ofdm_symbol_size>>3),rx_antenna_colors[arx]);
fl_set_xyplot_overlay_type(form->chest_t,arx,FL_DASHED_XYPLOT);
}
}
- // Avoid flickering effect
- // fl_get_xyplot_ybounds(form->chest_t,&ymin,&ymax);
- fl_set_xyplot_ybounds(form->chest_t,0,ymax);
+
+ // Avoid flickering effect
+ // fl_get_xyplot_ybounds(form->chest_t,&ymin,&ymax);
+ fl_set_xyplot_ybounds(form->chest_t,0,ymax);
+ }
+
+ // Channel Frequency Response (includes 5 complex sample for filter)
+ if (chest_f != NULL) {
+ ind = 0;
+
+ for (atx=0; atxchest_f,0,nb_antennas_rx*nb_antennas_tx*nsymb_ce);
- //fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*frame_parms->symbols_per_tti,2);
- // fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*2,2);
- fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR);
- fl_set_xyplot_data(form->chest_f,freq,chest_f_abs,nsymb_ce,"","","");
- for (arx=1;arxchest_f,1,&freq[arx*nsymb_ce],&chest_f_abs[arx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
- }
- // other tx antennas
- if (nb_antennas_tx > 1) {
- if (nb_antennas_rx > 1) {
- for (atx=1;atxchest_f,(atx<<1)+arx,&freq[((atx<<1)+arx)*nsymb_ce],&chest_f_abs[((atx<<1)+arx)*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
- }
- }
- } else { // 1 rx antenna
- atx=1; arx=0;
- fl_add_xyplot_overlay(form->chest_f,atx,&freq[atx*nsymb_ce],&chest_f_abs[atx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
- }
- }
+
+ // tx antenna 0
+ fl_set_xyplot_xbounds(form->chest_f,0,nb_antennas_rx*nb_antennas_tx*nsymb_ce);
+ //fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*frame_parms->symbols_per_tti,2);
+ // fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*2,2);
+ fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR);
+ fl_set_xyplot_data(form->chest_f,freq,chest_f_abs,nsymb_ce,"","","");
+
+ for (arx=1; arxchest_f,1,&freq[arx*nsymb_ce],&chest_f_abs[arx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
}
- /*
- // PBCH LLRs
- if (pbch_llr != NULL) {
- for (i=0; i<1920;i++) {
- llr_pbch[i] = (float) pbch_llr[i];
- bit_pbch[i] = (float) i;
+
+ // other tx antennas
+ if (nb_antennas_tx > 1) {
+ if (nb_antennas_rx > 1) {
+ for (atx=1; atxchest_f,(atx<<1)+arx,&freq[((atx<<1)+arx)*nsymb_ce],&chest_f_abs[((atx<<1)+arx)*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
+ }
}
- fl_set_xyplot_data(form->pbch_llr,bit_pbch,llr_pbch,1920,"","","");
+ } else { // 1 rx antenna
+ atx=1;
+ arx=0;
+ fl_add_xyplot_overlay(form->chest_f,atx,&freq[atx*nsymb_ce],&chest_f_abs[atx*nsymb_ce],nsymb_ce,rx_antenna_colors[arx]);
+ }
}
- // PBCH I/Q of MF Output
- if (pbch_comp!=NULL) {
- for (i=0; i<72*2; i++) {
- I[i] = pbch_comp[2*i];
- Q[i] = pbch_comp[2*i+1];
- }
- fl_set_xyplot_data(form->pbch_comp,I,Q,72*2,"","","");
- }
- // PDCCH LLRs
- if (pdcch_llr != NULL) {
- for (i=0; i<12*frame_parms->N_RB_DL*2*num_pdcch_symbols;i++) {
- llr_pdcch[i] = (float) pdcch_llr[i];
- bit_pdcch[i] = (float) i;
- }
- fl_set_xyplot_xbounds(form->pdcch_llr,0,12*frame_parms->N_RB_DL*2*3);
- fl_set_xyplot_data(form->pdcch_llr,bit_pdcch,llr_pdcch,12*frame_parms->N_RB_DL*2*num_pdcch_symbols,"","","");
- }
- // PDCCH I/Q of MF Output
- if (pdcch_comp!=NULL) {
- for (i=0; i<12*frame_parms->N_RB_DL*num_pdcch_symbols; i++) {
- I[i] = pdcch_comp[2*i];
- Q[i] = pdcch_comp[2*i+1];
- }
- fl_set_xyplot_data(form->pdcch_comp,I,Q,12*frame_parms->N_RB_DL*num_pdcch_symbols,"","","");
- }
- */
- // PDSCH LLRs CW0
- if (pdsch_llr != NULL) {
- for (i=0; ipdsch_llr,0,coded_bits_per_codeword0);
- fl_set_xyplot_data(form->pdsch_llr,bit0,llr0,coded_bits_per_codeword0,"","","");
+ }
+
+ /*
+ // PBCH LLRs
+ if (pbch_llr != NULL) {
+ for (i=0; i<1920;i++) {
+ llr_pbch[i] = (float) pbch_llr[i];
+ bit_pbch[i] = (float) i;
+ }
+ fl_set_xyplot_data(form->pbch_llr,bit_pbch,llr_pbch,1920,"","","");
+ }
+ // PBCH I/Q of MF Output
+ if (pbch_comp!=NULL) {
+ for (i=0; i<72*2; i++) {
+ I[i] = pbch_comp[2*i];
+ Q[i] = pbch_comp[2*i+1];
+ }
+ fl_set_xyplot_data(form->pbch_comp,I,Q,72*2,"","","");
+ }
+ // PDCCH LLRs
+ if (pdcch_llr != NULL) {
+ for (i=0; i<12*frame_parms->N_RB_DL*2*num_pdcch_symbols;i++) {
+ llr_pdcch[i] = (float) pdcch_llr[i];
+ bit_pdcch[i] = (float) i;
+ }
+ fl_set_xyplot_xbounds(form->pdcch_llr,0,12*frame_parms->N_RB_DL*2*3);
+ fl_set_xyplot_data(form->pdcch_llr,bit_pdcch,llr_pdcch,12*frame_parms->N_RB_DL*2*num_pdcch_symbols,"","","");
+ }
+ // PDCCH I/Q of MF Output
+ if (pdcch_comp!=NULL) {
+ for (i=0; i<12*frame_parms->N_RB_DL*num_pdcch_symbols; i++) {
+ I[i] = pdcch_comp[2*i];
+ Q[i] = pdcch_comp[2*i+1];
+ }
+ fl_set_xyplot_data(form->pdcch_comp,I,Q,12*frame_parms->N_RB_DL*num_pdcch_symbols,"","","");
+ }
+ */
+ // PDSCH LLRs CW0
+ if (pdsch_llr != NULL) {
+ for (i=0; ipdsch_llr,0,coded_bits_per_codeword0);
+ fl_set_xyplot_data(form->pdsch_llr,bit0,llr0,coded_bits_per_codeword0,"","","");
+ }
+
// PDSCH I/Q of MF Output
- if (pdsch_comp!=NULL) {
- ind=0;
- for (k=0; ksymbols_per_tti; k++) {
- for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
- I[ind] = pdsch_comp[(2*frame_parms->N_RB_DL*12*k)+4*i];
- Q[ind] = pdsch_comp[(2*frame_parms->N_RB_DL*12*k)+4*i+1];
- ind++;
- }
- }
- fl_set_xyplot_data(form->pdsch_comp,I,Q,ind,"","","");
+ if (pdsch_comp!=NULL) {
+ ind=0;
+
+ for (k=0; ksymbols_per_tti; k++) {
+ for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
+ I[ind] = pdsch_comp[(2*frame_parms->N_RB_DL*12*k)+4*i];
+ Q[ind] = pdsch_comp[(2*frame_parms->N_RB_DL*12*k)+4*i+1];
+ ind++;
+ }
}
- if (pdsch_mag0 != NULL) {
- ind=0;
- for (k=0; ksymbols_per_tti; k++) {
- for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
+
+ fl_set_xyplot_data(form->pdsch_comp,I,Q,ind,"","","");
+ }
+
+ if (pdsch_mag0 != NULL) {
+ ind=0;
+
+ for (k=0; ksymbols_per_tti; k++) {
+ for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
I[ind] = pdsch_mag0[(2*frame_parms->N_RB_DL*12*k)+4*i]*cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
Q[ind] = pdsch_mag0[(2*frame_parms->N_RB_DL*12*k)+4*i+1]*sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
ind++;
- }
- }
- fl_add_xyplot_overlay(form->pdsch_comp,1,I,Q,ind,FL_GREEN);
+ }
}
- if (pdsch_magb0 != NULL) {
- ind=0;
- for (k=0; ksymbols_per_tti; k++) {
- for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
+
+ fl_add_xyplot_overlay(form->pdsch_comp,1,I,Q,ind,FL_GREEN);
+ }
+
+ if (pdsch_magb0 != NULL) {
+ ind=0;
+
+ for (k=0; ksymbols_per_tti; k++) {
+ for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
I[ind] = pdsch_magb0[(2*frame_parms->N_RB_DL*12*k)+4*i]*cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
Q[ind] = pdsch_magb0[(2*frame_parms->N_RB_DL*12*k)+4*i+1]*sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
ind++;
- }
- }
- fl_add_xyplot_overlay(form->pdsch_comp,2,I,Q,ind,FL_RED);
+ }
}
- if ((pdsch_mag0 != NULL) && (pdsch_magb0 != NULL)) {
- ind=0;
- for (k=0; ksymbols_per_tti; k++) {
- for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
+
+ fl_add_xyplot_overlay(form->pdsch_comp,2,I,Q,ind,FL_RED);
+ }
+
+ if ((pdsch_mag0 != NULL) && (pdsch_magb0 != NULL)) {
+ ind=0;
+
+ for (k=0; ksymbols_per_tti; k++) {
+ for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
I[ind] =
- (pdsch_mag0[(2*frame_parms->N_RB_DL*12*k)+4*i]+
- pdsch_magb0[(2*frame_parms->N_RB_DL*12*k)+4*i])*
- cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
+ (pdsch_mag0[(2*frame_parms->N_RB_DL*12*k)+4*i]+
+ pdsch_magb0[(2*frame_parms->N_RB_DL*12*k)+4*i])*
+ cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
Q[ind] =
- (pdsch_mag0[(2*frame_parms->N_RB_DL*12*k)+4*i+1]+
- pdsch_magb0[(2*frame_parms->N_RB_DL*12*k)+4*i+1])*
- sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
+ (pdsch_mag0[(2*frame_parms->N_RB_DL*12*k)+4*i+1]+
+ pdsch_magb0[(2*frame_parms->N_RB_DL*12*k)+4*i+1])*
+ sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
ind++;
- }
- }
- fl_add_xyplot_overlay(form->pdsch_comp,3,I,Q,ind,FL_BLUE);
+ }
}
- // PDSCH LLRs CW1
- if (pdsch_llr1 != NULL) {
- for (i=0; ipdsch_llr1,0,coded_bits_per_codeword1);
- fl_set_xyplot_data(form->pdsch_llr1,bit1,llr1,coded_bits_per_codeword1,"","","");
+
+ fl_add_xyplot_overlay(form->pdsch_comp,3,I,Q,ind,FL_BLUE);
+ }
+
+ // PDSCH LLRs CW1
+ if (pdsch_llr1 != NULL) {
+ for (i=0; isymbols_per_tti; k++) {
- for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
- I[ind] = pdsch_comp1[(2*frame_parms->N_RB_DL*12*k)+4*i];
- Q[ind] = pdsch_comp1[(2*frame_parms->N_RB_DL*12*k)+4*i+1];
- ind++;
- }
- }
- fl_set_xyplot_data(form->pdsch_comp1,I,Q,ind,"","","");
+
+ fl_set_xyplot_xbounds(form->pdsch_llr1,0,coded_bits_per_codeword1);
+ fl_set_xyplot_data(form->pdsch_llr1,bit1,llr1,coded_bits_per_codeword1,"","","");
+ }
+
+ // PDSCH I/Q of MF Output
+ if (pdsch_comp1!=NULL) {
+ ind=0;
+
+ for (k=0; ksymbols_per_tti; k++) {
+ for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
+ I[ind] = pdsch_comp1[(2*frame_parms->N_RB_DL*12*k)+4*i];
+ Q[ind] = pdsch_comp1[(2*frame_parms->N_RB_DL*12*k)+4*i+1];
+ ind++;
+ }
}
- if (pdsch_mag1 != NULL) {
- ind=0;
- for (k=0; ksymbols_per_tti; k++) {
- for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
+
+ fl_set_xyplot_data(form->pdsch_comp1,I,Q,ind,"","","");
+ }
+
+ if (pdsch_mag1 != NULL) {
+ ind=0;
+
+ for (k=0; ksymbols_per_tti; k++) {
+ for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
I[ind] = pdsch_mag1[(2*frame_parms->N_RB_DL*12*k)+4*i]*cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
Q[ind] = pdsch_mag1[(2*frame_parms->N_RB_DL*12*k)+4*i+1]*sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
ind++;
- }
- }
- fl_add_xyplot_overlay(form->pdsch_comp1,1,I,Q,ind,FL_GREEN);
+ }
}
- if (pdsch_magb1 != NULL) {
- ind=0;
- for (k=0; ksymbols_per_tti; k++) {
- for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
+
+ fl_add_xyplot_overlay(form->pdsch_comp1,1,I,Q,ind,FL_GREEN);
+ }
+
+ if (pdsch_magb1 != NULL) {
+ ind=0;
+
+ for (k=0; ksymbols_per_tti; k++) {
+ for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
I[ind] = pdsch_magb1[(2*frame_parms->N_RB_DL*12*k)+4*i]*cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
Q[ind] = pdsch_magb1[(2*frame_parms->N_RB_DL*12*k)+4*i+1]*sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
ind++;
- }
- }
- fl_add_xyplot_overlay(form->pdsch_comp1,2,I,Q,ind,FL_RED);
+ }
}
- if ((pdsch_mag1 != NULL) && (pdsch_magb1 != NULL)) {
- ind=0;
- for (k=0; ksymbols_per_tti; k++) {
- for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
+
+ fl_add_xyplot_overlay(form->pdsch_comp1,2,I,Q,ind,FL_RED);
+ }
+
+ if ((pdsch_mag1 != NULL) && (pdsch_magb1 != NULL)) {
+ ind=0;
+
+ for (k=0; ksymbols_per_tti; k++) {
+ for (i=0; i<12*frame_parms->N_RB_DL/2; i++) {
I[ind] =
- (pdsch_mag1[(2*frame_parms->N_RB_DL*12*k)+4*i]+
- pdsch_magb1[(2*frame_parms->N_RB_DL*12*k)+4*i])*
- cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
+ (pdsch_mag1[(2*frame_parms->N_RB_DL*12*k)+4*i]+
+ pdsch_magb1[(2*frame_parms->N_RB_DL*12*k)+4*i])*
+ cos(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
Q[ind] =
- (pdsch_mag1[(2*frame_parms->N_RB_DL*12*k)+4*i+1]+
- pdsch_magb1[(2*frame_parms->N_RB_DL*12*k)+4*i+1])*
- sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
+ (pdsch_mag1[(2*frame_parms->N_RB_DL*12*k)+4*i+1]+
+ pdsch_magb1[(2*frame_parms->N_RB_DL*12*k)+4*i+1])*
+ sin(i*2*M_PI/(12*frame_parms->N_RB_DL/2));
ind++;
- }
- }
- fl_add_xyplot_overlay(form->pdsch_comp1,3,I,Q,ind,FL_BLUE);
+ }
}
- /*
- // PDSCH Throughput
- memcpy((void*)tput_time_ue[UE_id],(void*)&tput_time_ue[UE_id][1],(TPUT_WINDOW_LENGTH-1)*sizeof(float));
- memcpy((void*)tput_ue[UE_id],(void*)&tput_ue[UE_id][1],(TPUT_WINDOW_LENGTH-1)*sizeof(float));
- tput_time_ue[UE_id][TPUT_WINDOW_LENGTH-1] = (float) frame;
- tput_ue[UE_id][TPUT_WINDOW_LENGTH-1] = ((float) total_dlsch_bitrate)/1000.0;
- if (tput_ue[UE_id][TPUT_WINDOW_LENGTH-1] > tput_ue_max[UE_id]) {
- tput_ue_max[UE_id] = tput_ue[UE_id][TPUT_WINDOW_LENGTH-1];
- }
- fl_set_xyplot_data(form->pdsch_tput,tput_time_ue[UE_id],tput_ue[UE_id],TPUT_WINDOW_LENGTH,"","","");
- fl_set_xyplot_ybounds(form->pdsch_tput,0,tput_ue_max[UE_id]);
- */
- fl_unfreeze_form(form->lte_phy_scope_ue);
- fl_check_forms();
- free(I);
- free(Q);
- free(chest_f_abs);
- free(llr0);
- free(bit0);
- free(llr1);
- free(bit1);
- free(bit_pdcch);
- free(llr_pdcch);
- //This is done to avoid plotting old data when TB0 is disabled, and TB1 is mapped onto CW0
- /*if (phy_vars_ue->transmission_mode[eNB_id]==3 && phy_vars_ue->transmission_mode[eNB_id]==4){
- for (int i = 0; i<8; ++i)
- for (int j = 0; j < 7*2*frame_parms->N_RB_DL*12+4; ++j )
- phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[0][0][i][j]=0;
+ fl_add_xyplot_overlay(form->pdsch_comp1,3,I,Q,ind,FL_BLUE);
+ }
- for (int m=0; mpdsch_vars[subframe&0x1][eNB_id]->llr[0][m]=0;
- }*/
+ /*
+ // PDSCH Throughput
+ memcpy((void*)tput_time_ue[UE_id],(void*)&tput_time_ue[UE_id][1],(TPUT_WINDOW_LENGTH-1)*sizeof(float));
+ memcpy((void*)tput_ue[UE_id],(void*)&tput_ue[UE_id][1],(TPUT_WINDOW_LENGTH-1)*sizeof(float));
+ tput_time_ue[UE_id][TPUT_WINDOW_LENGTH-1] = (float) frame;
+ tput_ue[UE_id][TPUT_WINDOW_LENGTH-1] = ((float) total_dlsch_bitrate)/1000.0;
+ if (tput_ue[UE_id][TPUT_WINDOW_LENGTH-1] > tput_ue_max[UE_id]) {
+ tput_ue_max[UE_id] = tput_ue[UE_id][TPUT_WINDOW_LENGTH-1];
+ }
+ fl_set_xyplot_data(form->pdsch_tput,tput_time_ue[UE_id],tput_ue[UE_id],TPUT_WINDOW_LENGTH,"","","");
+ fl_set_xyplot_ybounds(form->pdsch_tput,0,tput_ue_max[UE_id]);
+ */
+ fl_unfreeze_form(form->lte_phy_scope_ue);
+ fl_check_forms();
+ free(I);
+ free(Q);
+ free(chest_f_abs);
+ free(llr0);
+ free(bit0);
+ free(llr1);
+ free(bit1);
+ free(bit_pdcch);
+ free(llr_pdcch);
+ //This is done to avoid plotting old data when TB0 is disabled, and TB1 is mapped onto CW0
+ /*if (phy_vars_ue->transmission_mode[eNB_id]==3 && phy_vars_ue->transmission_mode[eNB_id]==4){
+ for (int i = 0; i<8; ++i)
+ for (int j = 0; j < 7*2*frame_parms->N_RB_DL*12+4; ++j )
+ phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[0][0][i][j]=0;
+
+ for (int m=0; mpdsch_vars[subframe&0x1][eNB_id]->llr[0][m]=0;
+ }*/
}
diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c
index b45c1abf0b..90a252dc98 100644
--- a/openair1/PHY/TOOLS/nr_phy_scope.c
+++ b/openair1/PHY/TOOLS/nr_phy_scope.c
@@ -38,10 +38,7 @@ int otg_enabled;
const FL_COLOR rx_antenna_colors[4] = {FL_RED,FL_BLUE,FL_GREEN,FL_YELLOW};
const FL_COLOR water_colors[4] = {FL_BLUE,FL_GREEN,FL_YELLOW,FL_RED};
-typedef struct {
- int16_t r;
- int16_t i;
-} scopeSample_t;
+typedef struct complex16 scopeSample_t;
#define SquaredNorm(VaR) ((VaR).r*(VaR).r+(VaR).i*(VaR).i)
typedef struct OAIgraph {
@@ -59,7 +56,7 @@ typedef struct OAIgraph {
double *waterFallAvg;
boolean_t initDone;
int iteration;
- void (*gNBfunct) (struct OAIgraph *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id);
+ void (*gNBfunct) (struct OAIgraph *graph, scopeData_t *p, int UE_id);
void (*nrUEfunct)(struct OAIgraph *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id);
} OAIgraph_t;
@@ -135,7 +132,7 @@ static void commonGraph(OAIgraph_t *graph, int type, FL_Coord x, FL_Coord y, FL_
graph->iteration=0;
}
-static OAIgraph_t gNBcommonGraph( void (*funct) (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int UE_id),
+static OAIgraph_t gNBcommonGraph( void (*funct) (OAIgraph_t *graph, scopeData_t *p, int UE_id),
int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor) {
OAIgraph_t graph;
commonGraph(&graph, type, x, y, w, h, label, pointColor);
@@ -226,7 +223,8 @@ static void oai_xygraph(OAIgraph_t *graph, float *x, float *y, int len, int laye
static void genericWaterFall (OAIgraph_t *graph, scopeSample_t *values, const int datasize, const int divisions, const char *label) {
if ( values == NULL )
- return;
+ return;
+
fl_winset(FL_ObjWin(graph->graph));
const int samplesPerPixel=datasize/graph->w;
int displayPart=graph->waterFallh-ScaleZone;
@@ -242,7 +240,7 @@ static void genericWaterFall (OAIgraph_t *graph, scopeSample_t *values, const in
for (int pix=0; pixw; pix++) {
scopeSample_t *end=values+(pix+1)*samplesPerPixel;
end-=2;
- AssertFatal(end <= values+datasize,"diff : %ld", end-values+datasize);
+ AssertFatal(end <= values+datasize,"diff : %u", end-values+datasize);
double val=0;
for (scopeSample_t *s=values+(pix)*samplesPerPixel;
@@ -278,7 +276,7 @@ static void genericWaterFall (OAIgraph_t *graph, scopeSample_t *values, const in
graph->initDone=true;
}
- fl_set_object_label_f(graph->text, "%s, avg I/Q pow: %4.1f", label, sqrt(avg));
+ fl_set_object_label_f(graph->text, "%s, avg I/Q pow: %4.1f", label, 0/*sqrt(avg)*/);
graph->iteration++;
}
@@ -297,10 +295,10 @@ static void genericPowerPerAntena(OAIgraph_t *graph, const int nb_ant, const sc
}
}
-static void gNBWaterFall (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
- NR_DL_FRAME_PARMS *frame_parms=&phy_vars_gnb->frame_parms;
+static void gNBWaterFall (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
+ NR_DL_FRAME_PARMS *frame_parms=&p->gNB->frame_parms;
//use 1st antenna
- genericWaterFall(graph, (scopeSample_t *)phy_vars_ru->common.rxdata[0],
+ genericWaterFall(graph, (scopeSample_t *)p->ru->common.rxdata[0],
frame_parms->samples_per_frame, frame_parms->slots_per_frame,
"X axis:one frame in time");
}
@@ -318,31 +316,35 @@ static void timeSignal (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy
}
*/
-static void timeResponse (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
- const int len=2*phy_vars_gnb->frame_parms.ofdm_symbol_size;
+static void timeResponse (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
+ const int len=2*p->gNB->frame_parms.ofdm_symbol_size;
float *values, *time;
oai_xygraph_getbuff(graph, &time, &values, len, 0);
const int ant=0; // display antenna 0 for each UE
for (int ue=0; uepusch_vars[ue]->ul_ch_estimates_time[ant];
+ if ( p->gNB->pusch_vars && p->gNB->pusch_vars[ue] &&
+ p->gNB->pusch_vars[ue]->ul_ch_estimates_time &&
+ p->gNB->pusch_vars[ue]->ul_ch_estimates_time[ant] ) {
+ scopeSample_t *data= (scopeSample_t *)p->gNB->pusch_vars[ue]->ul_ch_estimates_time[ant];
- if (data != NULL) {
- for (int i=0; iframe_parms;
+static void gNBfreqWaterFall (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
+ NR_DL_FRAME_PARMS *frame_parms=&p->gNB->frame_parms;
//use 1st antenna
- genericWaterFall(graph, (scopeSample_t *)phy_vars_ru->common.rxdataF[0], frame_parms->samples_per_frame_wCP,
+ genericWaterFall(graph, (scopeSample_t *)p->rxdataF, frame_parms->samples_per_frame_wCP,
frame_parms->slots_per_frame,
- "X axis: Frequency domain, one frame");
+ "X axis: Frequency domain, one subframe");
}
/*
@@ -354,16 +356,18 @@ static void frequencyResponse (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU
}
*/
-static void puschLLR (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
+static void puschLLR (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
//int Qm = 2;
int coded_bits_per_codeword =3*8*6144+12; // (8*((3*8*6144)+12)); // frame_parms->N_RB_UL*12*Qm*frame_parms->symbols_per_tti;
for (int ue=0; uepusch_vars[ue]->llr;
- float *llr, *bit;
- oai_xygraph_getbuff(graph, &bit, &llr, coded_bits_per_codeword, ue);
+ if ( p->gNB->pusch_vars &&
+ p->gNB->pusch_vars[ue] &&
+ p->gNB->pusch_vars[ue]->llr ) {
+ int16_t *pusch_llr = (int16_t *)p->gNB->pusch_vars[ue]->llr;
+ float *llr, *bit;
+ oai_xygraph_getbuff(graph, &bit, &llr, coded_bits_per_codeword, ue);
- if (pusch_llr) {
for (int i=0; iframe_parms;
+static void puschIQ (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
+ NR_DL_FRAME_PARMS *frame_parms=&p->gNB->frame_parms;
int sz=frame_parms->N_RB_UL*12*frame_parms->symbols_per_slot;
for (int ue=0; uepusch_vars[ue]->rxdataF_comp[0];
- float *I, *Q;
- oai_xygraph_getbuff(graph, &I, &Q, sz, ue);
+ if ( p->gNB->pusch_vars &&
+ p->gNB->pusch_vars[ue] &&
+ p->gNB->pusch_vars[ue]->rxdataF_comp &&
+ p->gNB->pusch_vars[ue]->rxdataF_comp[0] ) {
+ scopeSample_t *pusch_comp = (scopeSample_t *) p->gNB->pusch_vars[ue]->rxdataF_comp[0];
+ float *I, *Q;
+ oai_xygraph_getbuff(graph, &I, &Q, sz, ue);
- if (pusch_comp) {
for (int k=0; kpucch1ab_stats[UE_id];
@@ -419,10 +426,10 @@ static void pucchEnergy (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *ph
*/
}
-static void pucchIQ (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
+static void pucchIQ (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
}
-static void puschThroughtput (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_t *phy_vars_ru, int nb_UEs) {
+static void puschThroughtput (OAIgraph_t *graph, scopeData_t *p, int nb_UEs) {
// PUSCH Throughput
/*
float tput_time_enb[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
@@ -437,7 +444,6 @@ static void puschThroughtput (OAIgraph_t *graph, PHY_VARS_gNB *phy_vars_gnb, RU_
// fl_set_xyplot_ybounds(form->pusch_tput,0,ymax);
*/
}
-
static OAI_phy_scope_t *create_phy_scope_gnb(void) {
FL_OBJECT *obj;
OAI_phy_scope_t *fdui = calloc(( sizeof *fdui ),1);
@@ -486,11 +492,9 @@ static OAI_phy_scope_t *create_phy_scope_gnb(void) {
fl_show_form (fdui->phy_scope, FL_PLACE_HOTSPOT, FL_FULLBORDER, "LTE UL SCOPE gNB");
return fdui;
}
-
static const int scope_enb_num_ue = 1;
void phy_scope_gNB(OAI_phy_scope_t *form,
- PHY_VARS_gNB *phy_vars_gnb,
- RU_t *phy_vars_ru,
+ scopeData_t *p,
int UE_id) {
static OAI_phy_scope_t *rememberForm=NULL;
@@ -505,15 +509,14 @@ void phy_scope_gNB(OAI_phy_scope_t *form,
int i=0;
while (form->graph[i].graph) {
- form->graph[i].gNBfunct(form->graph+i, phy_vars_gnb, phy_vars_ru, UE_id);
+ form->graph[i].gNBfunct(form->graph+i, p, UE_id);
i++;
}
//fl_check_forms();
}
-
static void *scope_thread_gNB(void *arg) {
- scopeParms_t *p=(scopeParms_t *) arg;
+ scopeData_t *p=(scopeData_t *) arg;
//# ifdef ENABLE_XFORMS_WRITE_STATS
// FILE *gNB_stats = fopen("gNB_stats.txt", "w");
//#endif
@@ -530,20 +533,31 @@ static void *scope_thread_gNB(void *arg) {
OAI_phy_scope_t *form_gnb = create_phy_scope_gnb();
while (!oai_exit) {
- phy_scope_gNB(form_gnb, p->gNB, p->ru, nb_ue);
+ phy_scope_gNB(form_gnb, p, nb_ue);
usleep(99*1000);
}
return NULL;
}
-
-void gNBinitScope(scopeParms_t *p) {
- static scopeParms_t parms;
- memcpy(&parms,p,sizeof(parms));
- pthread_t forms_thread;
- threadCreate(&forms_thread, scope_thread_gNB, &parms, "scope", -1, OAI_PRIORITY_RT_LOW);
+static void copyRxdataF(int32_t *data, int slot, void *scopeData) {
+ scopeData_t *scope=(scopeData_t *)scopeData;
+ memcpy(scope->rxdataF + slot*scope->gNB->frame_parms.samples_per_slot_wCP,
+ data,
+ scope->gNB->frame_parms.samples_per_slot_wCP);
}
+void gNBinitScope(scopeParms_t *p) {
+ AssertFatal(p->gNB->scopeData=malloc(sizeof(scopeData_t)),"");
+ scopeData_t *scope=(scopeData_t *) p->gNB->scopeData;
+ scope->argc=p->argc;
+ scope->argv=p->argv;
+ scope->ru=p->ru;
+ scope->gNB=p->gNB;
+ scope->slotFunc=copyRxdataF;
+ AssertFatal(scope->rxdataF=(int32_t *) calloc(p->gNB->frame_parms.samples_per_frame_wCP*sizeof(int32_t),1),"");
+ pthread_t forms_thread;
+ threadCreate(&forms_thread, scope_thread_gNB, p->gNB->scopeData, "scope", -1, OAI_PRIORITY_RT_LOW);
+}
static void ueWaterFall (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
// Received signal in time domain of receive antenna 0
genericWaterFall(graph,
@@ -552,7 +566,6 @@ static void ueWaterFall (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eN
phy_vars_ue->frame_parms.slots_per_frame,
"X axis: one frame time");
}
-
/* replaced by waterfall
static void ueTimeResponse (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
// Received signal in time domain of receive antenna 0
@@ -561,14 +574,12 @@ static void ueTimeResponse (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int
phy_vars_ue->frame_parms.samples_per_frame);
}
*/
-
static void ueChannelResponse (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
// Channel Impulse Response
genericPowerPerAntena(graph, phy_vars_ue->frame_parms.nb_antennas_rx,
(const scopeSample_t **) phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates_time,
phy_vars_ue->frame_parms.ofdm_symbol_size>>3);
}
-
static void ueFreqWaterFall (OAIgraph_t *graph,PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id ) {
NR_DL_FRAME_PARMS *frame_parms=&phy_vars_ue->frame_parms;
//use 1st antenna
@@ -578,7 +589,6 @@ static void ueFreqWaterFall (OAIgraph_t *graph,PHY_VARS_NR_UE *phy_vars_ue, int
phy_vars_ue->frame_parms.slots_per_frame,
"X axis: one frame frequency" );
}
-
/*
static void uePbchFrequencyResp (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
// Channel Frequency Response (includes 5 complex sample for filter)
@@ -614,7 +624,6 @@ static void uePbchFrequencyResp (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue
oai_xygraph(graph,freq,chest_f_abs,frame_parms->ofdm_symbol_size,0,10);
}
*/
-
static void uePbchLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
// PBCH LLRs
if ( !phy_vars_ue->pbch_vars[eNB_id]->llr)
@@ -630,7 +639,6 @@ static void uePbchLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_
oai_xygraph(graph,bit_pbch,llr_pbch,864,0,10);
}
-
static void uePbchIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
// PBCH I/Q of MF Output
if (!phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0])
@@ -665,15 +673,14 @@ static void uePbchIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_i
AssertFatal(base <= 180*3,"");
oai_xygraph(graph,I,Q,base,0, 10);
}
-
static void uePcchLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
// PDCCH LLRs
if (!phy_vars_ue->pdcch_vars[0][eNB_id]->llr)
return;
- int num_re = 4*273*12; // 12*frame_parms->N_RB_DL*num_pdcch_symbols
- int Qm = 2;
- int coded_bits_per_codeword = num_re*Qm;
+ //int num_re = 4*273*12; // 12*frame_parms->N_RB_DL*num_pdcch_symbols
+ //int Qm = 2;
+ int coded_bits_per_codeword = 2*4*100*12; //num_re*Qm;
float *llr, *bit;
oai_xygraph_getbuff(graph, &bit, &llr, coded_bits_per_codeword*RX_NB_TH_MAX, 0);
int base=0;
@@ -691,7 +698,6 @@ static void uePcchLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_
AssertFatal(base <= coded_bits_per_codeword*RX_NB_TH_MAX, "");
oai_xygraph(graph,bit,llr,base,0,10);
}
-
static void uePcchIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
// PDCCH I/Q of MF Output
if (!phy_vars_ue->pdcch_vars[0][eNB_id]->rxdataF_comp[0])
@@ -716,7 +722,6 @@ static void uePcchIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_i
AssertFatal(base <= nb*RX_NB_TH_MAX, "");
oai_xygraph(graph,I,Q,base,0,10);
}
-
static void uePdschLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
// PDSCH LLRs
if (!phy_vars_ue->pdsch_vars[0][eNB_id]->llr[0])
@@ -744,7 +749,6 @@ static void uePdschLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB
//fl_set_xyplot_xbounds(form->pdsch_llr,0,coded_bits_per_codeword);
oai_xygraph(graph,bit,llr,base,0,10);
}
-
static void uePdschIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
// PDSCH I/Q of MF Output
if (!phy_vars_ue->pdsch_vars[0][eNB_id]->rxdataF_comp0[0])
@@ -772,7 +776,6 @@ static void uePdschIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_
AssertFatal(base <= sz*RX_NB_TH_MAX, "");
oai_xygraph(graph,I,Q,sz*RX_NB_TH_MAX,0,10);
}
-
static void uePdschThroughput (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
/*
float tput_time_ue[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
@@ -796,7 +799,6 @@ static void uePdschThroughput (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue,
fl_set_xyplot_ybounds(form->pdsch_tput,0,tput_ue_max[UE_id]);
*/
}
-
static OAI_phy_scope_t *create_phy_scope_nrue( int ID ) {
FL_OBJECT *obj;
OAI_phy_scope_t *fdui = calloc(( sizeof *fdui ),1);
@@ -866,7 +868,6 @@ static OAI_phy_scope_t *create_phy_scope_nrue( int ID ) {
fl_show_form (fdui->phy_scope, FL_PLACE_HOTSPOT, FL_FULLBORDER, buf);
return fdui;
}
-
void phy_scope_nrUE(OAI_phy_scope_t *form,
PHY_VARS_NR_UE *phy_vars_ue,
int eNB_id,
@@ -890,8 +891,6 @@ void phy_scope_nrUE(OAI_phy_scope_t *form,
//fl_check_forms();
}
-
-
static void *nrUEscopeThread(void *arg) {
PHY_VARS_NR_UE *ue=(PHY_VARS_NR_UE *)arg;
size_t stksize;
@@ -915,13 +914,10 @@ static void *nrUEscopeThread(void *arg) {
pthread_exit((void *)arg);
}
-
void nrUEinitScope(PHY_VARS_NR_UE *ue) {
pthread_t forms_thread;
threadCreate(&forms_thread, nrUEscopeThread, ue, "scope", -1, OAI_PRIORITY_RT_LOW);
}
-
-
void nrscope_autoinit(void *dataptr) {
AssertFatal( (IS_SOFTMODEM_GNB_BIT||IS_SOFTMODEM_5GUE_BIT),"Scope cannot find NRUE or GNB context");
@@ -956,7 +952,6 @@ static void reset_stats_gNB(FL_OBJECT *button,
}
}
}
-
static FD_stats_form *create_form_stats_form(int ID) {
FL_OBJECT *obj;
FD_stats_form *fdui = calloc(( sizeof *fdui ),1);
diff --git a/openair1/PHY/TOOLS/nr_phy_scope.h b/openair1/PHY/TOOLS/nr_phy_scope.h
index 84b9e66908..e34ddf2c20 100644
--- a/openair1/PHY/TOOLS/nr_phy_scope.h
+++ b/openair1/PHY/TOOLS/nr_phy_scope.h
@@ -33,13 +33,7 @@
//#include "PHY/impl_defs_top.h"
#include "PHY/defs_nr_UE.h"
-typedef struct {
- int *argc;
- char **argv;
- RU_t *ru;
- PHY_VARS_gNB *gNB;
-} scopeParms_t;
-
+#include
extern RAN_CONTEXT_t RC;
#endif
diff --git a/openair1/PHY/TOOLS/phy_scope_interface.c b/openair1/PHY/TOOLS/phy_scope_interface.c
index af237b2325..7cd68c53d2 100644
--- a/openair1/PHY/TOOLS/phy_scope_interface.c
+++ b/openair1/PHY/TOOLS/phy_scope_interface.c
@@ -35,6 +35,7 @@
#include "phy_scope_interface.h"
#define SOFTSCOPE_ENDFUNC_IDX 0
+
static loader_shlibfunc_t scope_fdesc[]= {{"end_forms",NULL}};
int load_softscope(char *exectype, void *initarg) {
diff --git a/openair1/PHY/TOOLS/phy_scope_interface.h b/openair1/PHY/TOOLS/phy_scope_interface.h
index adf04d5ea4..8b747d575d 100644
--- a/openair1/PHY/TOOLS/phy_scope_interface.h
+++ b/openair1/PHY/TOOLS/phy_scope_interface.h
@@ -29,7 +29,26 @@
* \note
* \warning
*/
+#ifndef __PHY_SCOPE_INTERFACE_H__
+#define __PHY_SCOPE_INTERFACE_H__
+#include
+typedef struct {
+ int *argc;
+ char **argv;
+ RU_t *ru;
+ PHY_VARS_gNB *gNB;
+} scopeParms_t;
+typedef struct scopeData_s {
+ int *argc;
+ char **argv;
+ RU_t *ru;
+ PHY_VARS_gNB *gNB;
+ int32_t * rxdataF;
+ void (*slotFunc)(int32_t* data, int slot, void * scopeData);
+} scopeData_t;
+
int load_softscope(char *exectype, void *initarg);
int end_forms(void) ;
+#endif
diff --git a/openair1/PHY/TOOLS/time_meas.c b/openair1/PHY/TOOLS/time_meas.c
index cfa3b93007..001770c876 100644
--- a/openair1/PHY/TOOLS/time_meas.c
+++ b/openair1/PHY/TOOLS/time_meas.c
@@ -26,9 +26,12 @@
// global var for openair performance profiler
int opp_enabled = 0;
+double cpu_freq_GHz __attribute__ ((aligned(32)));
+double cpu_freq_GHz __attribute__ ((aligned(32)))=0.0;
double get_cpu_freq_GHz(void)
{
+ if (cpu_freq_GHz <1 ) {
time_stats_t ts = {0};
reset_meas(&ts);
ts.trials++;
@@ -37,6 +40,7 @@ double get_cpu_freq_GHz(void)
ts.diff = (rdtsc_oai()-ts.in);
cpu_freq_GHz = (double)ts.diff/1000000000;
printf("CPU Freq is %f \n", cpu_freq_GHz);
+ }
return cpu_freq_GHz;
}
@@ -99,10 +103,11 @@ void print_meas(time_stats_t *ts,
if (ts->trials>0) {
//printf("%20s: total: %10.3f ms, average: %10.3f us (%10d trials)\n", name, ts->diff/cpu_freq_GHz/1000000.0, ts->diff/ts->trials/cpu_freq_GHz/1000.0, ts->trials);
if ((total_exec_time == NULL) || (sf_exec_time== NULL)) {
- fprintf(stderr, "%25s: %15.3f us; %15d;\n",
+ fprintf(stderr, "%25s: %15.3f us; %15d; %15.3f us;\n",
name,
(ts->diff/ts->trials/cpu_freq_GHz/1000.0),
- ts->trials);
+ ts->trials,
+ ts->max/cpu_freq_GHz/1000.0);
} else {
fprintf(stderr, "%25s: %15.3f ms (%5.2f%%); %15.3f us (%5.2f%%); %15d;\n",
name,
diff --git a/openair1/PHY/TOOLS/time_meas.h b/openair1/PHY/TOOLS/time_meas.h
index 2deab40f27..e2ceef8405 100644
--- a/openair1/PHY/TOOLS/time_meas.h
+++ b/openair1/PHY/TOOLS/time_meas.h
@@ -33,7 +33,7 @@
#include
// global var to enable openair performance profiler
extern int opp_enabled;
-double cpu_freq_GHz __attribute__ ((aligned(32)));;
+extern double cpu_freq_GHz __attribute__ ((aligned(32)));;
#if defined(__x86_64__) || defined(__i386__)
typedef struct {
diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h
index db7ac3d813..4c68c15cb6 100644
--- a/openair1/PHY/TOOLS/tools_defs.h
+++ b/openair1/PHY/TOOLS/tools_defs.h
@@ -44,6 +44,11 @@ struct complex {
double y;
};
+struct complexd {
+ double r;
+ double i;
+};
+
struct complexf {
float r;
float i;
diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h
index 27765a8548..1a8016054a 100644
--- a/openair1/PHY/defs_common.h
+++ b/openair1/PHY/defs_common.h
@@ -867,8 +867,9 @@ typedef enum {
NOT_SYNCHED=0,
PRACH=1,
RA_RESPONSE=2,
- PUSCH=3,
- RESYNCH=4
+ RA_WAIT_CR=3,
+ PUSCH=4,
+ RESYNCH=5
} UE_MODE_t;
#define FOREACH_PARALLEL(GEN) \
diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h
index 2f6c4324b0..edb19f7501 100644
--- a/openair1/PHY/defs_gNB.h
+++ b/openair1/PHY/defs_gNB.h
@@ -664,6 +664,7 @@ typedef struct {
int prach_I0;
} PHY_MEASUREMENTS_gNB;
+#define MAX_NUM_NR_PRACH_PREAMBLES 64
#define MAX_NUM_NR_RX_RACH_PDUS 4
#define MAX_NUM_NR_RX_PRACH_PREAMBLES 4
#define MAX_UL_PDUS_PER_SLOT 8
@@ -823,6 +824,7 @@ typedef struct PHY_VARS_gNB_s {
time_stats_t dlsch_segmentation_stats;
time_stats_t rx_pusch_stats;
+ time_stats_t ul_indication_stats;
time_stats_t ulsch_decoding_stats;
time_stats_t ulsch_rate_unmatching_stats;
time_stats_t ulsch_ldpc_decoding_stats;
@@ -846,7 +848,7 @@ typedef struct PHY_VARS_gNB_s {
tpool_t *threadPool;
int nbDecode;
uint8_t pusch_proc_threads;
-
+ void * scopeData;
} PHY_VARS_gNB;
typedef struct LDPCDecode_s {
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/PHY/impl_defs_nr.h b/openair1/PHY/impl_defs_nr.h
index ceb75c2554..fad578c8b0 100644
--- a/openair1/PHY/impl_defs_nr.h
+++ b/openair1/PHY/impl_defs_nr.h
@@ -214,10 +214,8 @@ typedef enum {
#define NB_SRS_PERIOD (17)
-const uint16_t srs_period[NB_SRS_PERIOD]
-#ifdef INIT_VARIABLES_PHY_IMPLEMENTATION_DEFS_NR_H
+static const uint16_t srs_period[NB_SRS_PERIOD]
= { 1, 2, 4, 5, 8, 10, 16, 20, 32, 40, 64, 80, 160, 320, 640, 1280, 2560}
-#endif
;
/// SRS_Resource of SRS_Config information element from 38.331 RRC specifications
@@ -796,7 +794,6 @@ typedef struct {
uint8_t initial_CS_indexes[MAX_NB_CYCLIC_SHIFT];
} initial_pucch_resource_t;
-const initial_pucch_resource_t initial_pucch_resource[NB_INITIAL_PUCCH_RESOURCE]; /* TS 36.213 Table 9.2.1-1: PUCCH resource sets before dedicated PUCCH resource configuration */
/* structure with all possible fields for pucch format from 0 to 4 */
typedef struct {
@@ -1051,11 +1048,6 @@ typedef struct {
#define NB_SR_PERIOD (15)
-const uint16_t scheduling_request_periodicity[NB_SR_PERIOD]
-#ifdef INIT_VARIABLES_PHY_IMPLEMENTATION_DEFS_NR_H
-= { 0, 0, 1, 2, 4, 5, 8, 10, 16, 20, 40, 80, 160, 320, 640 }
-#endif
-;
typedef enum {
sr_sym2 = 0,
diff --git a/openair1/PHY/phy_extern.h b/openair1/PHY/phy_extern.h
index 165ed961b3..4ba5e328e3 100644
--- a/openair1/PHY/phy_extern.h
+++ b/openair1/PHY/phy_extern.h
@@ -48,12 +48,6 @@ extern short primary_synch2[144];
extern unsigned char primary_synch0_tab[72];
extern unsigned char primary_synch1_tab[72];
extern unsigned char primary_synch2_tab[72];
-extern int16_t *primary_synch0_time; //!< index: [0..ofdm_symbol_size*2[
-extern int16_t *primary_synch1_time; //!< index: [0..ofdm_symbol_size*2[
-extern int16_t *primary_synch2_time; //!< index: [0..ofdm_symbol_size*2[
-extern int *sync_corr_ue0; //!< index [0..10*samples_per_tti[
-extern int *sync_corr_ue1; //!< index [0..10*samples_per_tti[
-extern int *sync_corr_ue2; //!< index [0..10*samples_per_tti[
extern int flagMag;
//extern short **txdataF_rep_tmp;
diff --git a/openair1/PHY/phy_extern_nr_ue.h b/openair1/PHY/phy_extern_nr_ue.h
index 700419c61c..f1704a7902 100644
--- a/openair1/PHY/phy_extern_nr_ue.h
+++ b/openair1/PHY/phy_extern_nr_ue.h
@@ -55,9 +55,6 @@ extern unsigned char primary_synch2_tab[72];
extern int16_t *primary_synch0_time; //!< index: [0..ofdm_symbol_size*2[
extern int16_t *primary_synch1_time; //!< index: [0..ofdm_symbol_size*2[
extern int16_t *primary_synch2_time; //!< index: [0..ofdm_symbol_size*2[
-extern int *sync_corr_ue0; //!< index [0..10*samples_per_tti[
-extern int *sync_corr_ue1; //!< index [0..10*samples_per_tti[
-extern int *sync_corr_ue2; //!< index [0..10*samples_per_tti[
extern int flagMag;
//extern short **txdataF_rep_tmp;
diff --git a/openair1/PHY/phy_extern_ue.h b/openair1/PHY/phy_extern_ue.h
index 622551c2fe..fdaf6eaa89 100644
--- a/openair1/PHY/phy_extern_ue.h
+++ b/openair1/PHY/phy_extern_ue.h
@@ -47,12 +47,6 @@ extern short primary_synch2[144];
extern unsigned char primary_synch0_tab[72];
extern unsigned char primary_synch1_tab[72];
extern unsigned char primary_synch2_tab[72];
-extern int16_t *primary_synch0_time; //!< index: [0..ofdm_symbol_size*2[
-extern int16_t *primary_synch1_time; //!< index: [0..ofdm_symbol_size*2[
-extern int16_t *primary_synch2_time; //!< index: [0..ofdm_symbol_size*2[
-extern int *sync_corr_ue0; //!< index [0..10*samples_per_tti[
-extern int *sync_corr_ue1; //!< index [0..10*samples_per_tti[
-extern int *sync_corr_ue2; //!< index [0..10*samples_per_tti[
extern int flagMag;
//extern short **txdataF_rep_tmp;
diff --git a/openair1/PHY/phy_vars.h b/openair1/PHY/phy_vars.h
index 5e2be8bd8f..dadb1649ec 100644
--- a/openair1/PHY/phy_vars.h
+++ b/openair1/PHY/phy_vars.h
@@ -33,9 +33,6 @@ char* namepointer_log2;
#include "PHY/LTE_REFSIG/primary_synch.h"
-int16_t *primary_synch0_time;
-int16_t *primary_synch1_time;
-int16_t *primary_synch2_time;
#include "PHY/LTE_TRANSPORT/transport_vars.h"
diff --git a/openair1/PHY/phy_vars_ue.h b/openair1/PHY/phy_vars_ue.h
index e90c2641aa..469a5c4754 100644
--- a/openair1/PHY/phy_vars_ue.h
+++ b/openair1/PHY/phy_vars_ue.h
@@ -33,9 +33,6 @@ char *namepointer_log2;
#include "PHY/LTE_REFSIG/primary_synch.h"
-int16_t *primary_synch0_time;
-int16_t *primary_synch1_time;
-int16_t *primary_synch2_time;
PHY_VARS_UE ***PHY_vars_UE_g;
diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index 38307a7b9e..d894061acd 100644
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -40,6 +40,7 @@
#include "common/utils/LOG/log.h"
#include
#include "common/utils/LOG/vcd_signal_dumper.h"
+#include
#include "assertions.h"
#include "msc.h"
@@ -51,7 +52,6 @@
#define MBMS_NFAPI_SCHEDULER
-nfapi_ue_release_request_body_t release_rntis;
int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *eNB,uint16_t UE_id,uint8_t harq_pid, uint8_t bw_factor) {
uint32_t Nre,sumKr,MPR_x100,Kr,r;
diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
index d44c8641a6..d68cacece2 100644
--- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c
+++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
@@ -194,6 +194,8 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,0);
}
+ if (do_meas==1) stop_meas(&gNB->phy_proc_tx);
+
if ((frame&127) == 0) dump_pdsch_stats(gNB);
//apply the OFDM symbol rotation here
@@ -539,6 +541,8 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
int power_rxF = signal_energy_nodc(&gNB->common_vars.rxdataF[0][offset],12*18);
LOG_D(PHY,"frame %d, slot %d: UL signal energy %d\n",frame_rx,slot_rx,power_rxF);
+ start_meas(&gNB->phy_proc_rx);
+
for (int i=0;ipucch[i];
if (pucch) {
@@ -560,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,
@@ -644,7 +652,7 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
start_meas(&gNB->rx_pusch_stats);
for(uint8_t symbol = symbol_start; symbol < symbol_end; symbol++) {
no_sig = nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, symbol, harq_pid);
- if (no_sig) {
+ if (no_sig && (get_softmodem_params()->phy_test == 0)) {
LOG_I(PHY, "PUSCH not detected in symbol %d\n",symbol);
nr_fill_indication(gNB,frame_rx, slot_rx, ULSCH_id, harq_pid, 1);
return;
@@ -662,6 +670,7 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
}
}
}
+ stop_meas(&gNB->phy_proc_rx);
// figure out a better way to choose slot_rx, 19 is ok for a particular TDD configuration with 30kHz SCS
if ((frame_rx&127) == 0 && slot_rx==19) {
dump_pusch_stats(gNB);
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 e70c353589..c8ac871bbf 100644
--- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
+++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
@@ -84,6 +84,8 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
}
else if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH){
dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch_ra[0];
+ dlsch0->rnti_type = _RA_RNTI_;
+ dlsch0->harq_processes[dlsch0->current_harq_pid]->status = ACTIVE;
}
else if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH){
dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch_SI[0];
@@ -125,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 df66217e49..ff7e4280a1 100644
--- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
@@ -234,7 +234,7 @@ void ue_ta_procedures(PHY_VARS_NR_UE *ue, int slot_tx, int frame_tx){
ue->timing_advance += (ul_time_alignment->ta_command - 31) * bw_scaling;
- LOG_I(PHY, "In %s: [UE %d] [%d.%d] Got timing advance command %u from MAC, new value is %d\n",
+ LOG_D(PHY, "In %s: [UE %d] [%d.%d] Got timing advance command %u from MAC, new value is %d\n",
__FUNCTION__,
ue->Mod_id,
frame_tx,
@@ -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);
@@ -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");
+ }
}
}
@@ -771,6 +758,7 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_
uint16_t pdsch_nb_rb = dlsch0_harq->nb_rb;
uint16_t s0 = dlsch0_harq->start_symbol;
uint16_t s1 = dlsch0_harq->nb_symbols;
+ bool is_SI = dlsch0->rnti_type == _SI_RNTI_;
LOG_D(PHY,"[UE %d] PDSCH type %d active in nr_slot_rx %d, harq_pid %d (%d), rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d, DMRS mask %x\n",ue->Mod_id,pdsch,nr_slot_rx,harq_pid,dlsch0->harq_processes[harq_pid]->status,pdsch_start_rb,pdsch_nb_rb,s0,s1,dlsch0->harq_processes[harq_pid]->dlDmrsSymbPos);
@@ -780,6 +768,7 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_
nr_pdsch_channel_estimation(ue,
proc,
0 /*eNB_id*/,
+ is_SI,
nr_slot_rx,
aatx /*p*/,
m,
@@ -1134,7 +1123,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
LOG_D(PHY, "harq_pid: %d, TBS expected dlsch1: %d \n", harq_pid, dlsch1->harq_processes[harq_pid]->TBS);
}
- LOG_D(PHY," ------ end ldpc decoder for AbsSubframe %d.%d ------ \n", frame_rx, nr_slot_rx);
+ LOG_D(PHY," ------ end ldpc decoder for AbsSubframe %d.%d ------ decoded in %d \n", frame_rx, nr_slot_rx, ret);
LOG_D(PHY, "harq_pid: %d, TBS expected dlsch0: %d \n",harq_pid, dlsch0->harq_processes[harq_pid]->TBS);
if(retmax_ldpc_iterations+1){
@@ -1613,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;
@@ -1690,9 +1680,9 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
}
if ((frame_rx%64 == 0) && (nr_slot_rx==0)) {
- printf("============================================\n");
+ LOG_I(PHY,"============================================\n");
LOG_I(PHY,"Harq round stats for Downlink: %d/%d/%d/%d DLSCH errors: %d\n",ue->dl_stats[0],ue->dl_stats[1],ue->dl_stats[2],ue->dl_stats[3],ue->dl_stats[4]);
- printf("============================================\n");
+ LOG_I(PHY,"============================================\n");
}
#ifdef NR_PDCCH_SCHED
@@ -1770,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);
@@ -1902,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
@@ -2068,7 +2066,7 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t
}
- if (nr_prach == 1) {
+ if (nr_prach == GENERATE_PREAMBLE) {
if (ue->mac_enabled == 1) {
int16_t pathloss = get_nr_PL(mod_id, ue->CC_id, gNB_id);
@@ -2114,18 +2112,15 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t
if (ue->mac_enabled == 1)
nr_Msg1_transmitted(mod_id, ue->CC_id, frame_tx, gNB_id);
- } else if (nr_prach == 2) {
-
+ } else if (nr_prach == WAIT_CONTENTION_RESOLUTION) {
+ LOG_D(PHY, "In %s: [UE %d] RA waiting contention resolution\n", __FUNCTION__, mod_id);
+ ue->UE_mode[gNB_id] = RA_WAIT_CR;
+ } else if (nr_prach == RA_SUCCEEDED) {
LOG_D(PHY, "In %s: [UE %d] RA completed, setting UE mode to PUSCH\n", __FUNCTION__, mod_id);
-
ue->UE_mode[gNB_id] = PUSCH;
-
- } else if(nr_prach == 3){
-
+ } else if(nr_prach == RA_FAILED){
LOG_D(PHY, "In %s: [UE %d] RA failed, setting UE mode to PRACH\n", __FUNCTION__, mod_id);
-
ue->UE_mode[gNB_id] = PRACH;
-
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_OUT);
diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c
index edb070f873..0455c481d5 100644
--- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c
+++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c
@@ -40,6 +40,7 @@
#include
#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
#include "openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h"
+#include
#ifndef NO_RAT_NR
@@ -54,10 +55,172 @@
#endif
+/* TS 36.213 Table 9.2.3-3: Mapping of values for one HARQ-ACK bit to sequences */
+static const int sequence_cyclic_shift_1_harq_ack_bit[2]
+/* HARQ-ACK Value 0 1 */
+/* Sequence cyclic shift */ = { 0, 6 }
+;
+
+/* TS 36.213 Table 9.2.5-2: Mapping of values for two HARQ-ACK bits and positive SR to sequences */
+static const int sequence_cyclic_shift_2_harq_ack_bits_positive_sr[4]
+/* HARQ-ACK Value (0,0) (0,1) (1,0) (1,1) */
+/* Sequence cyclic shift */ = { 1, 4, 10, 7 }
+;
+
uint8_t nr_is_cqi_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t gNB_id);
uint8_t nr_is_ri_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t gNB_id);
+static const uint16_t scheduling_request_periodicity[NB_SR_PERIOD]
+= { 0, 0, 1, 2, 4, 5, 8, 10, 16, 20, 40, 80, 160, 320, 640 }
+;
+
+/* TS 38.213 9.2.5.2 UE procedure for multiplexing HARQ-ACK/SR and CSI in a PUCCH */
+/* this is a counter of number of pucch format 4 per subframe */
+static int nb_pucch_format_4_in_subframes[LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] = { 0 } ;
+
+/* TS 36.213 Table 9.2.5.2-1: Code rate corresponding to higher layer parameter PUCCH-F2-maximum-coderate, */
+/* or PUCCH-F3-maximum-coderate, or PUCCH-F4-maximum-coderate */
+/* add one additional element set to 0 for parsing the array until this end */
+/* stored values are code rates * 100 */
+//static const int code_rate_r_time_100[8] = { (0.08 * 100), (0.15 * 100), (0.25*100), (0.35*100), (0.45*100), (0.60*100), (0.80*100), 0 } ;
+
+/* TS 38.213 Table 9.2.3-4: Mapping of values for two HARQ-ACK bits to sequences */
+static const int sequence_cyclic_shift_2_harq_ack_bits[4]
+/* HARQ-ACK Value (0,0) (0,1) (1,0) (1,1) */
+/* Sequence cyclic shift */ = { 0, 3, 9, 6 }
+;
+
+/* TS 38.211 Table 6.4.1.3.3.2-1: DM-RS positions for PUCCH format 3 and 4 */
+static const int nb_symbols_excluding_dmrs[NB_SYMBOL_MINUS_FOUR][2][2]
+= {
+/* No additional DMRS Additional DMRS */
+/* PUCCH length No hopping hopping No hopping hopping */
+/* index 0 1 0 1 */
+/* 4 */ {{ 3 , 2 } , { 3 , 2 }},
+/* 5 */ {{ 3 , 3 } , { 3 , 3 }},
+/* 6 */ {{ 4 , 4 } , { 4 , 4 }},
+/* 7 */ {{ 5 , 5 } , { 5 , 5 }},
+/* 8 */ {{ 6 , 6 } , { 6 , 6 }},
+/* 9 */ {{ 7 , 7 } , { 7 , 7 }},
+/* 10 */ {{ 8 , 8 } , { 6 , 6 }},
+/* 11 */ {{ 9 , 9 } , { 7 , 7 }},
+/* 12 */ {{ 10 , 10 } , { 8 , 8 }},
+/* 13 */ {{ 11 , 11 } , { 9 , 9 }},
+/* 14 */ {{ 12 , 12 } , { 10 , 10 }},
+}
+;
+
+
+/* TS 36.213 Table 9.2.5-1: Mapping of values for one HARQ-ACK bit and positive SR to sequences */
+static const int sequence_cyclic_shift_1_harq_ack_bit_positive_sr[2]
+/* HARQ-ACK Value 0 1 */
+/* Sequence cyclic shift */ = { 3, 9 }
+;
+
+static float RSRP_meas_mapping_nr[98]
+= {
+ -140,
+ -139,
+ -138,
+ -137,
+ -136,
+ -135,
+ -134,
+ -133,
+ -132,
+ -131,
+ -130,
+ -129,
+ -128,
+ -127,
+ -126,
+ -125,
+ -124,
+ -123,
+ -122,
+ -121,
+ -120,
+ -119,
+ -118,
+ -117,
+ -116,
+ -115,
+ -114,
+ -113,
+ -112,
+ -111,
+ -110,
+ -109,
+ -108,
+ -107,
+ -106,
+ -105,
+ -104,
+ -103,
+ -102,
+ -101,
+ -100,
+ -99,
+ -98,
+ -97,
+ -96,
+ -95,
+ -94,
+ -93,
+ -92,
+ -91,
+ -90,
+ -89,
+ -88,
+ -87,
+ -86,
+ -85,
+ -84,
+ -83,
+ -82,
+ -81,
+ -80,
+ -79,
+ -78,
+ -77,
+ -76,
+ -75,
+ -74,
+ -73,
+ -72,
+ -71,
+ -70,
+ -69,
+ -68,
+ -67,
+ -66,
+ -65,
+ -64,
+ -63,
+ -62,
+ -61,
+ -60,
+ -59,
+ -58,
+ -57,
+ -56,
+ -55,
+ -54,
+ -53,
+ -52,
+ -51,
+ -50,
+ -49,
+ -48,
+ -47,
+ -46,
+ -45,
+ -44,
+ -43
+ }
+ ;
+
long
binary_search_float_nr(
float elements[],
@@ -202,6 +365,30 @@ void nr_generate_pucch3_4(int32_t **txdataF,
*
*********************************************************************/
+/* TS 36.213 Table 9.2.1-1: PUCCH resource sets before dedicated PUCCH resource configuration */
+const initial_pucch_resource_t initial_pucch_resource[NB_INITIAL_PUCCH_RESOURCE]
+=
+{
+/* format first symbol Number of symbols PRB offset nb index for set of initial CS */
+/* 0 */ { pucch_format0_nr, 12, 2, 0, 2, { 0, 3, 0, 0 } },
+/* 1 */ { pucch_format0_nr, 12, 2, 0, 3, { 0, 4, 8, 0 } },
+/* 2 */ { pucch_format0_nr, 12, 2, 3, 3, { 0, 4, 8, 0 } },
+/* 3 */ { pucch_format1_nr, 10, 4, 0, 2, { 0, 6, 0, 0 } },
+/* 4 */ { pucch_format1_nr, 10, 4, 0, 4, { 0, 3, 6, 9 } },
+/* 5 */ { pucch_format1_nr, 10, 4, 2, 4, { 0, 3, 6, 9 } },
+/* 6 */ { pucch_format1_nr, 10, 4, 4, 4, { 0, 3, 6, 9 } },
+/* 7 */ { pucch_format1_nr, 4, 10, 0, 2, { 0, 6, 0, 0 } },
+/* 8 */ { pucch_format1_nr, 4, 10, 0, 4, { 0, 3, 6, 9 } },
+/* 9 */ { pucch_format1_nr, 4, 10, 2, 4, { 0, 3, 6, 9 } },
+/* 10 */ { pucch_format1_nr, 4, 10, 4, 4, { 0, 3, 6, 9 } },
+/* 11 */ { pucch_format1_nr, 0, 14, 0, 2, { 0, 6, 0, 0 } },
+/* 12 */ { pucch_format1_nr, 0, 14, 0, 4, { 0, 3, 6, 9 } },
+/* 13 */ { pucch_format1_nr, 0, 14, 2, 4, { 0, 3, 6, 9 } },
+/* 14 */ { pucch_format1_nr, 0, 14, 4, 4, { 0, 3, 6, 9 } },
+/* 15 */ { pucch_format1_nr, 0, 14, 0, 4, { 0, 3, 6, 9 } },
+}
+;
+
bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_t *proc, bool reset_harq)
{
uint8_t sr_payload = 0;
@@ -788,7 +975,7 @@ uint8_t get_downlink_ack(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_t
LOG_E(PHY,"PUCCH Downlink DAI has an invalid value : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
}
else if (harq_status->send_harq_status == 0) {
- LOG_D(PHY,"PUCCH Downlink ack can not be transmitted : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
+ LOG_E(PHY,"PUCCH Downlink ack can not be transmitted : at line %d in function %s of file %s \n", LINE_FILE , __func__, FILE_NAME);
}
else {
diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h
index 9b53331f50..97d8d73282 100644
--- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h
+++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h
@@ -60,214 +60,12 @@
/************** VARIABLES *****************************************/
-float RSRP_meas_mapping_nr[98]
-#ifdef INIT_VARIABLES_PUCCH_UE_NR_H
-= {
- -140,
- -139,
- -138,
- -137,
- -136,
- -135,
- -134,
- -133,
- -132,
- -131,
- -130,
- -129,
- -128,
- -127,
- -126,
- -125,
- -124,
- -123,
- -122,
- -121,
- -120,
- -119,
- -118,
- -117,
- -116,
- -115,
- -114,
- -113,
- -112,
- -111,
- -110,
- -109,
- -108,
- -107,
- -106,
- -105,
- -104,
- -103,
- -102,
- -101,
- -100,
- -99,
- -98,
- -97,
- -96,
- -95,
- -94,
- -93,
- -92,
- -91,
- -90,
- -89,
- -88,
- -87,
- -86,
- -85,
- -84,
- -83,
- -82,
- -81,
- -80,
- -79,
- -78,
- -77,
- -76,
- -75,
- -74,
- -73,
- -72,
- -71,
- -70,
- -69,
- -68,
- -67,
- -66,
- -65,
- -64,
- -63,
- -62,
- -61,
- -60,
- -59,
- -58,
- -57,
- -56,
- -55,
- -54,
- -53,
- -52,
- -51,
- -50,
- -49,
- -48,
- -47,
- -46,
- -45,
- -44,
- -43
- }
- #endif
- ;
-
-/* TS 36.213 Table 9.2.1-1: PUCCH resource sets before dedicated PUCCH resource configuration */
-const initial_pucch_resource_t initial_pucch_resource[NB_INITIAL_PUCCH_RESOURCE]
-#ifdef INIT_VARIABLES_PUCCH_UE_NR_H
-=
-{
-/* format first symbol Number of symbols PRB offset nb index for set of initial CS */
-/* 0 */ { pucch_format0_nr, 12, 2, 0, 2, { 0, 3, 0, 0 } },
-/* 1 */ { pucch_format0_nr, 12, 2, 0, 3, { 0, 4, 8, 0 } },
-/* 2 */ { pucch_format0_nr, 12, 2, 3, 3, { 0, 4, 8, 0 } },
-/* 3 */ { pucch_format1_nr, 10, 4, 0, 2, { 0, 6, 0, 0 } },
-/* 4 */ { pucch_format1_nr, 10, 4, 0, 4, { 0, 3, 6, 9 } },
-/* 5 */ { pucch_format1_nr, 10, 4, 2, 4, { 0, 3, 6, 9 } },
-/* 6 */ { pucch_format1_nr, 10, 4, 4, 4, { 0, 3, 6, 9 } },
-/* 7 */ { pucch_format1_nr, 4, 10, 0, 2, { 0, 6, 0, 0 } },
-/* 8 */ { pucch_format1_nr, 4, 10, 0, 4, { 0, 3, 6, 9 } },
-/* 9 */ { pucch_format1_nr, 4, 10, 2, 4, { 0, 3, 6, 9 } },
-/* 10 */ { pucch_format1_nr, 4, 10, 4, 4, { 0, 3, 6, 9 } },
-/* 11 */ { pucch_format1_nr, 0, 14, 0, 2, { 0, 6, 0, 0 } },
-/* 12 */ { pucch_format1_nr, 0, 14, 0, 4, { 0, 3, 6, 9 } },
-/* 13 */ { pucch_format1_nr, 0, 14, 2, 4, { 0, 3, 6, 9 } },
-/* 14 */ { pucch_format1_nr, 0, 14, 4, 4, { 0, 3, 6, 9 } },
-/* 15 */ { pucch_format1_nr, 0, 14, 0, 4, { 0, 3, 6, 9 } },
-}
-#endif
-;
-
-/* TS 36.213 Table 9.2.3-3: Mapping of values for one HARQ-ACK bit to sequences */
-const int sequence_cyclic_shift_1_harq_ack_bit[2]
-#ifdef INIT_VARIABLES_PUCCH_UE_NR_H
-/* HARQ-ACK Value 0 1 */
-/* Sequence cyclic shift */ = { 0, 6 }
-#endif
-;
-
-/* TS 38.213 Table 9.2.3-4: Mapping of values for two HARQ-ACK bits to sequences */
-const int sequence_cyclic_shift_2_harq_ack_bits[4]
-#ifdef INIT_VARIABLES_PUCCH_UE_NR_H
-/* HARQ-ACK Value (0,0) (0,1) (1,0) (1,1) */
-/* Sequence cyclic shift */ = { 0, 3, 9, 6 }
-#endif
-;
-
-/* TS 36.213 Table 9.2.5-1: Mapping of values for one HARQ-ACK bit and positive SR to sequences */
-const int sequence_cyclic_shift_1_harq_ack_bit_positive_sr[2]
-#ifdef INIT_VARIABLES_PUCCH_UE_NR_H
-/* HARQ-ACK Value 0 1 */
-/* Sequence cyclic shift */ = { 3, 9 }
-#endif
-;
-
-/* TS 36.213 Table 9.2.5-2: Mapping of values for two HARQ-ACK bits and positive SR to sequences */
-const int sequence_cyclic_shift_2_harq_ack_bits_positive_sr[4]
-#ifdef INIT_VARIABLES_PUCCH_UE_NR_H
-/* HARQ-ACK Value (0,0) (0,1) (1,0) (1,1) */
-/* Sequence cyclic shift */ = { 1, 4, 10, 7 }
-#endif
-;
-
-/* TS 36.213 Table 9.2.5.2-1: Code rate corresponding to higher layer parameter PUCCH-F2-maximum-coderate, */
-/* or PUCCH-F3-maximum-coderate, or PUCCH-F4-maximum-coderate */
-/* add one additional element set to 0 for parsing the array until this end */
-/* stored values are code rates * 100 */
-const int code_rate_r_time_100[8]
-#ifdef INIT_VARIABLES_PUCCH_UE_NR_H
-= { (0.08 * 100), (0.15 * 100), (0.25*100), (0.35*100), (0.45*100), (0.60*100), (0.80*100), 0 }
-#endif
-;
-
#define NB_SYMBOL_MINUS_FOUR (11)
#define I_PUCCH_NO_ADDITIONAL_DMRS (0)
#define I_PUCCH_ADDITIONAL_DMRS (1)
#define I_PUCCH_NO_HOPPING (0)
#define I_PUCCH_HOPING (1)
-/* TS 38.211 Table 6.4.1.3.3.2-1: DM-RS positions for PUCCH format 3 and 4 */
-const int nb_symbols_excluding_dmrs[NB_SYMBOL_MINUS_FOUR][2][2]
-#ifdef INIT_VARIABLES_PUCCH_UE_NR_H
-= {
-/* No additional DMRS Additional DMRS */
-/* PUCCH length No hopping hopping No hopping hopping */
-/* index 0 1 0 1 */
-/* 4 */ {{ 3 , 2 } , { 3 , 2 }},
-/* 5 */ {{ 3 , 3 } , { 3 , 3 }},
-/* 6 */ {{ 4 , 4 } , { 4 , 4 }},
-/* 7 */ {{ 5 , 5 } , { 5 , 5 }},
-/* 8 */ {{ 6 , 6 } , { 6 , 6 }},
-/* 9 */ {{ 7 , 7 } , { 7 , 7 }},
-/* 10 */ {{ 8 , 8 } , { 6 , 6 }},
-/* 11 */ {{ 9 , 9 } , { 7 , 7 }},
-/* 12 */ {{ 10 , 10 } , { 8 , 8 }},
-/* 13 */ {{ 11 , 11 } , { 9 , 9 }},
-/* 14 */ {{ 12 , 12 } , { 10 , 10 }},
-}
-#endif
-;
-
-/* TS 38.213 9.2.5.2 UE procedure for multiplexing HARQ-ACK/SR and CSI in a PUCCH */
-/* this is a counter of number of pucch format 4 per subframe */
-int nb_pucch_format_4_in_subframes[LTE_NUMBER_OF_SUBFRAMES_PER_FRAME]
-#ifdef INIT_VARIABLES_PUCCH_UE_NR_H
-= { 0 }
-#endif
-;
/*************** FUNCTIONS ****************************************/
diff --git a/openair1/SIMULATION/LTE_PHY/common_sim.h b/openair1/SIMULATION/LTE_PHY/common_sim.h
index 796a576aed..5e0be3de89 100644
--- a/openair1/SIMULATION/LTE_PHY/common_sim.h
+++ b/openair1/SIMULATION/LTE_PHY/common_sim.h
@@ -46,13 +46,13 @@ void sumUpStatsSlot(time_stats_t *res, time_stats_t src[RX_NB_TH][2], int lastAc
}
double squareRoot(time_stats_t *ptr) {
- double timeBase=1/(1000*cpu_freq_GHz);
+ double timeBase=1/(1000*get_cpu_freq_GHz());
return sqrt((double)ptr->diff_square*pow(timeBase,2)/ptr->trials -
pow((double)ptr->diff/ptr->trials*timeBase,2));
}
void printDistribution(time_stats_t *ptr, varArray_t *sortedList, char *txt) {
- double timeBase=1/(1000*cpu_freq_GHz);
+ double timeBase=1/(1000*get_cpu_freq_GHz());
printf("%-43s %6.2f us (%d trials)\n",
txt,
(double)ptr->diff/ptr->trials*timeBase,
@@ -69,7 +69,7 @@ void printStatIndent(time_stats_t *ptr, char *txt) {
}
void printStatIndent2(time_stats_t *ptr, char *txt) {
- double timeBase=1/(1000*cpu_freq_GHz);
+ double timeBase=1/(1000*get_cpu_freq_GHz());
printf(" |__ %-34s %6.2f us (%3d trials)\n",
txt,
ptr->trials?((double)ptr->diff)/ptr->trials*timeBase:0,
@@ -77,7 +77,7 @@ void printStatIndent2(time_stats_t *ptr, char *txt) {
}
void printStatIndent3(time_stats_t *ptr, char *txt) {
- double timeBase=1/(1000*cpu_freq_GHz);
+ double timeBase=1/(1000*get_cpu_freq_GHz());
printf(" |__ %-30s %6.2f us (%3d trials)\n",
txt,
ptr->trials?((double)ptr->diff)/ptr->trials*timeBase:0,
diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c
index 667913d377..8955454282 100644
--- a/openair1/SIMULATION/LTE_PHY/dlsim.c
+++ b/openair1/SIMULATION/LTE_PHY/dlsim.c
@@ -65,11 +65,14 @@ void feptx_ofdm(RU_t *ru, int frame, int subframe);
void feptx_prec(RU_t *ru, int frame, int subframe);
double cpuf;
-#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0))
+#define inMicroS(a) (((double)(a))/(get_cpu_freq_GHz()*1000.0))
//#define MCS_COUNT 23//added for PHY abstraction
#include
int otg_enabled=0;
+THREAD_STRUCT thread_struct;
+nfapi_ue_release_request_body_t release_rntis;
+
/*the following parameters are used to control the processing times calculations*/
double t_tx_max = -1000000000; /*!< \brief initial max process time for tx */
double t_rx_max = -1000000000; /*!< \brief initial max process time for rx */
@@ -1179,7 +1182,7 @@ int main(int argc, char **argv) {
DS_TDL,
forgetting_factor,
rx_sample_offset,
- 0);
+ 0, 0);
reset_meas(&eNB2UE[0]->random_channel);
reset_meas(&eNB2UE[0]->interp_time);
@@ -1193,7 +1196,7 @@ int main(int argc, char **argv) {
DS_TDL,
forgetting_factor,
rx_sample_offset,
- 0);
+ 0, 0);
reset_meas(&eNB2UE[n]->random_channel);
reset_meas(&eNB2UE[n]->interp_time);
}
diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c
index a585e8efc6..3b4e6782da 100644
--- a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c
+++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c
@@ -988,7 +988,7 @@ int main(int argc, char **argv)
N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
forgetting_factor,
rx_sample_offset,
- 0);
+ 0, 0);
if(num_rounds>1) {
for(n=1; n<8; n++)
@@ -999,7 +999,7 @@ int main(int argc, char **argv)
N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
forgetting_factor,
rx_sample_offset,
- 0);
+ 0, 0);
}
if (eNB2UE[0]==NULL) {
diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c
index 5973f80b55..bd164150c5 100644
--- a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c
+++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c
@@ -834,7 +834,7 @@ int main(int argc, char **argv) {
N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
forgetting_factor,
rx_sample_offset,
- 0);
+ 0, 0);
if(num_rounds>1) {
for(n=1; n<4; n++)
@@ -845,7 +845,7 @@ int main(int argc, char **argv) {
N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
forgetting_factor,
rx_sample_offset,
- 0);
+ 0, 0);
}
if (eNB2UE[0]==NULL) {
diff --git a/openair1/SIMULATION/LTE_PHY/mbmssim.c b/openair1/SIMULATION/LTE_PHY/mbmssim.c
index b1f4d933b3..78fd1a293e 100644
--- a/openair1/SIMULATION/LTE_PHY/mbmssim.c
+++ b/openair1/SIMULATION/LTE_PHY/mbmssim.c
@@ -1290,7 +1290,7 @@ int main(int argc, char **argv) {
N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
forgetting_factor,
rx_sample_offset,
- 0);
+ 0, 0);
reset_meas(&eNB2UE[0]->random_channel);
reset_meas(&eNB2UE[0]->interp_time);
@@ -1303,7 +1303,7 @@ int main(int argc, char **argv) {
N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
forgetting_factor,
rx_sample_offset,
- 0);
+ 0, 0);
reset_meas(&eNB2UE[n]->random_channel);
reset_meas(&eNB2UE[n]->interp_time);
}
diff --git a/openair1/SIMULATION/LTE_PHY/pbchsim.c b/openair1/SIMULATION/LTE_PHY/pbchsim.c
index 00ad03c52d..71286faafb 100644
--- a/openair1/SIMULATION/LTE_PHY/pbchsim.c
+++ b/openair1/SIMULATION/LTE_PHY/pbchsim.c
@@ -386,7 +386,7 @@ int main(int argc, char **argv) {
N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
0,
0,
- 0);
+ 0, 0);
if (interf1>-20)
eNB2UE1 = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx,
@@ -396,7 +396,7 @@ int main(int argc, char **argv) {
N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
0,
4,
- 0);
+ 0, 0);
if (interf2>-20)
eNB2UE2 = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx,
@@ -406,7 +406,7 @@ int main(int argc, char **argv) {
N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
0,
8,
- 0);
+ 0, 0);
if (eNB2UE==NULL) {
msg("Problem generating channel model. Exiting.\n");
diff --git a/openair1/SIMULATION/LTE_PHY/pdcchsim.c b/openair1/SIMULATION/LTE_PHY/pdcchsim.c
index 004eb24243..bd2c2d66b9 100644
--- a/openair1/SIMULATION/LTE_PHY/pdcchsim.c
+++ b/openair1/SIMULATION/LTE_PHY/pdcchsim.c
@@ -708,7 +708,7 @@ int main(int argc, char **argv) {
N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
0,
0,
- 0);
+ 0, 0);
L1_rxtx_proc_t *proc_rxtx = (subframe == 0)? &eNB->proc.L1_proc: &eNB->proc.L1_proc_tx;
eNB->ulsch[0] = new_eNB_ulsch(MAX_TURBO_ITERATIONS,N_RB_DL,0);
UE->ulsch[0] = new_ue_ulsch(N_RB_DL,0);
diff --git a/openair1/SIMULATION/LTE_PHY/prachsim.c b/openair1/SIMULATION/LTE_PHY/prachsim.c
index c997aa7639..229764a893 100644
--- a/openair1/SIMULATION/LTE_PHY/prachsim.c
+++ b/openair1/SIMULATION/LTE_PHY/prachsim.c
@@ -343,7 +343,7 @@ int main(int argc, char **argv) {
N_RB2channel_bandwidth(eNB->frame_parms.N_RB_UL),
0.0,
delay,
- 0);
+ 0, 0);
if (UE2eNB==NULL) {
msg("Problem generating channel model. Exiting.\n");
diff --git a/openair1/SIMULATION/LTE_PHY/pucchsim.c b/openair1/SIMULATION/LTE_PHY/pucchsim.c
index 127bfcb533..083a756afb 100644
--- a/openair1/SIMULATION/LTE_PHY/pucchsim.c
+++ b/openair1/SIMULATION/LTE_PHY/pucchsim.c
@@ -323,7 +323,7 @@ int main(int argc, char **argv) {
N_RB2channel_bandwidth(eNB->frame_parms.N_RB_UL),
0.0,
0,
- 0);
+ 0, 0);
if (UE2eNB==NULL) {
printf("Problem generating channel model. Exiting.\n");
diff --git a/openair1/SIMULATION/LTE_PHY/scansim.c b/openair1/SIMULATION/LTE_PHY/scansim.c
index 5ceeee7f2f..839d30a8de 100644
--- a/openair1/SIMULATION/LTE_PHY/scansim.c
+++ b/openair1/SIMULATION/LTE_PHY/scansim.c
@@ -335,7 +335,7 @@ int main(int argc, char **argv) {
N_RB2channel_bandwidth(PHY_vars_eNB->lte_frame_parms.N_RB_DL),
0,
0,
- 0);
+ 0, 0);
if (eNB2UE==NULL) {
msg("Problem generating channel model. Exiting.\n");
diff --git a/openair1/SIMULATION/LTE_PHY/syncsim.c b/openair1/SIMULATION/LTE_PHY/syncsim.c
index 80598b37e4..e8ee7d3d5e 100644
--- a/openair1/SIMULATION/LTE_PHY/syncsim.c
+++ b/openair1/SIMULATION/LTE_PHY/syncsim.c
@@ -724,7 +724,7 @@ int main(int argc, char **argv) {
BW,
0,
0,
- 0);
+ 0, 0);
if (interf1>-20)
eNB2UE1 = new_channel_desc_scm(PHY_vars_eNB->lte_frame_parms.nb_antennas_tx,
@@ -733,7 +733,7 @@ int main(int argc, char **argv) {
BW,
0,
0,
- 0);
+ 0, 0);
if (interf2>-20)
eNB2UE2 = new_channel_desc_scm(PHY_vars_eNB->lte_frame_parms.nb_antennas_tx,
@@ -742,7 +742,7 @@ int main(int argc, char **argv) {
BW,
0,
0,
- 0);
+ 0, 0);
if (eNB2UE==NULL) {
msg("Problem generating channel model. Exiting.\n");
diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c
index 80beee4bed..c6049bc31d 100644
--- a/openair1/SIMULATION/LTE_PHY/ulsim.c
+++ b/openair1/SIMULATION/LTE_PHY/ulsim.c
@@ -57,7 +57,7 @@
#include "executables/split_headers.h"
double cpuf;
-#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0))
+#define inMicroS(a) (((double)(a))/(get_cpu_freq_GHz()*1000.0))
//#define MCS_COUNT 23//added for PHY abstraction
#include
channel_desc_t *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX];
@@ -70,6 +70,9 @@ node_desc_t *ue_data[NUMBER_OF_UE_MAX];
extern uint16_t beta_ack[16],beta_ri[16],beta_cqi[16];
//extern char* namepointer_chMag ;
int xforms=0;
+THREAD_STRUCT thread_struct;
+nfapi_ue_release_request_body_t release_rntis;
+
FD_lte_phy_scope_enb *form_enb;
char title[255];
@@ -734,7 +737,7 @@ int main(int argc, char **argv) {
30e-9,
forgetting_factor,
delay,
- 0);
+ 0, 0);
// set Doppler
UE2eNB->max_Doppler = maxDoppler;
diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c
index 00983553d8..12b0b1d1f0 100644
--- a/openair1/SIMULATION/NR_PHY/dlschsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlschsim.c
@@ -339,7 +339,7 @@ int main(int argc, char **argv)
61.44e6, //N_RB2sampling_rate(N_RB_DL),
40e6, //N_RB2channel_bandwidth(N_RB_DL),
DS_TDL,
- 0, 0, 0);
+ 0, 0, 0, 0);
if (gNB2UE == NULL) {
printf("Problem generating channel model. Exiting.\n");
diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c
index 0a7ae96e09..6fb03e46b7 100644
--- a/openair1/SIMULATION/NR_PHY/dlsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlsim.c
@@ -63,7 +63,7 @@
//#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c"
#include "PHY/NR_REFSIG/ptrs_nr.h"
#include "NR_RRCReconfiguration.h"
-#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0))
+#define inMicroS(a) (((double)(a))/(get_cpu_freq_GHz()*1000.0))
#include "SIMULATION/LTE_PHY/common_sim.h"
#include
@@ -83,16 +83,23 @@ uint16_t sf_ahead=4 ;
uint16_t sl_ahead=0;
//uint8_t nfapi_mode = 0;
uint64_t downlink_frequency[MAX_NUM_CCs][4];
+THREAD_STRUCT thread_struct;
+nfapi_ue_release_request_body_t release_rntis;
+msc_interface_t msc_interface;
+
// dummy functions
int dummy_nr_ue_ul_indication(nr_uplink_indication_t *ul_info) { return(0); }
-int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id,
- const int CC_id,
- const uint8_t gNB_index,
- const int8_t channel,
- const uint8_t* pduP,
- const sdu_size_t pdu_len)
+int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id,
+ const int CC_id,
+ const uint8_t gNB_index,
+ const frame_t frame,
+ const sub_frame_t sub_frame,
+ const rnti_t rnti,
+ const channel_t channel,
+ const uint8_t* pduP,
+ const sdu_size_t pdu_len)
{
return 0;
}
@@ -195,6 +202,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); }
@@ -229,13 +238,38 @@ void nr_dlsim_preprocessor(module_id_t module_id,
sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */);
sched_ctrl->cce_index = 0;
- sched_ctrl->rbStart = g_rbStart;
- sched_ctrl->rbSize = g_rbSize;
- sched_ctrl->mcs = g_mcsIndex;
- sched_ctrl->time_domain_allocation = 2;
- sched_ctrl->mcsTableIdx = g_mcsTableIdx;
+ NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
+ const NR_ServingCellConfigCommon_t *scc = RC.nrmac[0]->common_channels[0].ServingCellConfigCommon;
+ nr_set_pdsch_semi_static(scc,
+ UE_info->secondaryCellGroup[0],
+ sched_ctrl->active_bwp,
+ /* tda = */ 2,
+ /* num_dmrs_cdm_grps_no_data = */ 1,
+ ps);
+
+ NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
+ sched_pdsch->rbStart = g_rbStart;
+ sched_pdsch->rbSize = g_rbSize;
+ sched_pdsch->mcs = g_mcsIndex;
+ /* the following might override the table that is mandated by RRC
+ * configuration */
+ ps->mcsTableIdx = g_mcsTableIdx;
+
+ sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx);
+ sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx);
+ sched_pdsch->tb_size = nr_compute_tbs(sched_pdsch->Qm,
+ sched_pdsch->R,
+ sched_pdsch->rbSize,
+ ps->nrOfSymbols,
+ ps->N_PRB_DMRS * ps->N_DMRS_SLOT,
+ 0 /* N_PRB_oh, 0 for initialBWP */,
+ 0 /* tb_scaling */,
+ 1 /* nrOfLayers */)
+ >> 3;
+
/* the simulator assumes the HARQ PID is equal to the slot number */
- sched_ctrl->dl_harq_pid = slot;
+ sched_pdsch->dl_harq_pid = slot;
+
/* The scheduler uses lists to track whether a HARQ process is
* free/busy/awaiting retransmission, and updates the HARQ process states.
* However, in the simulation, we never get ack or nack for any HARQ process,
@@ -248,13 +282,26 @@ void nr_dlsim_preprocessor(module_id_t module_id,
else
add_front_nr_list(&sched_ctrl->retrans_dl_harq, slot); // ... make PID retransmission
sched_ctrl->harq_processes[slot].is_waiting = false;
- AssertFatal(sched_ctrl->rbStart >= 0, "invalid rbStart %d\n", sched_ctrl->rbStart);
- AssertFatal(sched_ctrl->rbSize > 0, "invalid rbSize %d\n", sched_ctrl->rbSize);
- AssertFatal(sched_ctrl->mcs >= 0, "invalid sched_ctrl->mcs %d\n", sched_ctrl->mcs);
- AssertFatal(sched_ctrl->mcsTableIdx >= 0 && sched_ctrl->mcsTableIdx <= 2, "invalid sched_ctrl->mcsTableIdx %d\n", sched_ctrl->mcsTableIdx);
- sched_ctrl->numDmrsCdmGrpsNoData = 1;
+ AssertFatal(sched_pdsch->rbStart >= 0, "invalid rbStart %d\n", sched_pdsch->rbStart);
+ AssertFatal(sched_pdsch->rbSize > 0, "invalid rbSize %d\n", sched_pdsch->rbSize);
+ AssertFatal(sched_pdsch->mcs >= 0, "invalid mcs %d\n", sched_pdsch->mcs);
+ 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)
{
@@ -270,7 +317,7 @@ int main(int argc, char **argv)
//float psnr;
float eff_tp_check = 0.7;
uint8_t snrRun;
- uint32_t TBS;
+ uint32_t TBS = 0;
int **txdata;
double **s_re,**s_im,**r_re,**r_im;
//double iqim = 0.0;
@@ -627,7 +674,6 @@ int main(int argc, char **argv)
RC.nb_nr_mac_CC[i] = 1;
mac_top_init_gNB();
gNB_mac = RC.nrmac[0];
- gNB_mac->pre_processor_dl = nr_dlsim_preprocessor;
gNB_RRC_INST rrc;
memset((void*)&rrc,0,sizeof(rrc));
@@ -715,6 +761,9 @@ int main(int argc, char **argv)
rrc_mac_config_req_gNB(0,0,n_tx,1,pusch_tgt_snrx10,pucch_tgt_snrx10,scc,0,0,NULL);
// UE dedicated configuration
rrc_mac_config_req_gNB(0,0,n_tx,1,pusch_tgt_snrx10,pucch_tgt_snrx10,NULL,1,secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup);
+ // reset preprocessor to the one of DLSIM after it has been set during
+ // rrc_mac_config_req_gNB
+ gNB_mac->pre_processor_dl = nr_dlsim_preprocessor;
phy_init_nr_gNB(gNB,0,0);
N_RB_DL = gNB->frame_parms.N_RB_DL;
NR_UE_info_t *UE_info = &RC.nrmac[0]->UE_info;
@@ -767,7 +816,7 @@ int main(int argc, char **argv)
30e-9,
0,
0,
- 0);
+ 0, 0);
if (gNB2UE==NULL) {
printf("Problem generating channel model. Exiting.\n");
@@ -852,6 +901,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);
@@ -988,7 +1038,7 @@ int main(int argc, char **argv)
if (run_initial_sync)
nr_common_signal_procedures(gNB,frame,slot,gNB->ssb[0].ssb_pdu);
else
- phy_procedures_gNB_TX(gNB,frame,slot,0);
+ phy_procedures_gNB_TX(gNB,frame,slot,1);
int txdataF_offset = (slot%2) * frame_parms->samples_per_slot_wCP;
@@ -1102,7 +1152,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/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c
index ee74909a9e..c24a841c4b 100644
--- a/openair1/SIMULATION/NR_PHY/pbchsim.c
+++ b/openair1/SIMULATION/NR_PHY/pbchsim.c
@@ -66,6 +66,7 @@ uint8_t const nr_rv_round_map[4] = {0, 2, 1, 3};
uint8_t const nr_rv_round_map_ue[4] = {0, 2, 1, 3};
uint64_t get_softmodem_optmask(void) {return 0;}
+softmodem_params_t *get_softmodem_params(void) {return 0;}
void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {}
@@ -479,7 +480,7 @@ int main(int argc, char **argv)
300e-9,
0,
0,
- 0);
+ 0, 0);
if (gNB2UE==NULL) {
printf("Problem generating channel model. Exiting.\n");
diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c
index efbc40cd55..54ec6ab9da 100644
--- a/openair1/SIMULATION/NR_PHY/prachsim.c
+++ b/openair1/SIMULATION/NR_PHY/prachsim.c
@@ -37,6 +37,7 @@
#include "SCHED_NR_UE/phy_frame_config_nr.h"
#include "PHY/phy_vars_nr_ue.h"
#include "PHY/NR_REFSIG/refsig_defs_ue.h"
+#include "PHY/MODULATION/nr_modulation.h"
#include "PHY/MODULATION/modulation_eNB.h"
#include "PHY/MODULATION/modulation_UE.h"
#include "PHY/INIT/phy_init.h"
@@ -47,6 +48,7 @@
#include "OCG_vars.h"
#include
#include
+#include
//#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c"
@@ -65,10 +67,12 @@ extern uint16_t prach_root_sequence_map0_3[838];
openair0_config_t openair0_cfg[MAX_CARDS];
//uint8_t nfapi_mode=0;
uint16_t sl_ahead = 0;
+msc_interface_t msc_interface;
//void dump_nr_prach_config(NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe);
/* temporary dummy implem of get_softmodem_optmask, till basic simulators implemented as device */
+msc_interface_t msc_interface;
uint64_t get_softmodem_optmask(void) {return 0;}
softmodem_params_t *get_softmodem_params(void) {return 0;}
int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) { return(0); }
@@ -130,7 +134,18 @@ nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
return 0;
}
-int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, const int8_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) {return 0;}
+int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id,
+ const int CC_id,
+ const uint8_t gNB_index,
+ const frame_t frame,
+ const sub_frame_t sub_frame,
+ const rnti_t rnti,
+ const channel_t channel,
+ const uint8_t* pduP,
+ const sdu_size_t pdu_len)
+{
+ return 0;
+}
void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index)
{
@@ -159,13 +174,27 @@ 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;
double sigma2, sigma2_dB = 0, SNR, snr0 = -2.0, snr1 = 0.0, ue_speed0 = 0.0, ue_speed1 = 0.0;
double **s_re, **s_im, **r_re, **r_im, iqim = 0.0, delay_avg = 0, ue_speed = 0, fs, bw;
- int i, aa, aarx, **txdata, trial, n_frames = 1, prach_start, rx_prach_start; //, ntrials=1;
+ int i, l, aa, aarx, **txdata, trial, n_frames = 1, prach_start, rx_prach_start; //, ntrials=1;
int N_RB_UL = 106, delay = 0, NCS_config = 13, rootSequenceIndex = 1, threequarter_fs = 0, mu = 1, fd_occasion = 0, loglvl = OAILOG_INFO, numRA = 0, prachStartSymbol = 0;
uint8_t snr1set = 0, ue_speed1set = 0, transmission_mode = 1, n_tx = 1, n_rx = 1, awgn_flag = 0, msg1_frequencystart = 0, num_prach_fd_occasions = 1, prach_format=0;
uint8_t frame = 1, slot=19, slot_gNB=19, config_index = 98, prach_sequence_length = 1, restrictedSetConfig = 0, N_dur, N_t_slot, start_symbol;
@@ -662,7 +691,7 @@ int main(int argc, char **argv){
DS_TDL,
0.0,
delay,
- 0);
+ 0, 0);
if (UE2gNB==NULL) {
printf("Problem generating channel model. Exiting.\n");
@@ -800,7 +829,17 @@ int main(int argc, char **argv){
}
}
-
+ for (l = 0; l < frame_parms->symbols_per_slot; l++) {
+ for (aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
+ nr_slot_fep_ul(frame_parms,
+ ru->common.rxdata[aa],
+ ru->common.rxdataF[aa],
+ l,
+ slot,
+ ru->N_TA_offset);
+ }
+ }
+
rx_nr_prach_ru(ru, prach_format, numRA, prachStartSymbol, prachOccasion, frame, slot);
gNB->prach_vars.rxsigF = ru->prach_rxsigF[prachOccasion];
@@ -823,7 +862,8 @@ int main(int argc, char **argv){
LOG_M("prachF0.m","prachF0", &gNB->prach_vars.prachF[0], N_ZC, 1, 1);
LOG_M("rxsig0.m","rxs0", &gNB->common_vars.rxdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1);
LOG_M("ru_rxsig0.m","rxs0", &ru->common.rxdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1);
- LOG_M("ru_rxsigF0.m","rxsF0", ru->prach_rxsigF[0][0], N_ZC, 1, 1);
+ LOG_M("ru_rxsigF0.m","rxsF0", ru->common.rxdataF[0], frame_parms->ofdm_symbol_size*frame_parms->symbols_per_slot, 1, 1);
+ LOG_M("ru_prach_rxsigF0.m","rxsF0", ru->prach_rxsigF[0][0], N_ZC, 1, 1);
LOG_M("prach_preamble.m","prachp", &gNB->X_u[0], N_ZC, 1, 1);
LOG_M("ue_prach_preamble.m","prachp", &UE->X_u[0], N_ZC, 1, 1);
#endif
diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c
index 8d79633a6f..4cef1213c9 100644
--- a/openair1/SIMULATION/NR_PHY/pucchsim.c
+++ b/openair1/SIMULATION/NR_PHY/pucchsim.c
@@ -418,7 +418,7 @@ int main(int argc, char **argv)
printf("FFO = %lf; IFO = %d\n",eps-IFO,IFO);
}
- UE2gNB = new_channel_desc_scm(n_tx, n_rx, channel_model, fs, bw, DS_TDL,0, 0, 0);
+ UE2gNB = new_channel_desc_scm(n_tx, n_rx, channel_model, fs, bw, DS_TDL,0, 0, 0, 0);
if (UE2gNB==NULL) {
printf("Problem generating channel model. Exiting.\n");
diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c
index 6f2af73a1d..f84e553683 100644
--- a/openair1/SIMULATION/NR_PHY/ulschsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulschsim.c
@@ -364,7 +364,7 @@ int main(int argc, char **argv)
61.44e6, //N_RB2sampling_rate(N_RB_DL),
40e6, //N_RB2channel_bandwidth(N_RB_DL),
DS_TDL,
- 0,0,0);
+ 0,0,0, 0);
if (gNB2UE == NULL) {
printf("Problem generating channel model. Exiting.\n");
diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c
index fce690ebd2..e28f404f21 100644
--- a/openair1/SIMULATION/NR_PHY/ulsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulsim.c
@@ -57,7 +57,7 @@
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
#include "common/utils/threadPool/thread-pool.h"
#include "PHY/NR_REFSIG/ptrs_nr.h"
-#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0))
+#define inMicroS(a) (((double)(a))/(get_cpu_freq_GHz()*1000.0))
#include "SIMULATION/LTE_PHY/common_sim.h"
#include
@@ -81,11 +81,25 @@ uint16_t sl_ahead=0;
double cpuf;
//uint8_t nfapi_mode = 0;
uint64_t downlink_frequency[MAX_NUM_CCs][4];
+THREAD_STRUCT thread_struct;
+nfapi_ue_release_request_body_t release_rntis;
+msc_interface_t msc_interface;
extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration
-int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index,
- const int8_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) { return 0; }
+int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id,
+ const int CC_id,
+ const uint8_t gNB_index,
+ const frame_t frame,
+ const sub_frame_t sub_frame,
+ const rnti_t rnti,
+ const channel_t channel,
+ const uint8_t* pduP,
+ const sdu_size_t pdu_len)
+{
+ return 0;
+}
+
int generate_dlsch_header(unsigned char *mac_header,
unsigned char num_sdus,
unsigned short *sdu_lengths,
@@ -184,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];
@@ -593,7 +620,7 @@ int main(int argc, char **argv)
sampling_frequency,
bandwidth,
DS_TDL,
- 0, 0, 0);
+ 0, 0, 0, 0);
if (UE2gNB == NULL) {
printf("Problem generating channel model. Exiting.\n");
@@ -1156,7 +1183,6 @@ int main(int argc, char **argv)
gNB->UL_INFO.rx_ind.number_of_pdus = 0;
gNB->UL_INFO.crc_ind.number_crcs = 0;
- start_meas(&gNB->phy_proc_rx);
phy_procedures_gNB_common_RX(gNB, frame, slot);
phy_procedures_gNB_uespec_RX(gNB, frame, slot);
@@ -1188,7 +1214,6 @@ int main(int argc, char **argv)
LOG_M("rxsigF0_llr.m","rxsF0_llr",
&gNB->pusch_vars[0]->llr[0],(nb_symb_sch-1)*NR_NB_SC_PER_RB * pusch_pdu->rb_size * mod_order,1,0);
}
- start_meas(&gNB->phy_proc_rx);
////////////////////////////////////////////////////////////
if (gNB->ulsch[0][0]->last_iteration_cnt >=
diff --git a/openair1/SIMULATION/TOOLS/DOC/arch.md b/openair1/SIMULATION/TOOLS/DOC/arch.md
new file mode 100644
index 0000000000..30be337829
--- /dev/null
+++ b/openair1/SIMULATION/TOOLS/DOC/arch.md
@@ -0,0 +1,9 @@
+# Channel simulation source files
+
+1. [random_channel.c](../random_channel.c)
+1. [sim.h](../sim.h)
+
+
+
+[channel simulation main page](channel_simulation.md)
+[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
\ No newline at end of file
diff --git a/openair1/SIMULATION/TOOLS/DOC/channel_simulation.md b/openair1/SIMULATION/TOOLS/DOC/channel_simulation.md
new file mode 100644
index 0000000000..be2b987b40
--- /dev/null
+++ b/openair1/SIMULATION/TOOLS/DOC/channel_simulation.md
@@ -0,0 +1,13 @@
+# OAI channel simulation feature
+
+oai includes a channel simulation feature that any component can use to alter time domain samples of a RF channel by applying pre-defined models as defined, for example, in 3GPP TR 36.873 or TR 38.901
+
+Definition, configuration and run-time modification of a channel model are implemented in common code included in UEs, gNb, eNB and used when running with the rfsimulator or the L1 simulator. Phy simulators are also using channel simulation but configuration is done via dedicated command line options. The rfsimulator is the only option to get access to all the configurations and run-time modifications features of oai channel simulation.
+
+## Documentation
+
+* [runtime usage](rtusage.md)
+* [developer usage](devusage.md)
+* [module architecture](arch.md)
+
+[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
diff --git a/openair1/SIMULATION/TOOLS/DOC/devusage.md b/openair1/SIMULATION/TOOLS/DOC/devusage.md
new file mode 100644
index 0000000000..8fa6b3fe7a
--- /dev/null
+++ b/openair1/SIMULATION/TOOLS/DOC/devusage.md
@@ -0,0 +1,7 @@
+### channel simulation developer usage
+
+
+[Configuring the channel simulation](rtusage.md)
+
+[channel simulation main page](channel_simulation.md)
+[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
\ No newline at end of file
diff --git a/openair1/SIMULATION/TOOLS/DOC/rtusage.md b/openair1/SIMULATION/TOOLS/DOC/rtusage.md
new file mode 100644
index 0000000000..37fc62b496
--- /dev/null
+++ b/openair1/SIMULATION/TOOLS/DOC/rtusage.md
@@ -0,0 +1,69 @@
+## configuring the channel simulation
+Oai channel simulation is using the [config module](../../../config/config.md) to get its parameters at init time. The [telnet server](../../telnetsrv/DOC/telnetsrv.md) includes a set of commands which can be used to dynamically modify some channel model parameters
+
+All channel simulation parameters are defined in the `channelmod` section. Most parameters are specific to a channel model and are only used by the rfsimulator.
+
+### global parameters
+
+| name | type | default | description |
+|:---:|:---:|:---:|:----|
+| `max_chan` | integer | `25` | Maximum number of channel model that can be defined in the system. Must be greater than the number of model definitions in the model list loaded at init time. |
+| `modellist` | character string | `DefaultChannelList` | Name of the channel models list to load at init time. |
+
+### Model lists
+
+Several model lists can be defined in the oai configuration file. One, defined by the `modellist` parameter is loaded at init time. In the configuration file each model list item describes a channel model using a group of parameters:
+
+| parameter name | type | default | description |
+|:---:|:---:|:---:|:----|
+| `model name` | character string | mandatory |name of the model, as used in the code to retrieve a model definition|
+| `type` | | `AWGN` | name of the channel modelization algorithm applied on rf signal. The list of available model types can be listed via the [telnet server](../../telnetsrv/DOC/telnetsrv.md) or by entering an invalid type name |
+| `ploss_dB` | real (float) | | path loss of the channel, in dB |
+| `noise_power_dB` | real (double) | | noise of the channel in dB |
+| `forgetfact` | real (double) | | |
+| `offset` | integer | | |
+| `ds_tdl` | real double | | |
+
+Channel simulation parameters can also be specified on the command line:
+
+```bash
+./lte-softmodem -O ../../../ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf --noS1 --rfsim --rfsimulator.options chanmod --rfsimulator.serveraddr enb --telnetsrv --channelmod.modellist modellist_rfsimu_2 --channelmod.modellist_rfsimu_2.[1].offset 120
+```
+### Using the telnet server to modify channel simulator parameters
+The telnet server includes a `channelmod` command which can be used to dynamically modify some channel model parameters. This command is only available when channel simulation is enabled (via `rfsimulator.options chanmod` option when running the rfsimulator. `channelmod` command has its own help:
+
+```
+$ telnet 127.0.0.1 9090
+Trying 127.0.0.1...
+Connected to 127.0.0.1.
+Escape character is '^]'.
+
+softmodem_enb> help
+.....................................
+ module 6 = channelmod:
+ channelmod help
+ channelmod show
+ channelmod modify
+ module 7 = rfsimu:
+ rfsimu setmodel
+softmodem_enb> channelmod help
+channelmod commands can be used to display or modify channel models parameters
+channelmod show predef: display predefined model algorithms available in oai
+channelmod show current: display the currently used models in the running executable
+channelmod modify : set the specified parameters in a current model to the given value
+ specifies the model, the show current model command can be used to list the current models indexes
+ can be one of "riceanf", "aoa", "randaoa", "ploss", "noise_power_dB", "offset", "forgetf"
+softmodem_enb>
+
+```
+
+
+
+
+
+
+
+The [rfsimulator documentation](../../../../targets/ARCH/rfsimulator/README.md ) has also some specific information when using the channel simulation via this tool.
+
+[channel simulation main page](channel_simulation.md)
+[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
\ No newline at end of file
diff --git a/openair1/SIMULATION/TOOLS/phase_noise.c b/openair1/SIMULATION/TOOLS/phase_noise.c
index 5958a0ccdd..6cc24f23db 100644
--- a/openair1/SIMULATION/TOOLS/phase_noise.c
+++ b/openair1/SIMULATION/TOOLS/phase_noise.c
@@ -26,6 +26,7 @@
#include "sim.h"
+static uint16_t LUTSin[ResolSinCos+1];
/* linear phase noise model */
void phase_noise(double ts, int16_t * InRe, int16_t * InIm)
{
diff --git a/openair1/SIMULATION/TOOLS/random_channel.c b/openair1/SIMULATION/TOOLS/random_channel.c
index 47597f4d6e..4e26d9a954 100644
--- a/openair1/SIMULATION/TOOLS/random_channel.c
+++ b/openair1/SIMULATION/TOOLS/random_channel.c
@@ -50,7 +50,7 @@ static int channelmod_print_help(char *buff, int debug, telnet_printfunc_t prnt)
static telnetshell_cmddef_t channelmod_cmdarray[] = {
{"help","",channelmod_print_help},
{"show","",channelmod_show_cmd},
- {"modify"," ",channelmod_modify_cmd},
+ {"modify"," ",channelmod_modify_cmd},
{"","",NULL},
};
@@ -62,13 +62,16 @@ static double snr_dB=25;
static double sinr_dB=0;
static unsigned int max_chan;
static channel_desc_t **defined_channels;
+static char modellist_name[MAX_OPTNAME_SIZE]= {0};
+
+
void fill_channel_desc(channel_desc_t *chan_desc,
uint8_t nb_tx,
uint8_t nb_rx,
uint8_t nb_taps,
uint8_t channel_length,
double *amps,
- double *delays,
+ double *delays,
struct complex **R_sqrt,
double Td,
double sampling_rate,
@@ -136,8 +139,10 @@ void fill_channel_desc(channel_desc_t *chan_desc,
if (R_sqrt == NULL) {
chan_desc->R_sqrt = (struct complex **) calloc(nb_taps,sizeof(struct complex *));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_NTAPS ;
+
for (i = 0; iR_sqrt[i] = (struct complex *) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex));
+ chan_desc->R_sqrt[i] = (struct complex *) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex));
+
for (j = 0; jR_sqrt[i][j].x = 1.0;
chan_desc->R_sqrt[i][j].y = 0.0;
@@ -145,7 +150,7 @@ void fill_channel_desc(channel_desc_t *chan_desc,
}
} else {
chan_desc->R_sqrt = (struct complex **) calloc(nb_taps,sizeof(struct complex *));
-
+
for (i = 0; iR_sqrt[i] = (struct complex*) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex));
//chan_desc->R_sqrt = (struct complex*)&R_sqrt[i][0];
@@ -175,224 +180,229 @@ void fill_channel_desc(channel_desc_t *chan_desc,
double mbsfn_delays[] = {0,.03,.15,.31,.37,1.09,12.490,12.52,12.64,12.80,12.86,13.58,27.49,27.52,27.64,27.80,27.86,28.58};
double mbsfn_amps_dB[] = {0,-1.5,-1.4,-3.6,-0.6,-7.0,-10,-11.5,-11.4,-13.6,-10.6,-17.0,-20,-21.5,-21.4,-23.6,-20.6,-27};
-double scm_c_delays[] = {0, 0.0125, 0.0250, 0.3625, 0.3750, 0.3875, 0.2500, 0.2625, 0.2750, 1.0375, 1.0500, 1.0625, 2.7250, 2.7375, 2.7500, 4.6000, 4.6125, 4.6250};
+double scm_c_delays[] = {0, 0.0125, 0.0250, 0.3625, 0.3750, 0.3875, 0.2500, 0.2625, 0.2750, 1.0375, 1.0500, 1.0625, 2.7250, 2.7375, 2.7500, 4.6000, 4.6125, 4.6250};
double scm_c_amps_dB[] = {0.00, -2.22, -3.98, -1.86, -4.08, -5.84, -1.08, -3.30, -5.06, -9.08, -11.30, -13.06, -15.14, -17.36, -19.12, -20.64, -22.85, -24.62};
double tdl_a_delays[] = {0.0000,
- 0.3819,
- 0.4025,
- 0.5868,
- 0.4610,
- 0.5375,
- 0.6708,
- 0.5750,
- 0.7618,
- 1.5375,
- 1.8978,
- 2.2242,
- 2.1718,
- 2.4942,
- 2.5119,
- 3.0582,
- 4.0810,
- 4.4579,
- 4.5695,
- 4.7966,
- 5.0066,
- 5.3043,
- 9.6586};
+ 0.3819,
+ 0.4025,
+ 0.5868,
+ 0.4610,
+ 0.5375,
+ 0.6708,
+ 0.5750,
+ 0.7618,
+ 1.5375,
+ 1.8978,
+ 2.2242,
+ 2.1718,
+ 2.4942,
+ 2.5119,
+ 3.0582,
+ 4.0810,
+ 4.4579,
+ 4.5695,
+ 4.7966,
+ 5.0066,
+ 5.3043,
+ 9.6586
+ };
double tdl_a_amps_dB[] = {-13.4,
- 0,
- -2.2,
- -4,
- -6,
- -8.2,
- -9.9,
- -10.5,
- -7.5,
- -15.9,
- -6.6,
- -16.7,
- -12.4,
- -15.2,
- -10.8,
- -11.3,
- -12.7,
- -16.2,
- -18.3,
- -18.9,
- -16.6,
- -19.9,
- -29.7};
-#define TDL_A_PATHS 23
+ 0,
+ -2.2,
+ -4,
+ -6,
+ -8.2,
+ -9.9,
+ -10.5,
+ -7.5,
+ -15.9,
+ -6.6,
+ -16.7,
+ -12.4,
+ -15.2,
+ -10.8,
+ -11.3,
+ -12.7,
+ -16.2,
+ -18.3,
+ -18.9,
+ -16.6,
+ -19.9,
+ -29.7
+ };
double tdl_b_delays[] = {0.0000,
- 0.1072,
- 0.2155,
- 0.2095,
- 0.2870,
- 0.2986,
- 0.3752,
- 0.5055,
- 0.3681,
- 0.3697,
- 0.5700,
- 0.5283,
- 1.1021,
- 1.2756,
- 1.5474,
- 1.7842,
- 2.0169,
- 2.8294,
- 3.0219,
- 3.6187,
- 4.1067,
- 4.2790,
- 4.7834};
+ 0.1072,
+ 0.2155,
+ 0.2095,
+ 0.2870,
+ 0.2986,
+ 0.3752,
+ 0.5055,
+ 0.3681,
+ 0.3697,
+ 0.5700,
+ 0.5283,
+ 1.1021,
+ 1.2756,
+ 1.5474,
+ 1.7842,
+ 2.0169,
+ 2.8294,
+ 3.0219,
+ 3.6187,
+ 4.1067,
+ 4.2790,
+ 4.7834
+ };
double tdl_b_amps_dB[] = {0,
- -2.2,
- -4,
- -3.2,
- -9.8,
- -1.2,
- -3.4,
- -5.2,
- -7.6,
- -3,
- -8.9,
- -9,
- -4.8,
- -5.7,
- -7.5,
- -1.9,
- -7.6,
- -12.2,
- -9.8,
- -11.4,
- -14.9,
- -9.2,
- -11.3};
-#define TDL_B_PATHS 23
+ -2.2,
+ -4,
+ -3.2,
+ -9.8,
+ -1.2,
+ -3.4,
+ -5.2,
+ -7.6,
+ -3,
+ -8.9,
+ -9,
+ -4.8,
+ -5.7,
+ -7.5,
+ -1.9,
+ -7.6,
+ -12.2,
+ -9.8,
+ -11.4,
+ -14.9,
+ -9.2,
+ -11.3
+ };
double tdl_c_delays[] = {0,
- 0.2099,
- 0.2219,
- 0.2329,
- 0.2176,
- 0.6366,
- 0.6448,
- 0.6560,
- 0.6584,
- 0.7935,
- 0.8213,
- 0.9336,
- 1.2285,
- 1.3083,
- 2.1704,
- 2.7105,
- 4.2589,
- 4.6003,
- 5.4902,
- 5.6077,
- 6.3065,
- 6.6374,
- 7.0427,
- 8.6523};
+ 0.2099,
+ 0.2219,
+ 0.2329,
+ 0.2176,
+ 0.6366,
+ 0.6448,
+ 0.6560,
+ 0.6584,
+ 0.7935,
+ 0.8213,
+ 0.9336,
+ 1.2285,
+ 1.3083,
+ 2.1704,
+ 2.7105,
+ 4.2589,
+ 4.6003,
+ 5.4902,
+ 5.6077,
+ 6.3065,
+ 6.6374,
+ 7.0427,
+ 8.6523
+ };
double tdl_c_amps_dB[] = {-4.4,
- -1.2,
- -3.5,
- -5.2,
- -2.5,
- 0,
- -2.2,
- -3.9,
- -7.4,
- -7.1,
- -10.7,
- -11.1,
- -5.1,
- -6.8,
- -8.7,
- -13.2,
- -13.9,
- -13.9,
- -15.8,
- -17.1,
- -16,
- -15.7,
- -21.6,
- -22.8};
-#define TDL_C_PATHS 24
+ -1.2,
+ -3.5,
+ -5.2,
+ -2.5,
+ 0,
+ -2.2,
+ -3.9,
+ -7.4,
+ -7.1,
+ -10.7,
+ -11.1,
+ -5.1,
+ -6.8,
+ -8.7,
+ -13.2,
+ -13.9,
+ -13.9,
+ -15.8,
+ -17.1,
+ -16,
+ -15.7,
+ -21.6,
+ -22.8
+ };
double tdl_d_delays[] = {//0,
- 0,
- 0.035,
- 0.612,
- 1.363,
- 1.405,
- 1.804,
- 2.596,
- 1.775,
- 4.042,
- 7.937,
- 9.424,
- 9.708,
- 12.525};
+ 0,
+ 0.035,
+ 0.612,
+ 1.363,
+ 1.405,
+ 1.804,
+ 2.596,
+ 1.775,
+ 4.042,
+ 7.937,
+ 9.424,
+ 9.708,
+ 12.525
+};
double tdl_d_amps_dB[] = {//-0.2,
-//-13.5,
- -.00147,
- -18.8,
- -21,
- -22.8,
- -17.9,
- -20.1,
- -21.9,
- -22.9,
- -27.8,
- -23.6,
- -24.8,
- -30.0,
- -27.7};
+ //-13.5,
+ -.00147,
+ -18.8,
+ -21,
+ -22.8,
+ -17.9,
+ -20.1,
+ -21.9,
+ -22.9,
+ -27.8,
+ -23.6,
+ -24.8,
+ -30.0,
+ -27.7
+ };
-#define TDL_D_PATHS 13
#define TDL_D_RICEAN_FACTOR .046774
double tdl_e_delays[] = {0,
- 0.5133,
- 0.5440,
- 0.5630,
- 0.5440,
- 0.7112,
- 1.9092,
- 1.9293,
- 1.9589,
- 2.6426,
- 3.7136,
- 5.4524,
- 12.0034,
- 20.6519};
+ 0.5133,
+ 0.5440,
+ 0.5630,
+ 0.5440,
+ 0.7112,
+ 1.9092,
+ 1.9293,
+ 1.9589,
+ 2.6426,
+ 3.7136,
+ 5.4524,
+ 12.0034,
+ 20.6519
+ };
double tdl_e_amps_dB[] = {//-0.03,
- //-22.03,
- -.00433,
- -15.8,
- -18.1,
- -19.8,
- -22.9,
- -22.4,
- -18.6,
- -20.8,
- -22.6,
- -22.3,
- -25.6,
- -20.2,
- -29.8,
- -29.2};
+ //-22.03,
+ -.00433,
+ -15.8,
+ -18.1,
+ -19.8,
+ -22.9,
+ -22.4,
+ -18.6,
+ -20.8,
+ -22.6,
+ -22.3,
+ -25.6,
+ -20.2,
+ -29.8,
+ -29.2
+ };
-#define TDL_E_PATHS 14
#define TDL_E_RICEAN_FACTOR 0.0063096
double epa_delays[] = { 0,.03,.07,.09,.11,.19,.41};
@@ -494,31 +504,101 @@ struct complex *R_sqrt_22_EPA_medium[1] = {R_sqrt_22_EPA_medium_tap};
//Rayleigh1_orth_eff_ch_TM4
+void tdlModel(int tdl_paths, double *tdl_delays, double *tdl_amps_dB, double DS_TDL, channel_desc_t *chan_desc ) {
+ int nb_rx=chan_desc-> nb_rx;
+ int nb_tx=chan_desc-> nb_tx;
+ int tdl_pathsby3 = tdl_paths/3;
+
+ if ((tdl_paths%3)>0)
+ tdl_pathsby3++;
+
+ chan_desc->nb_taps = tdl_paths;
+ chan_desc->Td = tdl_delays[tdl_paths-1]*DS_TDL;
+ printf("last path (%d) at %f * %e = %e\n",tdl_paths-1,tdl_delays[tdl_paths-1],DS_TDL,chan_desc->Td);
+ chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td +
+ 1 +
+ 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td));
+ printf("TDL : %f Ms/s, nb_taps %d, Td %e, channel_length %d\n",chan_desc->sampling_rate,tdl_paths,chan_desc->Td,chan_desc->channel_length);
+ double sum_amps = 0;
+ chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
+
+ for (int i = 0; inb_taps; i++) {
+ chan_desc->amps[i] = pow(10,.1*tdl_amps_dB[i]);
+ sum_amps += chan_desc->amps[i];
+ }
+
+ for (int i = 0; inb_taps; i++) {
+ chan_desc->amps[i] /= sum_amps;
+ tdl_delays[i] *= DS_TDL;
+ }
+
+ chan_desc->delays = tdl_delays;
+ chan_desc->aoa = 0;
+ chan_desc->random_aoa = 0;
+ chan_desc->ch = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *));
+ chan_desc->chF = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *));
+ chan_desc->a = (struct complex **) malloc(chan_desc->nb_taps*sizeof(struct complex *));
+
+ for (int i = 0; ich[i] = (struct complex *) malloc(chan_desc->channel_length * sizeof(struct complex));
+
+ for (int i = 0; ichF[i] = (struct complex *) malloc(1200 * sizeof(struct complex));
+
+ for (int i = 0; inb_taps; i++)
+ chan_desc->a[i] = (struct complex *) malloc(nb_tx*nb_rx * sizeof(struct complex));
+
+ chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **));
+
+ if (nb_tx==2 && nb_rx==2) {
+ for (int i = 0; i<(tdl_pathsby3); i++)
+ chan_desc->R_sqrt[i] = (struct complex *) &R22_sqrt[i][0];
+ } else if (nb_tx==2 && nb_rx==1) {
+ for (int i = 0; i<(tdl_pathsby3); i++)
+ chan_desc->R_sqrt[i] = (struct complex *) &R21_sqrt[i][0];
+ } else if (nb_tx==1 && nb_rx==2) {
+ for (int i = 0; i<(tdl_pathsby3); i++)
+ chan_desc->R_sqrt[i] = (struct complex *) &R12_sqrt[i][0];
+ } else {
+ for (int i = 0; i<(tdl_pathsby3); i++) {
+ chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex));
+
+ for (int j = 0; jR_sqrt[i][j].x = 1.0;
+ chan_desc->R_sqrt[i][j].y = 0.0;
+ }
+
+ LOG_W(OCM,"correlation matrix not implemented for nb_tx==%d and nb_rx==%d, using identity\n", nb_tx, nb_rx);
+ }
+ }
+}
+
channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
uint8_t nb_rx,
SCM_t channel_model,
double sampling_rate,
double channel_bandwidth,
- double DS_TDL,
+ double DS_TDL,
double forgetting_factor,
int32_t channel_offset,
- double path_loss_dB) {
+ double path_loss_dB,
+ float noise_power_dB) {
channel_desc_t *chan_desc = (channel_desc_t *)calloc(1,sizeof(channel_desc_t));
- for(int i=0; ichan_idx=i;
- break;
- }
- else {
- AssertFatal(i<(max_chan-1),
- "No more channel descriptors available, increase channelmod.max_chan parameter above %u\n",max_chan);
- }
+
+ for(int i=0; ichan_idx=i;
+ break;
+ } else {
+ AssertFatal(i<(max_chan-1),
+ "No more channel descriptors available, increase channelmod.max_chan parameter above %u\n",max_chan);
+ }
}
+
uint16_t i,j;
double sum_amps;
double aoa,ricean_factor,Td,maxDoppler;
-
int channel_length,nb_taps;
chan_desc->modelid = channel_model;
chan_desc->nb_tx = nb_tx;
@@ -530,13 +610,13 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->path_loss_dB = path_loss_dB;
chan_desc->first_run = 1;
chan_desc->ip = 0.0;
+ chan_desc->noise_power_dB = noise_power_dB;
LOG_I(OCM,"Channel Model (inside of new_channel_desc_scm)=%d\n\n", channel_model);
-
int tdl_paths=0;
- double tdl_ricean_factor = 1;
double *tdl_amps_dB;
double *tdl_delays;
+ /* Spatial Channel Models (SCM) channel model from TR 38.901 Section 7.7.2 */
switch (channel_model) {
case SCM_A:
LOG_W(OCM,"channel model not yet supported\n");
@@ -554,7 +634,8 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td));
sum_amps = 0;
chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
- chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
+ chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
+
for (i = 0; inb_taps; i++) {
chan_desc->amps[i] = pow(10,.1*scm_c_amps_dB[i]);
sum_amps += chan_desc->amps[i];
@@ -592,10 +673,11 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
for (i = 0; i<6; i++)
chan_desc->R_sqrt[i] = (struct complex *) &R12_sqrt[i][0];
} else {
- chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ;
+ chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ;
+
for (i = 0; i<6; i++) {
chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex));
-
+
for (j = 0; jR_sqrt[i][j].x = 1.0;
chan_desc->R_sqrt[i][j].y = 0.0;
@@ -615,6 +697,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
sum_amps = 0;
chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
+
for (i = 0; inb_taps; i++) {
chan_desc->amps[i] = pow(10,.1*scm_c_amps_dB[i]);
sum_amps += chan_desc->amps[i];
@@ -652,7 +735,8 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
for (i = 0; i<6; i++)
chan_desc->R_sqrt[i] = (struct complex *) &R12_sqrt[i][0];
} else {
- chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ;
+ chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ;
+
for (i = 0; i<6; i++) {
chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex));
@@ -666,99 +750,41 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
}
break;
-
+ /* tapped delay line (TDL) channel model from TR 38.901 Section 7.7.2 */
+#define tdl_m(MoDel)\
+ DevAssert(sizeof(tdl_ ## MoDel ## _amps_dB) == sizeof(tdl_ ## MoDel ## _delays)); \
+ tdl_paths=sizeof(tdl_ ## MoDel ## _amps_dB)/sizeof(*tdl_ ## MoDel ## _amps_dB);\
+ tdl_delays=tdl_ ## MoDel ## _delays;\
+ tdl_amps_dB=tdl_ ## MoDel ## _amps_dB
+
case TDL_A:
+ chan_desc->ricean_factor = 1;
+ tdl_m(a);
+ tdlModel(tdl_paths, tdl_delays, tdl_amps_dB, DS_TDL, chan_desc);
+ break;
+
case TDL_B:
- case TDL_C:
- case TDL_D:
+ chan_desc->ricean_factor = 1;
+ tdl_m(b);
+ tdlModel(tdl_paths, tdl_delays, tdl_amps_dB, DS_TDL, chan_desc);
+ break;
+
+ case TDL_C:
+ chan_desc->ricean_factor = 1;
+ tdl_m(c);
+ tdlModel(tdl_paths, tdl_delays, tdl_amps_dB, DS_TDL, chan_desc);
+ break;
+
+ case TDL_D:
+ chan_desc->ricean_factor = TDL_D_RICEAN_FACTOR;
+ tdl_m(d);
+ tdlModel(tdl_paths, tdl_delays, tdl_amps_dB, DS_TDL, chan_desc);
+ break;
+
case TDL_E:
- if (channel_model == TDL_A) {
- tdl_paths=TDL_A_PATHS;
- tdl_delays=tdl_a_delays;
- tdl_amps_dB=tdl_a_amps_dB;
- }else if (channel_model == TDL_B) {
- tdl_paths=TDL_B_PATHS;
- tdl_delays=tdl_b_delays;
- tdl_amps_dB=tdl_b_amps_dB;
- }
- else if (channel_model == TDL_C) {
- tdl_paths=TDL_C_PATHS;
- tdl_delays=tdl_c_delays;
- tdl_amps_dB=tdl_c_amps_dB;
- printf("Initializing TDL_C channel with %d paths\n",TDL_C_PATHS);
- } else if (channel_model == TDL_D) {
- tdl_paths=TDL_D_PATHS;
- tdl_delays=tdl_d_delays;
- tdl_amps_dB=tdl_d_amps_dB;
- tdl_ricean_factor = TDL_D_RICEAN_FACTOR;
- } else if (channel_model == TDL_E) {
- tdl_paths=TDL_E_PATHS-1;
- tdl_delays=tdl_e_delays+1;
- tdl_amps_dB=tdl_e_amps_dB;
- tdl_ricean_factor = TDL_E_RICEAN_FACTOR;
- }
-
- int tdl_pathsby3 = tdl_paths/3;
- if ((tdl_paths%3)>0) tdl_pathsby3++;
-
- chan_desc->nb_taps = tdl_paths;
- chan_desc->Td = tdl_delays[tdl_paths-1]*DS_TDL;
- printf("last path (%d) at %f * %e = %e\n",tdl_paths-1,tdl_delays[tdl_paths-1],DS_TDL,chan_desc->Td);
- chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td));
- printf("TDL : %f Ms/s, nb_taps %d, Td %e, channel_length %d\n",chan_desc->sampling_rate,tdl_paths,chan_desc->Td,chan_desc->channel_length);
- sum_amps = 0;
- chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
-
- for (i = 0; inb_taps; i++) {
- chan_desc->amps[i] = pow(10,.1*tdl_amps_dB[i]);
- sum_amps += chan_desc->amps[i];
- }
-
- for (i = 0; inb_taps; i++) {
- chan_desc->amps[i] /= sum_amps;
- tdl_delays[i] *= DS_TDL;
- }
- chan_desc->delays = tdl_delays;
- chan_desc->ricean_factor = tdl_ricean_factor;
- chan_desc->aoa = 0;
- chan_desc->random_aoa = 0;
- chan_desc->ch = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *));
- chan_desc->chF = (struct complex **) malloc(nb_tx*nb_rx*sizeof(struct complex *));
- chan_desc->a = (struct complex **) malloc(chan_desc->nb_taps*sizeof(struct complex *));
-
- for (i = 0; ich[i] = (struct complex *) malloc(chan_desc->channel_length * sizeof(struct complex));
-
- for (i = 0; ichF[i] = (struct complex *) malloc(1200 * sizeof(struct complex));
-
- for (i = 0; inb_taps; i++)
- chan_desc->a[i] = (struct complex *) malloc(nb_tx*nb_rx * sizeof(struct complex));
-
- chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **));
-
- if (nb_tx==2 && nb_rx==2) {
- for (i = 0; i<(tdl_pathsby3); i++)
- chan_desc->R_sqrt[i] = (struct complex *) &R22_sqrt[i][0];
- } else if (nb_tx==2 && nb_rx==1) {
- for (i = 0; i<(tdl_pathsby3); i++)
- chan_desc->R_sqrt[i] = (struct complex *) &R21_sqrt[i][0];
- } else if (nb_tx==1 && nb_rx==2) {
- for (i = 0; i<(tdl_pathsby3); i++)
- chan_desc->R_sqrt[i] = (struct complex *) &R12_sqrt[i][0];
- } else {
- for (i = 0; i<(tdl_pathsby3); i++) {
- chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex));
-
- for (j = 0; jR_sqrt[i][j].x = 1.0;
- chan_desc->R_sqrt[i][j].y = 0.0;
- }
-
- LOG_W(OCM,"correlation matrix not implemented for nb_tx==%d and nb_rx==%d, using identity\n", nb_tx, nb_rx);
- }
- }
-
+ chan_desc->ricean_factor = TDL_E_RICEAN_FACTOR;
+ tdl_m(e);
+ tdlModel(tdl_paths, tdl_delays, tdl_amps_dB, DS_TDL, chan_desc);
break;
case EPA:
@@ -768,6 +794,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
sum_amps = 0;
chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
+
for (i = 0; inb_taps; i++) {
chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]);
sum_amps += chan_desc->amps[i];
@@ -786,7 +813,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
for (i = 0; ich[i] = (struct complex *) malloc(chan_desc->channel_length * sizeof(struct complex));
-
+
for (i = 0; ichF[i] = (struct complex *) malloc(1200 * sizeof(struct complex));
@@ -801,6 +828,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
} else {
chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ;
+
for (i = 0; i<6; i++) {
chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex));
@@ -822,6 +850,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
sum_amps = 0;
chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
+
for (i = 0; inb_taps; i++) {
chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]);
sum_amps += chan_desc->amps[i];
@@ -867,7 +896,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n");
}
}*/
- break;
+ break;
case EPA_high:
chan_desc->nb_taps = 7;
@@ -876,6 +905,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
sum_amps = 0;
chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
+
for (i = 0; inb_taps; i++) {
chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]);
sum_amps += chan_desc->amps[i];
@@ -929,7 +959,8 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td));
sum_amps = 0;
chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
- chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
+ chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
+
for (i = 0; inb_taps; i++) {
chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]);
sum_amps += chan_desc->amps[i];
@@ -984,6 +1015,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
sum_amps = 0;
chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
+
for (i = 0; inb_taps; i++) {
chan_desc->amps[i] = pow(10,.1*eva_amps_dB[i]);
sum_amps += chan_desc->amps[i];
@@ -1017,7 +1049,8 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
} else {
chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ;
- for (i = 0; i<6; i++) {
+
+ for (i = 0; i<6; i++) {
chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex));
for (j = 0; jamps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
+
for (i = 0; inb_taps; i++) {
chan_desc->amps[i] = pow(10,.1*etu_amps_dB[i]);
sum_amps += chan_desc->amps[i];
@@ -1071,6 +1105,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
} else {
chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ;
+
for (i = 0; i<6; i++) {
chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex));
@@ -1092,6 +1127,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
sum_amps = 0;
chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ;
+
for (i = 0; inb_taps; i++) {
chan_desc->amps[i] = pow(10,.1*mbsfn_amps_dB[i]);
sum_amps += chan_desc->amps[i];
@@ -1119,6 +1155,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex *));
chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6;
+
for (i = 0; i<6; i++) {
chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex));
@@ -1628,38 +1665,65 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
chan_desc->nb_paths = 10;
return(chan_desc);
-}
-
+} /* channel_desc_t *new_channel_desc_scm */
+
+channel_desc_t *find_channel_desc_fromname( char *modelname ) {
+ for(int i=0; imodel_name,modelname) == 0)
+ return defined_channels[i];
+ }
+ }
+
+ LOG_E(OCM,"Model %s not found \n", modelname);
+ return NULL;
+} /* channel_desc_t * new_channel_desc_fromconfig */
+
+
+
void free_channel_desc_scm(channel_desc_t *ch) {
// Must be made cleanly, a lot of leaks...
if (max_chan != 0) defined_channels[ch->chan_idx]=NULL;
if(ch->free_flags&CHANMODEL_FREE_AMPS)
free(ch->amps);
- for (int i = 0; inb_tx*ch->nb_rx; i++) {
+
+ for (int i = 0; inb_tx*ch->nb_rx; i++) {
free(ch->ch[i]);
free(ch->chF[i]);
}
-
+
for (int i = 0; inb_taps; i++) {
- free(ch->a[i]);
- }
+ free(ch->a[i]);
+ }
+
if(ch->free_flags&CHANMODEL_FREE_DELAY)
- free(ch->delays);
+ free(ch->delays);
+
if(ch->free_flags&CHANMODEL_FREE_RSQRT_6)
- for (int i = 0; i<6; i++)
- free(ch->R_sqrt[i]);
+ for (int i = 0; i<6; i++)
+ free(ch->R_sqrt[i]);
+
if(ch->free_flags&CHANMODEL_FREE_RSQRT_NTAPS)
- for (int i = 0; inb_taps;i++)
- free(ch->R_sqrt[i]);
- free(ch->R_sqrt);
- free(ch->ch);
+ for (int i = 0; inb_taps; i++)
+ free(ch->R_sqrt[i]);
+
+ free(ch->R_sqrt);
+ free(ch->ch);
free(ch->chF);
- free(ch->a);
- free(ch);
+ free(ch->a);
+ free(ch->model_name);
+ free(ch);
}
void set_channeldesc_owner(channel_desc_t *cdesc, uint32_t module_id) {
- cdesc->module_id=module_id;
+ cdesc->module_id=module_id;
+}
+
+void set_channeldesc_name(channel_desc_t *cdesc,char *modelname) {
+ if(cdesc->model_name != NULL)
+ free(cdesc->model_name);
+
+ cdesc->model_name=strdup(modelname);
}
int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) {
@@ -1780,14 +1844,14 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) {
desc->ch[aarx+(aatx*desc->nb_rx)][k].x += s*desc->a[l][aarx+(aatx*desc->nb_rx)].x;
desc->ch[aarx+(aatx*desc->nb_rx)][k].y += s*desc->a[l][aarx+(aatx*desc->nb_rx)].y;
- // printf("l %d : desc->ch.x %f, s %e, delay %f\n",l,desc->a[l][aarx+(aatx*desc->nb_rx)].x,s,desc->delays[l]);
+ // printf("l %d : desc->ch.x %f, s %e, delay %f\n",l,desc->a[l][aarx+(aatx*desc->nb_rx)].x,s,desc->delays[l]);
} //nb_taps
#ifdef DEBUG_CH
printf("(%d,%d,%d)->(%e,%e)\n",k,aarx,aatx,desc->ch[aarx+(aatx*desc->nb_rx)][k].x,desc->ch[aarx+(aatx*desc->nb_rx)][k].y);
#endif
} //channel_length
- }
+ }
} //aatx
} //aarx
@@ -1799,7 +1863,7 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) {
return (0);
}
-
+
double N_RB2sampling_rate(uint16_t N_RB) {
double sampling_rate;
@@ -1848,128 +1912,144 @@ double N_RB2channel_bandwidth(uint16_t N_RB) {
break;
default:
- LOG_E(PHY,"Unknown N_PRB\n");
+ LOG_E(OCM,"Unknown N_PRB\n");
return(-1);
}
- return(channel_bandwidth);
-}
-
+ return(channel_bandwidth);
+}
+
+
static int channelmod_print_help(char *buff, int debug, telnet_printfunc_t prnt ) {
- prnt("channelmod commands can be used to display or modify channel models parameters\n");
- prnt("channelmod show predef: display predefined model algorithms available in oai\n");
- prnt("channelmod show current: display the currently used models in the running executable\n");
- prnt("channelmod modify : set the specified parameters in a current model to the given value\n");
- prnt(" specifies the model, the show current model command can be used to list the current models indexes\n");
- prnt(" can be one of \"riceanf\", \"aoa\", \"randaoa\", \"ploss\", \"offset\", \"forgetf\"\n");
- return CMDSTATUS_FOUND;
+ prnt("channelmod commands can be used to display or modify channel models parameters\n");
+ prnt("channelmod show predef: display predefined model algorithms available in oai\n");
+ prnt("channelmod show current: display the currently used models in the running executable\n");
+ prnt("channelmod modify : set the specified parameters in a current model to the given value\n");
+ prnt(" specifies the model, the show current model command can be used to list the current models indexes\n");
+ prnt(" can be one of \"riceanf\", \"aoa\", \"randaoa\", \"ploss\", \"noise_power_dB\", \"offset\", \"forgetf\"\n");
+ return CMDSTATUS_FOUND;
}
static void display_channelmodel(channel_desc_t *cd,int debug, telnet_printfunc_t prnt) {
- char *module_id_str[]=MODULEID_STR_INIT;
- if (cd->module_id != 0) {
- prnt("model owner: %s\n",module_id_str[cd->module_id]);
- }
- prnt("nb_tx: %i nb_rx: %i taps: %i bandwidth: %lf sampling: %lf\n",cd->nb_tx, cd->nb_rx, cd->nb_taps, cd->channel_bandwidth, cd->sampling_rate);
- prnt("channel length: %i Max path delay: %lf ricean fact.: %lf angle of arrival: %lf (randomized:%s)\n",
- cd->channel_length, cd->Td, cd->ricean_factor, cd->aoa, (cd->random_aoa?"Yes":"No"));
- prnt("max Doppler: %lf path loss: %lf rchannel offset: %i forget factor; %lf\n",
- cd->max_Doppler, cd->path_loss_dB, cd->channel_offset, cd->forgetting_factor);
- prnt("Initial phase: %lf nb_path: %i \n",
- cd->ip, cd->nb_paths);
- for (int i=0; inb_taps ; i++) {
- prnt("taps: %i lin. ampli. : %lf delay: %lf \n",i,cd->amps[i], cd->delays[i]);
- }
+ char *module_id_str[]=MODULEID_STR_INIT;
+ prnt("model owner: %s\n",(cd->module_id != 0)?module_id_str[cd->module_id]:"not set");
+ prnt("nb_tx: %i nb_rx: %i taps: %i bandwidth: %lf sampling: %lf\n",cd->nb_tx, cd->nb_rx, cd->nb_taps, cd->channel_bandwidth, cd->sampling_rate);
+ prnt("channel length: %i Max path delay: %lf ricean fact.: %lf angle of arrival: %lf (randomized:%s)\n",
+ cd->channel_length, cd->Td, cd->ricean_factor, cd->aoa, (cd->random_aoa?"Yes":"No"));
+ prnt("max Doppler: %lf path loss: %lf noise: %lf rchannel offset: %i forget factor; %lf\n",
+ cd->max_Doppler, cd->path_loss_dB, cd->noise_power_dB, cd->channel_offset, cd->forgetting_factor);
+ prnt("Initial phase: %lf nb_path: %i \n",
+ cd->ip, cd->nb_paths);
+
+ for (int i=0; inb_taps ; i++) {
+ prnt("taps: %i lin. ampli. : %lf delay: %lf \n",i,cd->amps[i], cd->delays[i]);
+ }
}
-
-
+
+
static int channelmod_show_cmd(char *buff, int debug, telnet_printfunc_t prnt) {
- char *subcmd=NULL;
+ char *subcmd=NULL;
int s = sscanf(buff,"%ms\n",&subcmd);
if (s>0) {
if ( strcmp(subcmd,"predef") == 0) {
for (int i=0; channelmod_names[i].name != NULL ; i++) {
prnt(" %i %s\n", i, map_int_to_str(channelmod_names,i ));
- }
+ }
} else if ( strcmp(subcmd,"current") == 0) {
for (int i=0; i < max_chan ; i++) {
- if (defined_channels[i] != NULL) {
- prnt("model %i %s: \n----------------\n", i, map_int_to_str(channelmod_names,defined_channels[i]->modelid));
- display_channelmodel(defined_channels[i],debug,prnt);
+ if (defined_channels[i] != NULL) {
+ prnt("model %i %s type %s: \n----------------\n", i, (defined_channels[i]->model_name !=NULL)?defined_channels[i]->model_name:"(no name set)",
+ map_int_to_str(channelmod_names,defined_channels[i]->modelid));
+ display_channelmodel(defined_channels[i],debug,prnt);
}
}
} else {
- channelmod_print_help(buff, debug, prnt);
+ channelmod_print_help(buff, debug, prnt);
}
- free(subcmd);
+
+ free(subcmd);
}
+
return CMDSTATUS_FOUND;
}
-
+
static int channelmod_modify_cmd(char *buff, int debug, telnet_printfunc_t prnt) {
- char *param=NULL, *value=NULL;
+ char *param=NULL, *value=NULL;
int cd_id= -1;
int s = sscanf(buff,"%i %ms %ms \n",&cd_id,¶m, &value);
+
if (cd_id<0 || cd_id >= max_chan) {
- prnt("ERROR, %i: Channel model id outof range (0-%i)\n",cd_id,max_chan-1);
- return CMDSTATUS_FOUND;
+ prnt("ERROR, %i: Channel model id outof range (0-%i)\n",cd_id,max_chan-1);
+ return CMDSTATUS_FOUND;
}
+
if (defined_channels[cd_id]==NULL) {
- prnt("ERROR, %i: Channel model has not been set\n",cd_id);
- return CMDSTATUS_FOUND;
- }
-
+ prnt("ERROR, %i: Channel model has not been set\n",cd_id);
+ return CMDSTATUS_FOUND;
+ }
+
if (s==3) {
if ( strcmp(param,"riceanf") == 0) {
- double dbl = atof(value);
- if (dbl <0 || dbl > 1)
- prnt("ERROR: ricean factor range: 0 to 1, %lf is outof range\n",dbl);
- else
- defined_channels[cd_id]->ricean_factor=dbl;
+ double dbl = atof(value);
+
+ if (dbl <0 || dbl > 1)
+ prnt("ERROR: ricean factor range: 0 to 1, %lf is outof range\n",dbl);
+ else
+ defined_channels[cd_id]->ricean_factor=dbl;
} else if ( strcmp(param,"aoa") == 0) {
- double dbl = atof(value);
- if (dbl <0 || dbl >6.28)
- prnt("ERROR: angle of arrival range: 0 to 2*Pi, %lf is outof range\n",dbl);
- else
- defined_channels[cd_id]->aoa=dbl;
+ double dbl = atof(value);
+
+ if (dbl <0 || dbl >6.28)
+ prnt("ERROR: angle of arrival range: 0 to 2*Pi, %lf is outof range\n",dbl);
+ else
+ defined_channels[cd_id]->aoa=dbl;
} else if ( strcmp(param,"randaoa") == 0) {
- int i = atoi(value);
- if (i!=0 && i!=1)
- prnt("ERROR: randaoa is a boolean, must be 0 or 1\n");
- else
- defined_channels[cd_id]->random_aoa=i;
+ int i = atoi(value);
+
+ if (i!=0 && i!=1)
+ prnt("ERROR: randaoa is a boolean, must be 0 or 1\n");
+ else
+ defined_channels[cd_id]->random_aoa=i;
} else if ( strcmp(param,"ploss") == 0) {
- double dbl = atof(value);
- defined_channels[cd_id]->path_loss_dB=dbl;
+ double dbl = atof(value);
+ defined_channels[cd_id]->path_loss_dB=dbl;
+ } else if ( strcmp(param,"noise_power_dB") == 0) {
+ double dbl = atof(value);
+ defined_channels[cd_id]->noise_power_dB=dbl;
} else if ( strcmp(param,"offset") == 0) {
- int i = atoi(value);
- defined_channels[cd_id]->channel_offset=i;
+ int i = atoi(value);
+ defined_channels[cd_id]->channel_offset=i;
} else if ( strcmp(param,"forgetf") == 0) {
- double dbl = atof(value);
- if (dbl <0 || dbl > 1)
- prnt("ERROR: forgetting factor range: 0 to 1 (disable variation), %lf is outof range\n",dbl);
- else
- defined_channels[cd_id]->forgetting_factor=dbl;
+ double dbl = atof(value);
+
+ if (dbl <0 || dbl > 1)
+ prnt("ERROR: forgetting factor range: 0 to 1 (disable variation), %lf is outof range\n",dbl);
+ else
+ defined_channels[cd_id]->forgetting_factor=dbl;
} else {
- prnt("ERROR: %s, unknown channel parameter\n",param);
- return CMDSTATUS_FOUND;
+ prnt("ERROR: %s, unknown channel parameter\n",param);
+ return CMDSTATUS_FOUND;
}
- display_channelmodel(defined_channels[cd_id],debug,prnt);
- free(param);
- free(value);
- random_channel(defined_channels[cd_id],false);
+
+ display_channelmodel(defined_channels[cd_id],debug,prnt);
+ free(param);
+ free(value);
+ random_channel(defined_channels[cd_id],false);
}
- return CMDSTATUS_FOUND;
+
+ return CMDSTATUS_FOUND;
}
-
-int modelid_fromname(char *modelname) {
- int modelid=map_str_to_int(channelmod_names,modelname);
- if (modelid < 0)
- LOG_E(OCM,"random_channel.c: Error channel model %s unknown\n",modelname);
+
+int modelid_fromstrtype(char *modeltype) {
+ int modelid=map_str_to_int(channelmod_names,modeltype);
+
+ if (modelid < 0)
+ LOG_E(OCM,"random_channel.c: Error channel model %s unknown\n",modeltype);
+
return modelid;
}
@@ -1983,18 +2063,61 @@ double channelmod_get_sinr_dB(void) {
void init_channelmod(void) {
paramdef_t channelmod_params[] = CHANNELMOD_PARAMS_DESC;
- int ret = config_get( channelmod_params,sizeof(channelmod_params)/sizeof(paramdef_t),CHANNELMOD_SECTION);
+ int numparams=sizeof(channelmod_params)/sizeof(paramdef_t);
+ int ret = config_get( channelmod_params,numparams,CHANNELMOD_SECTION);
AssertFatal(ret >= 0, "configuration couldn't be performed");
- defined_channels=calloc(max_chan,sizeof( channel_desc_t*));
+ defined_channels=calloc(max_chan,sizeof( channel_desc_t *));
AssertFatal(defined_channels!=NULL, "couldn't allocate %u channel descriptors\n",max_chan);
-
/* look for telnet server, if it is loaded, add the channel modeling commands to it */
add_telnetcmd_func_t addcmd = (add_telnetcmd_func_t)get_shlibmodule_fptr("telnetsrv", TELNET_ADDCMD_FNAME);
if (addcmd != NULL) {
addcmd("channelmod",channelmod_vardef,channelmod_cmdarray);
}
-}
+} /* init_channelmod */
+
+
+int load_channellist(uint8_t nb_tx, uint8_t nb_rx, double sampling_rate, double channel_bandwidth) {
+ paramdef_t achannel_params[] = CHANNELMOD_MODEL_PARAMS_DESC;
+ paramlist_def_t channel_list;
+ memset(&channel_list,0,sizeof(paramlist_def_t));
+ memcpy(channel_list.listname,modellist_name,sizeof(channel_list.listname)-1);
+ int numparams = sizeof(achannel_params)/sizeof(paramdef_t);
+ config_getlist( &channel_list,achannel_params,numparams, CHANNELMOD_SECTION);
+ AssertFatal(channel_list.numelt>0, "List %s.%s not found in config file\n",CHANNELMOD_SECTION,channel_list.listname);
+ int pindex_NAME = config_paramidx_fromname(achannel_params,numparams, CHANNELMOD_MODEL_NAME_PNAME);
+ int pindex_DT = config_paramidx_fromname(achannel_params,numparams, CHANNELMOD_MODEL_DT_PNAME );
+ int pindex_FF = config_paramidx_fromname(achannel_params,numparams, CHANNELMOD_MODEL_FF_PNAME );
+ int pindex_CO = config_paramidx_fromname(achannel_params,numparams, CHANNELMOD_MODEL_CO_PNAME );
+ int pindex_PL = config_paramidx_fromname(achannel_params,numparams, CHANNELMOD_MODEL_PL_PNAME );
+ int pindex_NP = config_paramidx_fromname(achannel_params,numparams, CHANNELMOD_MODEL_NP_PNAME );
+ int pindex_TYPE = config_paramidx_fromname(achannel_params,numparams, CHANNELMOD_MODEL_TYPE_PNAME);
+
+ for (int i=0; imodel_name = strdup(*(channel_list.paramarray[i][pindex_NAME].strptr));
+ LOG_I(OCM,"Model %s type %s allocated from config file, list %s\n",*(channel_list.paramarray[i][pindex_NAME].strptr),
+ *(channel_list.paramarray[i][pindex_TYPE].strptr), modellist_name);
+ } /* for loop on channel_list */
+
+ return channel_list.numelt;
+} /* load_channelist */
#ifdef RANDOM_CHANNEL_MAIN
#define sampling_rate 5.0
diff --git a/openair1/SIMULATION/TOOLS/sim.h b/openair1/SIMULATION/TOOLS/sim.h
index 55a78e9778..7696f9202f 100644
--- a/openair1/SIMULATION/TOOLS/sim.h
+++ b/openair1/SIMULATION/TOOLS/sim.h
@@ -89,6 +89,7 @@ typedef struct {
double path_loss_dB;
///additional delay of channel in samples.
int32_t channel_offset;
+ float noise_power_dB;
///This parameter (0...1) allows for simple 1st order temporal variation. 0 means a new channel every call, 1 means keep channel constant all the time
double forgetting_factor;
///needs to be set to 1 for the first call, 0 otherwise.
@@ -106,8 +107,10 @@ typedef struct {
unsigned int chan_idx;
/// id of the channel modeling algorithm
int modelid;
- /// identifies channel descriptor owner (the module which created this descriptor)
+ /// identifies channel descriptor owner (the module which created this descriptor
channelmod_moduleid_t module_id;
+ /// name of this descriptor,used for model created from config file at init time
+ char *model_name;
/// flags to properly trigger memory free
unsigned int free_flags;
} channel_desc_t;
@@ -241,12 +244,37 @@ typedef enum {
#define CONFIG_HLP_SNR "Set average SNR in dB (for --siml1 option)\n"
#define CHANNELMOD_SECTION "channelmod"
+
+/* global channel modelization parameters */
+#define CHANNELMOD_MODELLIST_PARANAME "modellist"
+
+#define CHANNELMOD_HELP_MODELLIST " channel list name in config file describing the model type and its parameters\n"
#define CHANNELMOD_PARAMS_DESC { \
- {"s" , CONFIG_HLP_SNR, PARAMFLAG_CMDLINE_NOPREFIXENABLED, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0},\
- {"sinr_dB", NULL, 0 , dblptr:&sinr_dB, defdblval:0 , TYPE_DOUBLE, 0},\
- {"max_chan, CONFIG_HLP_MAX_CHAN", 0, uptr:&max_chan, defintval:10, TYPE_UINT, 0},\
+ {"s" , CONFIG_HLP_SNR, PARAMFLAG_CMDLINE_NOPREFIXENABLED, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0},\
+ {"sinr_dB", NULL, 0, dblptr:&sinr_dB, defdblval:0 , TYPE_DOUBLE, 0},\
+ {"max_chan", "Max number of runtime models", 0, uptr:&max_chan, defintval:10, TYPE_UINT, 0},\
+ {CHANNELMOD_MODELLIST_PARANAME, CHANNELMOD_HELP_MODELLIST, 0, strptr:(char **)&modellist_name, defstrval:"DefaultChannelList", TYPE_STRING, 60 },\
}
+/* parameters for one model */
+#define CHANNELMOD_MODEL_NAME_PNAME "model_name"
+#define CHANNELMOD_MODEL_TYPE_PNAME "type"
+#define CHANNELMOD_MODEL_PL_PNAME "ploss_dB"
+#define CHANNELMOD_MODEL_NP_PNAME "noise_power_dB"
+#define CHANNELMOD_MODEL_FF_PNAME "forgetfact"
+#define CHANNELMOD_MODEL_CO_PNAME "offset"
+#define CHANNELMOD_MODEL_DT_PNAME "ds_tdl"
+
+#define CHANNELMOD_MODEL_PARAMS_DESC { \
+ {CHANNELMOD_MODEL_NAME_PNAME, "name of the model\n", 0, strptr:NULL , defstrval:"", TYPE_STRING, 0 },\
+ {CHANNELMOD_MODEL_TYPE_PNAME, "name of the model type\n", 0, strptr:NULL , defstrval:"AWGN", TYPE_STRING, 0 },\
+ {CHANNELMOD_MODEL_PL_PNAME, "channel path loss in dB\n", 0, dblptr:NULL, defdblval:0, TYPE_DOUBLE, 0 },\
+ {CHANNELMOD_MODEL_NP_PNAME, "channel noise in dB\n", 0, dblptr:NULL, defdblval:-50, TYPE_DOUBLE, 0 },\
+ {CHANNELMOD_MODEL_FF_PNAME, "channel forget factor ((0 to 1)\n", 0, dblptr:NULL, defdblval:0, TYPE_DOUBLE, 0 },\
+ {CHANNELMOD_MODEL_CO_PNAME, "channel offset in samps\n", 0, iptr:NULL, defintval:0, TYPE_INT, 0 },\
+ {CHANNELMOD_MODEL_DT_PNAME, "delay spread for TDL models\n", 0, dblptr:NULL, defdblval:0, TYPE_DOUBLE, 0 }\
+}
+
#include "platform_constants.h"
typedef struct {
@@ -275,12 +303,17 @@ typedef struct {
channel_desc_t *new_channel_desc_scm(uint8_t nb_tx,
uint8_t nb_rx,
SCM_t channel_model,
- double sampling_rate,
+ double sampling_rate,
double channel_bandwidth,
- double TDL_DS,
+ double TDL_DS,
double forgetting_factor,
int32_t channel_offset,
- double path_loss_dB);
+ double path_loss_dB,
+ float noise_power_dB);
+
+channel_desc_t *find_channel_desc_fromname( char *modelname );
+
+
/**
\brief free memory allocated for a model descriptor
\param ch points to the model, which cannot be used after calling this fuction
@@ -293,6 +326,12 @@ void free_channel_desc_scm(channel_desc_t *ch);
\param module_id identifies the channel model. should be define as a macro in simu.h
*/
void set_channeldesc_owner(channel_desc_t *cdesc, channelmod_moduleid_t module_id);
+/**
+\brief This function set a model name to a model descriptor, can be later used to identify a allocated channel model
+\param cdesc points to the model descriptor
+\param module_name is the C string to use as model name for the channel pointed by cdesc
+*/
+void set_channeldesc_name(channel_desc_t *cdesc,char *modelname);
/** \fn void random_channel(channel_desc_t *desc)
\brief This routine generates a random channel response (time domain) according to a tapped delay line model.
\param desc Pointer to the channel descriptor
@@ -452,11 +491,11 @@ void multipath_tv_channel(channel_desc_t *desc,
/**@} */
/**@} */
-int modelid_fromname(char *modelname);
+int modelid_fromstrtype(char *modeltype);
double channelmod_get_snr_dB(void);
double channelmod_get_sinr_dB(void);
void init_channelmod(void) ;
-
+int load_channellist(uint8_t nb_tx, uint8_t nb_rx, double sampling_rate, double channel_bandwidth) ;
double N_RB2sampling_rate(uint16_t N_RB);
double N_RB2channel_bandwidth(uint16_t N_RB);
@@ -468,7 +507,6 @@ double N_RB2channel_bandwidth(uint16_t N_RB);
*/
//look-up table for the sine (cosine) function
#define ResolSinCos 100
-uint16_t LUTSin[ResolSinCos+1];
void InitSinLUT( void );
void phase_noise(double ts, int16_t * InRe, int16_t * InIm);
diff --git a/openair2/COMMON/gtpv1_u_messages_types.h b/openair2/COMMON/gtpv1_u_messages_types.h
index 8fde343000..f5b6314fe1 100644
--- a/openair2/COMMON/gtpv1_u_messages_types.h
+++ b/openair2/COMMON/gtpv1_u_messages_types.h
@@ -175,6 +175,8 @@ typedef struct gtpv1u_enb_end_marker_ind_s {
typedef struct {
in_addr_t enb_ip_address_for_S1u_S12_S4_up;
tcp_udp_port_t enb_port_for_S1u_S12_S4_up;
+ char addrStr[256];
+ char portStr[256];
} Gtpv1uS1Req;
typedef struct {
diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h
index 9db5d61a11..d6dd6e3b6f 100644
--- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h
+++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h
@@ -51,8 +51,6 @@ typedef struct {
pthread_mutex_t *mutex;
} mac_stats_updates_context_t;
-/*Array holding the last stats reports for each eNB. Used for continuous reporting*/
-mac_stats_updates_context_t mac_stats_context[NUM_MAX_ENB];
/*Functions to initialize and destroy the struct required for the
*continuous stats update report*/
diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h
index 5f6432732f..a9236af80b 100644
--- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h
+++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h
@@ -49,8 +49,6 @@ typedef struct
/*To Be Extended*/
}rrc_meas_stats;
-/* RRC CMI statistics */
-rrc_meas_stats * meas_stats;
/* FLEXRAN AGENT-RRC Interface */
diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c
index d05fe7ac26..b53a6feda1 100644
--- a/openair2/ENB_APP/enb_config.c
+++ b/openair2/ENB_APP/enb_config.c
@@ -57,6 +57,7 @@
#include "enb_paramdef.h"
#include "proto_agent.h"
#include "executables/thread-common.h"
+#include
extern uint32_t to_earfcn_DL(int eutra_bandP, uint32_t dl_CarrierFreq, uint32_t bw);
extern uint32_t to_earfcn_UL(int eutra_bandP, uint32_t ul_CarrierFreq, uint32_t bw);
@@ -2058,7 +2059,9 @@ int RCconfig_gtpu(void ) {
IPV4_STR_ADDR_TO_INT_NWBO ( address, GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" );
LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up);
GTPV1U_ENB_S1_REQ(message).enb_port_for_S1u_S12_S4_up = enb_port_for_S1U;
- itti_send_msg_to_task (TASK_GTPV1_U, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id)
+ strcpy(GTPV1U_ENB_S1_REQ(message).addrStr,address);
+ sprintf(GTPV1U_ENB_S1_REQ(message).portStr,"%d", enb_port_for_S1U);
+ itti_send_msg_to_task (TASK_VARIABLE, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id)
} else
LOG_E(GTPU,"invalid address for S1U\n");
diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c
index abb5b57e0c..1af59eab87 100644
--- a/openair2/ENB_APP/flexran_agent_common.c
+++ b/openair2/ENB_APP/flexran_agent_common.c
@@ -648,18 +648,6 @@ error:
* ************************************
*/
-int sort_ue_config(const void *a, const void *b) {
- const Protocol__FlexUeConfig *fa = a;
- const Protocol__FlexUeConfig *fb = b;
-
- if (fa->rnti < fb->rnti)
- return -1;
- else if (fa->rnti < fb->rnti)
- return 1;
-
- return 0;
-}
-
int flexran_agent_ue_config_reply(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) {
xid_t xid;
Protocol__FlexHeader *header = NULL;
diff --git a/openair2/ENB_APP/flexran_agent_common.h b/openair2/ENB_APP/flexran_agent_common.h
index ae690c7124..18d32421dd 100644
--- a/openair2/ENB_APP/flexran_agent_common.h
+++ b/openair2/ENB_APP/flexran_agent_common.h
@@ -70,7 +70,6 @@ typedef struct {
pthread_mutex_t *mutex;
} stats_updates_context_t;
-stats_updates_context_t stats_context[NUM_MAX_ENB];
/**********************************
* FlexRAN protocol messages helper
diff --git a/openair2/ENB_APP/flexran_agent_net_comm.c b/openair2/ENB_APP/flexran_agent_net_comm.c
index 0d1c52096d..568a0e32cc 100644
--- a/openair2/ENB_APP/flexran_agent_net_comm.c
+++ b/openair2/ENB_APP/flexran_agent_net_comm.c
@@ -30,7 +30,7 @@
#include "common/utils/LOG/log.h"
flexran_agent_channel_t *agent_channel[NUM_MAX_ENB][FLEXRAN_AGENT_MAX];
-flexran_agent_channel_instance_t channel_instance;
+static flexran_agent_channel_instance_t channel_instance;
int flexran_agent_channel_id = 0;
int flexran_agent_msg_send(mid_t mod_id, agent_id_t agent_id, void *data, int size, int priority) {
diff --git a/openair2/ENB_APP/flexran_agent_ran_api_to_fix.c b/openair2/ENB_APP/flexran_agent_ran_api_to_fix.c
new file mode 100644
index 0000000000..a5eb850712
--- /dev/null
+++ b/openair2/ENB_APP/flexran_agent_ran_api_to_fix.c
@@ -0,0 +1,33 @@
+#include
+#include
+#include
+pdcp_enb_t pdcp_enb[MAX_NUM_CCs];
+uint32_t Pdcp_stats_tx_window_ms[MAX_eNB][MAX_MOBILES_PER_ENB];
+uint32_t Pdcp_stats_tx_bytes[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_bytes_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_bytes_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_sn[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_throughput_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_aiat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_aiat_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_aiat_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_iat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+
+uint32_t Pdcp_stats_rx_window_ms[MAX_eNB][MAX_MOBILES_PER_ENB];
+uint32_t Pdcp_stats_rx[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_bytes[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_bytes_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_bytes_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_sn[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_goodput_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_aiat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_aiat_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_aiat_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_iat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_outoforder[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+
diff --git a/openair2/GNB_APP/L1_nr_paramdef.h b/openair2/GNB_APP/L1_nr_paramdef.h
index 67be560778..88f2cb1615 100644
--- a/openair2/GNB_APP/L1_nr_paramdef.h
+++ b/openair2/GNB_APP/L1_nr_paramdef.h
@@ -62,7 +62,7 @@
{CONFIG_STRING_L1_REMOTE_N_PORTC, NULL, 0, uptr:NULL, defintval:50030, TYPE_UINT, 0}, \
{CONFIG_STRING_L1_LOCAL_N_PORTD, NULL, 0, uptr:NULL, defintval:50031, TYPE_UINT, 0}, \
{CONFIG_STRING_L1_REMOTE_N_PORTD, NULL, 0, uptr:NULL, defintval:50031, TYPE_UINT, 0}, \
-{CONFIG_STRING_L1_PUSCH_PROC_THREADS, NULL, 0, uptr:NULL, defintval:1, TYPE_UINT, 0} \
+{CONFIG_STRING_L1_PUSCH_PROC_THREADS, NULL, 0, uptr:NULL, defintval:3, TYPE_UINT, 0} \
}
#define L1_CC_IDX 0
#define L1_TRANSPORT_N_PREFERENCE_IDX 1
diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c
index b40ff5d9e2..d3dd769807 100644
--- a/openair2/GNB_APP/gnb_config.c
+++ b/openair2/GNB_APP/gnb_config.c
@@ -58,6 +58,7 @@
//#include "RRC_config_tools.h"
#include "gnb_paramdef.h"
#include "NR_MAC_gNB/mac_proto.h"
+#include
#include "NR_asn_constant.h"
#include "executables/thread-common.h"
@@ -123,7 +124,37 @@ void prepare_scc(NR_ServingCellConfigCommon_t *scc) {
scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup = CALLOC(1,sizeof(struct NR_PDCCH_ConfigCommon));
scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->controlResourceSetZero = CALLOC(1,sizeof(long));
scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceZero = CALLOC(1,sizeof(long));
- // scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonControlResourceSet = CALLOC(1,sizeof(struct NR_ControlResourceSet));
+
+ NR_ControlResourceSet_t *coreset0 = CALLOC(1,sizeof(struct NR_ControlResourceSet));
+ coreset0->controlResourceSetId = 0;
+ // frequencyDomainResources '11111111 00000000 00000000 00000000 00000000 00000'B,
+ if(coreset0->frequencyDomainResources.buf == NULL) coreset0->frequencyDomainResources.buf = calloc(1,6);
+ coreset0->frequencyDomainResources.buf[0] = 0xff;
+ coreset0->frequencyDomainResources.buf[1] = 0;
+ coreset0->frequencyDomainResources.buf[2] = 0;
+ coreset0->frequencyDomainResources.buf[3] = 0;
+ coreset0->frequencyDomainResources.buf[4] = 0;
+ coreset0->frequencyDomainResources.buf[5] = 0;
+ coreset0->frequencyDomainResources.size = 6;
+ coreset0->frequencyDomainResources.bits_unused = 3;
+ coreset0->duration = 1;
+ coreset0->cce_REG_MappingType.present=NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved;
+ coreset0->cce_REG_MappingType.choice.interleaved=calloc(1,sizeof(*coreset0->cce_REG_MappingType.choice.interleaved));
+ coreset0->cce_REG_MappingType.choice.interleaved->reg_BundleSize = NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6;
+ coreset0->cce_REG_MappingType.choice.interleaved->interleaverSize = NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n2;
+ coreset0->cce_REG_MappingType.choice.interleaved->shiftIndex = scc->physCellId;
+ coreset0->precoderGranularity = NR_ControlResourceSet__precoderGranularity_sameAsREG_bundle;
+ if(coreset0->tci_StatesPDCCH_ToAddList == NULL) coreset0->tci_StatesPDCCH_ToAddList = calloc(1,sizeof(*coreset0->tci_StatesPDCCH_ToAddList));
+ NR_TCI_StateId_t *tci[8];
+ for (int i=0;i<8;i++) {
+ tci[i]=calloc(1,sizeof(*tci[i]));
+ *tci[i] = i;
+ ASN_SEQUENCE_ADD(&coreset0->tci_StatesPDCCH_ToAddList->list,tci[i]);
+ }
+ coreset0->tci_StatesPDCCH_ToReleaseList = NULL;
+ coreset0->tci_PresentInDCI = NULL;
+ coreset0->pdcch_DMRS_ScramblingID = NULL;
+ scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonControlResourceSet = coreset0;
// scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList = CALLOC(1,sizeof(struct NR_PDCCH_ConfigCommon__commonSearchSpaceList));
// scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1 = CALLOC(1,sizeof(NR_SearchSpaceId_t));
@@ -1014,20 +1045,23 @@ int RCconfig_nr_gtpu(void ) {
MessageDef *message;
if (gnb_mode == 1) { // NSA
- AssertFatal((message = itti_alloc_new_message(TASK_GNB_APP, 0, GTPV1U_ENB_S1_REQ))!=NULL,"");
+ message = itti_alloc_new_message(TASK_GNB_APP, 0, GTPV1U_ENB_S1_REQ);
+ AssertFatal(message!=NULL,"");
// IPV4_STR_ADDR_TO_INT_NWBO ( address, RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" );
// LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up);
IPV4_STR_ADDR_TO_INT_NWBO (address, GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" );
LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up);
GTPV1U_ENB_S1_REQ(message).enb_port_for_S1u_S12_S4_up = gnb_port_for_S1U;
} else {// TODO SA
- AssertFatal((message = itti_alloc_new_message(TASK_GNB_APP, 0, GTPV1U_GNB_NG_REQ))!=NULL,"");
+ message = itti_alloc_new_message(TASK_GNB_APP, 0, GTPV1U_GNB_NG_REQ);
+ AssertFatal(message!=NULL,"");
IPV4_STR_ADDR_TO_INT_NWBO (address, GTPV1U_GNB_NG_REQ(message).gnb_ip_address_for_NGu_up, "BAD IP ADDRESS FORMAT FOR gNB NG_U !\n" );
LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_GNB_NG_REQ(message).gnb_ip_address_for_NGu_up);
GTPV1U_GNB_NG_REQ(message).gnb_port_for_NGu_up = gnb_port_for_NGU;
}
-
- itti_send_msg_to_task (TASK_GTPV1_U, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id)
+ strcpy(GTPV1U_ENB_S1_REQ(message).addrStr,address);
+ sprintf(GTPV1U_ENB_S1_REQ(message).portStr,"%d", gnb_port_for_NGU);
+ itti_send_msg_to_task (TASK_VARIABLE, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id)
} else
LOG_E(GTPU,"invalid address for NGU\n");
diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c
index 781347abaa..71f91a67ec 100644
--- a/openair2/LAYER2/MAC/config.c
+++ b/openair2/LAYER2/MAC/config.c
@@ -337,7 +337,8 @@ config_sib2(int Mod_idP,
LTE_ARFCN_ValueEUTRA_t *ul_CArrierFreqP,
long *ul_BandwidthP,
LTE_AdditionalSpectrumEmission_t *additionalSpectrumEmissionP,
- struct LTE_MBSFN_SubframeConfigList *mbsfn_SubframeConfigListP) {
+ struct LTE_MBSFN_SubframeConfigList *mbsfn_SubframeConfigListP,
+ int dl_Bandwidth) {
nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP];
cfg->subframe_config.pb.value = radioResourceConfigCommonP->pdsch_ConfigCommon.p_b;
cfg->subframe_config.pb.tl.tag = NFAPI_SUBFRAME_CONFIG_PB_TAG;
@@ -345,7 +346,7 @@ config_sib2(int Mod_idP,
cfg->rf_config.reference_signal_power.value = radioResourceConfigCommonP->pdsch_ConfigCommon.referenceSignalPower;
cfg->rf_config.reference_signal_power.tl.tag = NFAPI_RF_CONFIG_REFERENCE_SIGNAL_POWER_TAG;
cfg->num_tlv++;
- cfg->nfapi_config.max_transmit_power.value = cfg->rf_config.reference_signal_power.value + power_off_dB[cfg->rf_config.dl_channel_bandwidth.value];
+ cfg->nfapi_config.max_transmit_power.value = cfg->rf_config.reference_signal_power.value + power_off_dB[dl_Bandwidth];
cfg->nfapi_config.max_transmit_power.tl.tag = NFAPI_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG;
cfg->num_tlv++;
cfg->prach_config.configuration_index.value = radioResourceConfigCommonP->prach_Config.prach_ConfigInfo.prach_ConfigIndex;
@@ -870,7 +871,8 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP,
config_sib2(Mod_idP, CC_idP, radioResourceConfigCommon,
radioResourceConfigCommon_BR,
NULL, ul_Bandwidth, additionalSpectrumEmission,
- mbsfn_SubframeConfigList);
+ mbsfn_SubframeConfigList,
+ mib->message.dl_Bandwidth);
} // mib != NULL
if (mobilityControlInfo !=NULL) {
diff --git a/openair2/LAYER2/MAC/config_ue.c b/openair2/LAYER2/MAC/config_ue.c
index 1c5e706218..79202d87e3 100644
--- a/openair2/LAYER2/MAC/config_ue.c
+++ b/openair2/LAYER2/MAC/config_ue.c
@@ -85,10 +85,6 @@ void ue_mac_reset(module_id_t module_idP, uint8_t eNB_index) {
ue_init_mac(module_idP); //This will hopefully do the rest of the MAC reset procedure
}
-int32_t **rxdata;
-int32_t **txdata;
-
-
int
rrc_mac_config_req_ue(module_id_t Mod_idP,
int CC_idP,
diff --git a/openair2/LAYER2/MAC/defs_NB_IoT.h b/openair2/LAYER2/MAC/defs_NB_IoT.h
index 517f01d1b9..78524e104d 100644
--- a/openair2/LAYER2/MAC/defs_NB_IoT.h
+++ b/openair2/LAYER2/MAC/defs_NB_IoT.h
@@ -537,9 +537,6 @@ typedef struct {
// global variables
-nprach_parameters_NB_IoT_t nprach_list[3];
-//DLSF Table
-DLSF_INFO_t DLSF_information;
#endif /*__LAYER2_MAC_DEFS_NB_IoT_H__ */
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_mch.c b/openair2/LAYER2/MAC/eNB_scheduler_mch.c
index f3a77ed703..1272b16ec0 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_mch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_mch.c
@@ -84,7 +84,7 @@ get_mbsfn_sf_alloction(module_id_t module_idP, uint8_t CC_id,
static uint32_t bytes_in_buffer=0;
static uint32_t msi_pmch_stop=0;
-uint16_t mbms_rab_id=2047;//[8] = {2047,2047,2047,2047,2047,2047,2047,2047};
+rb_id_t mbms_rab_id=2047;//[8] = {2047,2047,2047,2047,2047,2047,2047,2047};
static uint32_t msi_sfs=0;
diff --git a/openair2/LAYER2/MAC/mac_extern.h b/openair2/LAYER2/MAC/mac_extern.h
index cee6066a9e..cda64ec0e9 100644
--- a/openair2/LAYER2/MAC/mac_extern.h
+++ b/openair2/LAYER2/MAC/mac_extern.h
@@ -65,6 +65,7 @@ extern const int cqi_to_mcs[16];
extern uint32_t RRC_CONNECTION_FLAG;
extern uint8_t rb_table[34];
+extern rb_id_t mbms_rab_id;
#if defined(PRE_SCD_THREAD)
@@ -77,4 +78,5 @@ extern eNB_UE_STATS pre_scd_eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
extern mac_rlc_am_muilist_t rlc_am_mui;
extern SCHEDULER_MODES global_scheduler_mode;
+extern rb_id_t mbms_rab_id;
#endif //DEF_H
diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c
index 0dedacb11f..9ae8f82a00 100644
--- a/openair2/LAYER2/MAC/ue_procedures.c
+++ b/openair2/LAYER2/MAC/ue_procedures.c
@@ -72,7 +72,7 @@ extern UL_IND_t *UL_INFO;
extern int next_ra_frame;
extern module_id_t next_Mod_id;
-int mbms_rab_id=2047;//[8] = {2047,2047,2047,2047,2047,2047,2047,2047};
+rb_id_t mbms_rab_id=2047;//[8] = {2047,2047,2047,2047,2047,2047,2047,2047};
static int mbms_mch_i=0;
//static int num_msi_per_CSA[28];
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
index 67cf5051ef..4a288ee12f 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
@@ -149,10 +149,10 @@ typedef struct {
// single Entry PHR MAC CE
// TS 38.321 ch. 6.1.3.8
typedef struct {
- uint8_t PH: 6;
- uint8_t R1: 2;
- uint8_t PCMAX: 6;
- uint8_t R2: 6;
+ uint8_t PH: 6; // octet 1 [5:0]
+ uint8_t R1: 2; // octet 1 [7:6]
+ uint8_t PCMAX: 6; // octet 2 [5:0]
+ uint8_t R2: 2; // octet 2 [7:6]
} __attribute__ ((__packed__)) NR_SINGLE_ENTRY_PHR_MAC_CE;
@@ -335,12 +335,12 @@ typedef struct {
#define DL_SCH_LCID_CON_RES_ID 0x3E
#define DL_SCH_LCID_PADDING 0x3F
-#define UL_SCH_LCID_CCCH 0x00
+#define UL_SCH_LCID_CCCH1 0x00
#define UL_SCH_LCID_SRB1 0x01
#define UL_SCH_LCID_SRB2 0x02
#define UL_SCH_LCID_SRB3 0x03
#define UL_SCH_LCID_DTCH 0x04
-#define UL_SCH_LCID_CCCH_MSG3 0x21
+#define UL_SCH_LCID_CCCH 0x34
#define UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY 0x35
#define UL_SCH_LCID_MULTI_ENTRY_PHR_4_OCT 0x36
#define UL_SCH_LCID_CONFIGURED_GRANT_CONFIRMATION 0x37
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
index 941bd04877..7140279a03 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
@@ -125,6 +125,152 @@ const float table_38213_13_12_c3[16] = { 1, 0.5f, 1, 0.5f, 1, 0.5f, 0.5f, 0.5f
const int32_t table_38213_10_1_1_c2[5] = { 0, 0, 4, 2, 1 };
+// for PDSCH from TS 38.214 subclause 5.1.2.1.1
+const uint8_t table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos2[16][3]={
+ {0,2,12}, // row index 1
+ {0,2,10}, // row index 2
+ {0,2,9}, // row index 3
+ {0,2,7}, // row index 4
+ {0,2,5}, // row index 5
+ {0,9,4}, // row index 6
+ {0,4,4}, // row index 7
+ {0,5,7}, // row index 8
+ {0,5,2}, // row index 9
+ {0,9,2}, // row index 10
+ {0,12,2}, // row index 11
+ {0,1,13}, // row index 12
+ {0,1,6}, // row index 13
+ {0,2,4}, // row index 14
+ {0,4,7}, // row index 15
+ {0,8,4} // row index 16
+};
+const uint8_t table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos3[16][3]={
+ {0,3,11}, // row index 1
+ {0,3,9}, // row index 2
+ {0,3,8}, // row index 3
+ {0,3,6}, // row index 4
+ {0,3,4}, // row index 5
+ {0,10,4}, // row index 6
+ {0,6,4}, // row index 7
+ {0,5,7}, // row index 8
+ {0,5,2}, // row index 9
+ {0,9,2}, // row index 10
+ {0,12,2}, // row index 11
+ {0,1,13}, // row index 12
+ {0,1,6}, // row index 13
+ {0,2,4}, // row index 14
+ {0,4,7}, // row index 15
+ {0,8,4} // row index 16
+};
+const uint8_t table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP_dmrs_typeA_pos2[16][3]={
+ {0,2,6}, // row index 1
+ {0,2,10}, // row index 2
+ {0,2,9}, // row index 3
+ {0,2,7}, // row index 4
+ {0,2,5}, // row index 5
+ {0,6,4}, // row index 6
+ {0,4,4}, // row index 7
+ {0,5,6}, // row index 8
+ {0,5,2}, // row index 9
+ {0,9,2}, // row index 10
+ {0,10,2}, // row index 11
+ {0,1,11}, // row index 12
+ {0,1,6}, // row index 13
+ {0,2,4}, // row index 14
+ {0,4,6}, // row index 15
+ {0,8,4} // row index 16
+};
+const uint8_t table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP_dmrs_typeA_pos3[16][3]={
+ {0,3,5}, // row index 1
+ {0,3,9}, // row index 2
+ {0,3,8}, // row index 3
+ {0,3,6}, // row index 4
+ {0,3,4}, // row index 5
+ {0,8,2}, // row index 6
+ {0,6,4}, // row index 7
+ {0,5,6}, // row index 8
+ {0,5,2}, // row index 9
+ {0,9,2}, // row index 10
+ {0,10,2}, // row index 11
+ {0,1,11}, // row index 12
+ {0,1,6}, // row index 13
+ {0,2,4}, // row index 14
+ {0,4,6}, // row index 15
+ {0,8,4} // row index 16
+};
+const uint8_t table_5_1_2_1_1_4_time_dom_res_alloc_B_dmrs_typeA_pos2[16][3]={
+ {0,2,2}, // row index 1
+ {0,4,2}, // row index 2
+ {0,6,2}, // row index 3
+ {0,8,2}, // row index 4
+ {0,10,2}, // row index 5
+ {1,2,2}, // row index 6
+ {1,4,2}, // row index 7
+ {0,2,4}, // row index 8
+ {0,4,4}, // row index 9
+ {0,6,4}, // row index 10
+ {0,8,4}, // row index 11
+ {0,10,4}, // row index 12
+ {0,2,7}, // row index 13
+ {0,2,12}, // row index 14
+ {1,2,4}, // row index 15
+ {0,0,0} // row index 16
+};
+const uint8_t table_5_1_2_1_1_4_time_dom_res_alloc_B_dmrs_typeA_pos3[16][3]={
+ {0,2,2}, // row index 1
+ {0,4,2}, // row index 2
+ {0,6,2}, // row index 3
+ {0,8,2}, // row index 4
+ {0,10,2}, // row index 5
+ {1,2,2}, // row index 6
+ {1,4,2}, // row index 7
+ {0,2,4}, // row index 8
+ {0,4,4}, // row index 9
+ {0,6,4}, // row index 10
+ {0,8,4}, // row index 11
+ {0,10,4}, // row index 12
+ {0,2,7}, // row index 13
+ {0,3,11}, // row index 14
+ {1,2,4}, // row index 15
+ {0,0,0} // row index 16
+};
+const uint8_t table_5_1_2_1_1_5_time_dom_res_alloc_C_dmrs_typeA_pos2[16][3]={
+ {0,2,2}, // row index 1
+ {0,4,2}, // row index 2
+ {0,6,2}, // row index 3
+ {0,8,2}, // row index 4
+ {0,10,2}, // row index 5
+ {0,0,0}, // row index 6
+ {0,0,0}, // row index 7
+ {0,2,4}, // row index 8
+ {0,4,4}, // row index 9
+ {0,6,4}, // row index 10
+ {0,8,4}, // row index 11
+ {0,10,4}, // row index 12
+ {0,2,7}, // row index 13
+ {0,2,12}, // row index 14
+ {0,0,6}, // row index 15
+ {0,2,6} // row index 16
+};
+const uint8_t table_5_1_2_1_1_5_time_dom_res_alloc_C_dmrs_typeA_pos3[16][3]={
+ {0,2,2}, // row index 1
+ {0,4,2}, // row index 2
+ {0,6,2}, // row index 3
+ {0,8,2}, // row index 4
+ {0,10,2}, // row index 5
+ {0,0,0}, // row index 6
+ {0,0,0}, // row index 7
+ {0,2,4}, // row index 8
+ {0,4,4}, // row index 9
+ {0,6,4}, // row index 10
+ {0,8,4}, // row index 11
+ {0,10,4}, // row index 12
+ {0,2,7}, // row index 13
+ {0,3,11}, // row index 14
+ {0,0,6}, // row index 15
+ {0,2,6} // row index 16
+};
+
const char *prachfmt[]={"0","1","2","3", "A1","A2","A3","B1","B4","C0","C2","A1/B1","A2/B2","A3/B3"};
const char *duplex_mode[]={"FDD","TDD"};
@@ -1017,7 +1163,7 @@ int get_format0(uint8_t index,
uint8_t unpaired,
frequency_range_t frequency_range){
- uint16_t format;
+ uint16_t format=0;
if (unpaired) {
if (frequency_range==FR1)
format = table_6_3_3_2_3_prachConfig_Index[index][0];
@@ -2166,8 +2312,8 @@ int get_num_dmrs(uint16_t dmrs_mask ) {
return(num_dmrs);
}
/* returns the total DMRS symbols in a slot*/
-uint8_t get_num_dmrs_symbols(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols){
- return get_num_dmrs(fill_dmrs_mask(pdsch_Config,dmrs_TypeA_Position,NrOfSymbols));
+uint8_t get_num_dmrs_symbols(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols,int startSymbol){
+ return get_num_dmrs(fill_dmrs_mask(pdsch_Config,dmrs_TypeA_Position,NrOfSymbols,startSymbol));
}
// Table 5.1.2.2.1-1 38.214
@@ -2771,7 +2917,7 @@ int is_nr_DL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slot) {
int slots1=period1*(1<tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots ? 1 : 0);
- else return(slot_in_period <= slots1+scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSlots ? 1 : 0);
+ else return(slot_in_period <= slots1+scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSlots ? 1 : 0);
}
int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc, slot_t slot, lte_frame_type_t frame_type) {
@@ -2803,24 +2949,28 @@ int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc, slot_t slot, lte_frame_type
int slots1=period1*(1<= scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots ? 1 : 0);
- else return(slot_in_period >= slots1+scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSlots ? 1 : 0);
+ else return(slot_in_period >= slots1+scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSlots ? 1 : 0);
}
-int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols) {
+int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols,int startSymbol) {
int l0;
+ int ld = NrOfSymbols+startSymbol;
if (dmrs_TypeA_Position == NR_ServingCellConfigCommon__dmrs_TypeA_Position_pos2) l0=2;
else if (dmrs_TypeA_Position == NR_ServingCellConfigCommon__dmrs_TypeA_Position_pos3) l0=3;
else AssertFatal(1==0,"Illegal dmrs_TypeA_Position %d\n",(int)dmrs_TypeA_Position);
if (pdsch_Config == NULL) { // Initial BWP
- return(1<dmrs_DownlinkForPDSCH_MappingTypeA &&
pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->present == NR_SetupRelease_DMRS_DownlinkConfig_PR_setup) {
// Relative to start of slot
NR_DMRS_DownlinkConfig_t *dmrs_config = (NR_DMRS_DownlinkConfig_t *)pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup;
- AssertFatal(NrOfSymbols>1 && NrOfSymbols < 15,"Illegal NrOfSymbols %d\n",NrOfSymbols);
+ AssertFatal(ld>1 && ld < 15,"Illegal l_d %d\n",ld);
int pos2=0;
if (dmrs_config->maxLength == NULL) {
// this is Table 7.4.1.1.2-3: PDSCH DM-RS positions l for single-symbol DM-RS
@@ -2829,7 +2979,7 @@ int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,i
return(1<3,"Illegal NrOfSymbols %d for len2 DMRS\n",NrOfSymbols);
- if (NrOfSymbols < 10) return(1<dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0) return(1<dmrs_AdditionalPosition!=NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0) return(1<3,"Illegal l_d %d for len2 DMRS\n",ld);
+ if (ld < 10) return(1<dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0) return(1<dmrs_AdditionalPosition!=NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0) return(1<dmrs_AdditionalPosition!=NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0) return(1<dmrs_AdditionalPosition!=NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1) return(1<dmrs_AdditionalPosition==NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos0) return(1<
#include "NR_MAC_UE/mac_proto.h"
#include "NR_MAC-CellGroupConfig.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
+#include "executables/softmodem-common.h"
int set_tdd_config_nr_ue(fapi_nr_config_request_t *cfg,
int mu,
@@ -309,8 +311,11 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l139;
else
cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l839;
-
- cfg->prach_config.num_prach_fd_occasions_list[i].k1 = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart;
+ if (get_softmodem_params()->sa) {
+ cfg->prach_config.num_prach_fd_occasions_list[i].k1 = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE) + scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart + (get_N_RA_RB(cfg->prach_config.prach_sub_c_spacing, scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing ) * i);
+ } else {
+ cfg->prach_config.num_prach_fd_occasions_list[i].k1 = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart + (get_N_RA_RB(cfg->prach_config.prach_sub_c_spacing, scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing ) * i);
+ }
cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig;
cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences = compute_nr_root_seq(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup, nb_preambles, mac->frame_type, frequency_range);
//cfg->prach_config.num_prach_fd_occasions_list[i].num_unused_root_sequences = ???
@@ -528,11 +533,13 @@ int nr_rrc_mac_config_req_ue(
mac->servCellIndex = *cell_group_config->spCellConfig->servCellIndex;
config_control_ue(mac);
if (cell_group_config->spCellConfig->reconfigurationWithSync) {
- ra->rach_ConfigDedicated = cell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink;
- mac->scc = cell_group_config->spCellConfig->reconfigurationWithSync->spCellConfigCommon;
- config_common_ue(mac,module_id,cc_idP);
- mac->crnti = cell_group_config->spCellConfig->reconfigurationWithSync->newUE_Identity;
- LOG_I(MAC,"Configuring CRNTI %x\n",mac->crnti);
+ if (cell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated) {
+ ra->rach_ConfigDedicated = cell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink;
+ }
+ mac->scc = cell_group_config->spCellConfig->reconfigurationWithSync->spCellConfigCommon;
+ config_common_ue(mac,module_id,cc_idP);
+ mac->crnti = cell_group_config->spCellConfig->reconfigurationWithSync->newUE_Identity;
+ LOG_I(MAC,"Configuring CRNTI %x\n",mac->crnti);
}
// Setup the SSB to Rach Occasions mapping according to the config
diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h
index 933286f95a..332cd600d3 100755
--- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h
@@ -234,9 +234,12 @@ typedef struct {
typedef enum {
RA_UE_IDLE = 0,
- WAIT_RAR = 1,
- WAIT_CONTENTION_RESOLUTION = 2,
- RA_SUCCEEDED = 3
+ GENERATE_IDLE = 0,
+ GENERATE_PREAMBLE = 1,
+ WAIT_RAR = 2,
+ WAIT_CONTENTION_RESOLUTION = 3,
+ RA_SUCCEEDED = 4,
+ RA_FAILED = 5
} RA_state_t;
typedef struct {
@@ -257,8 +260,10 @@ typedef struct {
uint8_t RA_attempt_number;
/// Random-access procedure flag
uint8_t RA_active;
+ /// Random-access preamble index
+ int ra_PreambleIndex;
/// Flag for the Msg1 generation: enabled at every occurrence of nr prach slot
- uint8_t generate_nr_prach;
+ RA_state_t generate_nr_prach;
/// Random-access window counter
int16_t RA_window_cnt;
@@ -289,6 +294,8 @@ typedef struct {
uint8_t RA_contention_resolution_timer_active;
/// Random-access Contention Resolution Timer count value
uint8_t RA_contention_resolution_cnt;
+ /// Transmitted UE Contention Resolution Identifier
+ uint8_t cont_res_id[6];
/// BeamfailurerecoveryConfig
NR_BeamFailureRecoveryConfig_t RA_BeamFailureRecoveryConfig;
@@ -374,6 +381,8 @@ typedef struct {
NR_SearchSpace_t *search_space_zero;
NR_ControlResourceSet_t *coreset0;
+ dci_pdu_rel15_t def_dci_pdu_rel15[8];
+
} NR_UE_MAC_INST_t;
typedef enum seach_space_mask_e {
diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
index 14d1ea63fb..394ab58fc7 100755
--- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
@@ -178,7 +178,8 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac,
nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu,
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu,
- uint8_t time_domain_ind);
+ uint8_t time_domain_ind,
+ bool use_default);
uint8_t
nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c b/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c
index 27623fe5be..2f4697c25d 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c
@@ -146,17 +146,11 @@ int nr_get_Po_NOMINAL_PUSCH(NR_PRACH_RESOURCES_t *prach_resources, module_id_t m
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
NR_ServingCellConfigCommon_t *scc = mac->scc;
- int8_t receivedTargerPower, delta_preamble;
- long preambleReceivedTargetPower = 0;
-
- if (prach_resources->RA_TYPE == RA_4STEP){
- NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
- preambleReceivedTargetPower = nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower;
- } else if (prach_resources->RA_TYPE == RA_2STEP){
- // msgA-PreambleReceivedTargetPower
- LOG_E(MAC, "In %s:%d: missing implementation for 2-step RA...\n", __FUNCTION__, __LINE__);
- }
+ int8_t receivedTargerPower;
+ int8_t delta_preamble;
+ NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
+ long preambleReceivedTargetPower = nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower;
delta_preamble = nr_get_DELTA_PREAMBLE(mod_id, CC_id, prach_resources->prach_format);
receivedTargerPower = preambleReceivedTargetPower + delta_preamble + (prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER - 1) * prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP + prach_resources->POWER_OFFSET_2STEP_RA;
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c
index 8f234cb585..080a09ad51 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c
@@ -64,6 +64,8 @@ void init_RA(module_id_t mod_id,
RA_config_t *ra = &mac->ra;
ra->RA_active = 1;
+ ra->ra_PreambleIndex = -1;
+ ra->RA_usedGroupA = 1;
ra->RA_RAPID_found = 0;
ra->preambleTransMax = 0;
ra->first_Msg3 = 1;
@@ -79,8 +81,8 @@ void init_RA(module_id_t mod_id,
if (rach_ConfigDedicated) {
if (rach_ConfigDedicated->cfra){
- LOG_I(MAC, "Initialization of 4-step contention-free random access procedure\n");
- prach_resources->RA_TYPE = RA_4STEP;
+ LOG_I(MAC, "Initialization of 2-step contention-free random access procedure\n");
+ prach_resources->RA_TYPE = RA_2STEP;
ra->cfra = 1;
} else if (rach_ConfigDedicated->ext1){
if (rach_ConfigDedicated->ext1->cfra_TwoStep_r16){
@@ -93,161 +95,152 @@ void init_RA(module_id_t mod_id,
} else {
LOG_E(MAC, "In %s: config not handled\n", __FUNCTION__);
}
+ } else if (nr_rach_ConfigCommon){
+ LOG_I(MAC, "Initialization of 4-step contention-based random access procedure\n");
+ prach_resources->RA_TYPE = RA_4STEP;
+ ra->cfra = 0;
} else {
LOG_E(MAC, "In %s: config not handled\n", __FUNCTION__);
}
- if (prach_resources->RA_TYPE == RA_2STEP){
- LOG_E(MAC, "Missing implementation of initialization of 2-step RA specific variables...\n");
- } else if (prach_resources->RA_TYPE == RA_4STEP){
- LOG_D(MAC, "Initialization of 4-step RA specific variables...\n");
- switch (rach_ConfigGeneric->powerRampingStep){ // in dB
- case 0:
+ switch (rach_ConfigGeneric->powerRampingStep){ // in dB
+ case 0:
prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 0;
break;
- case 1:
+ case 1:
prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 2;
break;
- case 2:
+ case 2:
prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 4;
break;
- case 3:
+ case 3:
prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 6;
break;
- }
-
- switch (rach_ConfigGeneric->preambleTransMax) {
- case 0:
- ra->preambleTransMax = 3;
- break;
- case 1:
- ra->preambleTransMax = 4;
- break;
- case 2:
- ra->preambleTransMax = 5;
- break;
- case 3:
- ra->preambleTransMax = 6;
- break;
- case 4:
- ra->preambleTransMax = 7;
- break;
- case 5:
- ra->preambleTransMax = 8;
- break;
- case 6:
- ra->preambleTransMax = 10;
- break;
- case 7:
- ra->preambleTransMax = 20;
- break;
- case 8:
- ra->preambleTransMax = 50;
- break;
- case 9:
- ra->preambleTransMax = 100;
- break;
- case 10:
- ra->preambleTransMax = 200;
- break;
- }
- if (nr_rach_ConfigCommon->ext1) {
- if (nr_rach_ConfigCommon->ext1->ra_PrioritizationForAccessIdentity){
- LOG_D(MAC, "In %s:%d: Missing implementation for Access Identity initialization procedures\n", __FUNCTION__, __LINE__);
- }
- }
}
- return;
+ switch (rach_ConfigGeneric->preambleTransMax) {
+ case 0:
+ ra->preambleTransMax = 3;
+ break;
+ case 1:
+ ra->preambleTransMax = 4;
+ break;
+ case 2:
+ ra->preambleTransMax = 5;
+ break;
+ case 3:
+ ra->preambleTransMax = 6;
+ break;
+ case 4:
+ ra->preambleTransMax = 7;
+ break;
+ case 5:
+ ra->preambleTransMax = 8;
+ break;
+ case 6:
+ ra->preambleTransMax = 10;
+ break;
+ case 7:
+ ra->preambleTransMax = 20;
+ break;
+ case 8:
+ ra->preambleTransMax = 50;
+ break;
+ case 9:
+ ra->preambleTransMax = 100;
+ break;
+ case 10:
+ ra->preambleTransMax = 200;
+ break;
+ }
+ if (nr_rach_ConfigCommon->ext1) {
+ if (nr_rach_ConfigCommon->ext1->ra_PrioritizationForAccessIdentity){
+ LOG_D(MAC, "In %s:%d: Missing implementation for Access Identity initialization procedures\n", __FUNCTION__, __LINE__);
+ }
+ }
}
void ssb_rach_config(RA_config_t *ra, NR_PRACH_RESOURCES_t *prach_resources, NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon, fapi_nr_ul_config_prach_pdu *prach_pdu){
// Determine the SSB to RACH mapping ratio
// =======================================
- if (prach_resources->RA_TYPE == RA_4STEP){
- NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR ssb_perRACH_config = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present;
- boolean_t multiple_ssb_per_ro; // true if more than one or exactly one SSB per RACH occasion, false if more than one RO per SSB
- uint8_t ssb_rach_ratio; // Nb of SSBs per RACH or RACHs per SSB
- int total_preambles_per_ssb;
- uint8_t ssb_nb_in_ro;
- int numberOfRA_Preambles = 64;
- switch (ssb_perRACH_config){
- case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneEighth:
- multiple_ssb_per_ro = false;
- ssb_rach_ratio = 8;
- ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneEighth + 1);
- break;
- case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneFourth:
- multiple_ssb_per_ro = false;
- ssb_rach_ratio = 4;
- ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneFourth + 1);
- break;
- case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneHalf:
- multiple_ssb_per_ro = false;
- ssb_rach_ratio = 2;
- ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneHalf + 1);
- break;
- case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_one:
- multiple_ssb_per_ro = true;
- ssb_rach_ratio = 1;
- ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.one + 1);
- break;
- case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_two:
- multiple_ssb_per_ro = true;
- ssb_rach_ratio = 2;
- ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.two + 1);
- break;
- case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_four:
- multiple_ssb_per_ro = true;
- ssb_rach_ratio = 4;
- ra->cb_preambles_per_ssb = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.four;
- break;
- case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_eight:
- multiple_ssb_per_ro = true;
- ssb_rach_ratio = 8;
- ra->cb_preambles_per_ssb = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.eight;
- break;
- case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_sixteen:
- multiple_ssb_per_ro = true;
- ssb_rach_ratio = 16;
- ra->cb_preambles_per_ssb = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.sixteen;
- break;
- default:
- AssertFatal(1 == 0, "Unsupported ssb_perRACH_config %d\n", ssb_perRACH_config);
- break;
- }
+ NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR ssb_perRACH_config = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present;
+ boolean_t multiple_ssb_per_ro; // true if more than one or exactly one SSB per RACH occasion, false if more than one RO per SSB
+ uint8_t ssb_rach_ratio; // Nb of SSBs per RACH or RACHs per SSB
+ int total_preambles_per_ssb;
+ uint8_t ssb_nb_in_ro;
+ int numberOfRA_Preambles = 64;
- if (nr_rach_ConfigCommon->totalNumberOfRA_Preambles)
- numberOfRA_Preambles = *(nr_rach_ConfigCommon->totalNumberOfRA_Preambles);
+ switch (ssb_perRACH_config){
+ case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneEighth:
+ multiple_ssb_per_ro = false;
+ ssb_rach_ratio = 8;
+ ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneEighth + 1);
+ break;
+ case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneFourth:
+ multiple_ssb_per_ro = false;
+ ssb_rach_ratio = 4;
+ ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneFourth + 1);
+ break;
+ case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneHalf:
+ multiple_ssb_per_ro = false;
+ ssb_rach_ratio = 2;
+ ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneHalf + 1);
+ break;
+ case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_one:
+ multiple_ssb_per_ro = true;
+ ssb_rach_ratio = 1;
+ ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.one + 1);
+ break;
+ case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_two:
+ multiple_ssb_per_ro = true;
+ ssb_rach_ratio = 2;
+ ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.two + 1);
+ break;
+ case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_four:
+ multiple_ssb_per_ro = true;
+ ssb_rach_ratio = 4;
+ ra->cb_preambles_per_ssb = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.four;
+ break;
+ case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_eight:
+ multiple_ssb_per_ro = true;
+ ssb_rach_ratio = 8;
+ ra->cb_preambles_per_ssb = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.eight;
+ break;
+ case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_sixteen:
+ multiple_ssb_per_ro = true;
+ ssb_rach_ratio = 16;
+ ra->cb_preambles_per_ssb = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.sixteen;
+ break;
+ default:
+ AssertFatal(1 == 0, "Unsupported ssb_perRACH_config %d\n", ssb_perRACH_config);
+ }
- // Compute the proper Preamble selection params according to the selected SSB and the ssb_perRACH_OccasionAndCB_PreamblesPerSSB configuration
- if ((true == multiple_ssb_per_ro) &&
- (ssb_rach_ratio > 1)) {
- total_preambles_per_ssb = numberOfRA_Preambles / ssb_rach_ratio;
+ if (nr_rach_ConfigCommon->totalNumberOfRA_Preambles)
+ numberOfRA_Preambles = *(nr_rach_ConfigCommon->totalNumberOfRA_Preambles);
- ssb_nb_in_ro = prach_pdu->ssb_nb_in_ro;
- ra->starting_preamble_nb = total_preambles_per_ssb * ssb_nb_in_ro;
- }
- else {
- total_preambles_per_ssb = numberOfRA_Preambles;
- ra->starting_preamble_nb = 0;
- }
+ // Compute the proper Preamble selection params according to the selected SSB and the ssb_perRACH_OccasionAndCB_PreamblesPerSSB configuration
+ if ((true == multiple_ssb_per_ro) && (ssb_rach_ratio > 1)) {
+ total_preambles_per_ssb = numberOfRA_Preambles / ssb_rach_ratio;
+
+ ssb_nb_in_ro = prach_pdu->ssb_nb_in_ro;
+ ra->starting_preamble_nb = total_preambles_per_ssb * ssb_nb_in_ro;
} else {
- LOG_E(MAC, "In %s:%d: missing implementation for 2-step RA...\n", __FUNCTION__, __LINE__);
+ total_preambles_per_ssb = numberOfRA_Preambles;
+ ra->starting_preamble_nb = 0;
}
}
-// This routine implements RA premable configuration according to
+// This routine implements RA preamble configuration according to
// section 5.1 (Random Access procedure) of 3GPP TS 38.321 version 16.2.1 Release 16
void ra_preambles_config(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t *mac, int16_t dl_pathloss){
int messageSizeGroupA = 0;
int sizeOfRA_PreamblesGroupA = 0;
int messagePowerOffsetGroupB = 0;
- int PLThreshold;
+ int PLThreshold = 0;
long deltaPreamble_Msg3 = 0;
uint8_t noGroupB = 0;
RA_config_t *ra = &mac->ra;
@@ -255,23 +248,21 @@ void ra_preambles_config(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &nr_rach_ConfigCommon->rach_ConfigGeneric;
- if (prach_resources->RA_TYPE == RA_4STEP){
+ if (scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->msg3_DeltaPreamble){
+ deltaPreamble_Msg3 = (*scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->msg3_DeltaPreamble) * 2; // dB
+ LOG_D(MAC, "In %s: deltaPreamble_Msg3 set to %ld\n", __FUNCTION__, deltaPreamble_Msg3);
+ }
- if (scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->msg3_DeltaPreamble){
- deltaPreamble_Msg3 = (*scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->msg3_DeltaPreamble) * 2; // dB
- LOG_D(MAC, "In %s: deltaPreamble_Msg3 set to %ld\n", __FUNCTION__, deltaPreamble_Msg3);
- }
-
- if (!nr_rach_ConfigCommon->groupBconfigured) {
- noGroupB = 1;
- LOG_D(MAC, "In %s:%d: preambles group B is not configured...\n", __FUNCTION__, __LINE__);
- } else {
- // RA preambles group B is configured
- // - Random Access Preambles group B is configured for 4-step RA type
- // - Defining the number of RA preambles in RA Preamble Group A for each SSB
- LOG_D(MAC, "In %s:%d: preambles group B is configured...\n", __FUNCTION__, __LINE__);
- sizeOfRA_PreamblesGroupA = nr_rach_ConfigCommon->groupBconfigured->numberOfRA_PreamblesGroupA;
- switch (nr_rach_ConfigCommon->groupBconfigured->ra_Msg3SizeGroupA){
+ if (!nr_rach_ConfigCommon->groupBconfigured) {
+ noGroupB = 1;
+ LOG_D(MAC, "In %s:%d: preambles group B is not configured...\n", __FUNCTION__, __LINE__);
+ } else {
+ // RA preambles group B is configured
+ // - Random Access Preambles group B is configured for 4-step RA type
+ // - Defining the number of RA preambles in RA Preamble Group A for each SSB
+ LOG_D(MAC, "In %s:%d: preambles group B is configured...\n", __FUNCTION__, __LINE__);
+ sizeOfRA_PreamblesGroupA = nr_rach_ConfigCommon->groupBconfigured->numberOfRA_PreamblesGroupA;
+ switch (nr_rach_ConfigCommon->groupBconfigured->ra_Msg3SizeGroupA){
/* - Threshold to determine the groups of RA preambles */
case 0:
messageSizeGroupA = 56;
@@ -337,44 +328,42 @@ void ra_preambles_config(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t
break;
default:
AssertFatal(1 == 0,"Unknown messagePowerOffsetGroupB %lu\n", nr_rach_ConfigCommon->groupBconfigured->messagePowerOffsetGroupB);
- }
-
- PLThreshold = prach_resources->RA_PCMAX - rach_ConfigGeneric->preambleReceivedTargetPower - deltaPreamble_Msg3 - messagePowerOffsetGroupB;
-
}
- } else {
- // todo:
- // - groupB-ConfiguredTwoStepRA
- // - msgA-DeltaPreamble
- LOG_E(MAC, "In %s:%d: missing implementation for 2-step RA...\n", __FUNCTION__, __LINE__);
+
+ PLThreshold = prach_resources->RA_PCMAX - rach_ConfigGeneric->preambleReceivedTargetPower - deltaPreamble_Msg3 - messagePowerOffsetGroupB;
+
}
+
/* Msg3 has not been transmitted yet */
if (ra->first_Msg3) {
- if (noGroupB) {
- // use Group A preamble
- prach_resources->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % ra->cb_preambles_per_ssb);
- ra->RA_usedGroupA = 1;
- } else if ((ra->Msg3_size < messageSizeGroupA) && (dl_pathloss > PLThreshold)) {
- // Group B is configured and RA preamble Group A is used
- // - todo add condition on CCCH_sdu_size for initiation by CCCH
- prach_resources->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % sizeOfRA_PreamblesGroupA);
- ra->RA_usedGroupA = 1;
- } else {
- // Group B preamble is configured and used
- // the first sizeOfRA_PreamblesGroupA RA preambles belong to RA Preambles Group A
- // the remaining belong to RA Preambles Group B
- prach_resources->ra_PreambleIndex = ra->starting_preamble_nb + sizeOfRA_PreamblesGroupA + ((taus()) % (ra->cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA));
- ra->RA_usedGroupA = 0;
+ if(ra->ra_PreambleIndex < 0 || ra->ra_PreambleIndex > 63) {
+ if (noGroupB) {
+ // use Group A preamble
+ ra->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % ra->cb_preambles_per_ssb);
+ ra->RA_usedGroupA = 1;
+ } else if ((ra->Msg3_size < messageSizeGroupA) && (dl_pathloss > PLThreshold)) {
+ // Group B is configured and RA preamble Group A is used
+ // - todo add condition on CCCH_sdu_size for initiation by CCCH
+ ra->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % sizeOfRA_PreamblesGroupA);
+ ra->RA_usedGroupA = 1;
+ } else {
+ // Group B preamble is configured and used
+ // the first sizeOfRA_PreamblesGroupA RA preambles belong to RA Preambles Group A
+ // the remaining belong to RA Preambles Group B
+ ra->ra_PreambleIndex = ra->starting_preamble_nb + sizeOfRA_PreamblesGroupA + ((taus()) % (ra->cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA));
+ ra->RA_usedGroupA = 0;
+ }
}
} else { // Msg3 is being retransmitted
if (ra->RA_usedGroupA && noGroupB) {
- prach_resources->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % ra->cb_preambles_per_ssb);
+ ra->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % ra->cb_preambles_per_ssb);
} else if (ra->RA_usedGroupA && !noGroupB){
- prach_resources->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % sizeOfRA_PreamblesGroupA);
+ ra->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % sizeOfRA_PreamblesGroupA);
} else {
- prach_resources->ra_PreambleIndex = ra->starting_preamble_nb + sizeOfRA_PreamblesGroupA + ((taus()) % (ra->cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA));
+ ra->ra_PreambleIndex = ra->starting_preamble_nb + sizeOfRA_PreamblesGroupA + ((taus()) % (ra->cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA));
}
}
+ prach_resources->ra_PreambleIndex = ra->ra_PreambleIndex;
}
// RA-RNTI computation (associated to PRACH occasion in which the RA Preamble is transmitted)
@@ -472,6 +461,7 @@ void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint
// start contention resolution timer
ra->RA_contention_resolution_cnt = (nr_rach_ConfigCommon->ra_ContentionResolutionTimer + 1) * 8;
ra->RA_contention_resolution_timer_active = 1;
+ ra->ra_state = WAIT_CONTENTION_RESOLUTION;
}
@@ -503,7 +493,8 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
RA_config_t *ra = &mac->ra;
uint8_t mac_sdus[MAX_NR_ULSCH_PAYLOAD_BYTES];
- uint8_t lcid = UL_SCH_LCID_CCCH_MSG3, *payload;
+ uint8_t lcid = UL_SCH_LCID_CCCH;
+ uint8_t *payload;
uint16_t size_sdu = 0;
unsigned short post_padding;
NR_ServingCellConfigCommon_t *scc = mac->scc;
@@ -527,7 +518,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
}
}
- if (prach_resources->init_msg1) {
+ if (prach_resources->init_msg1 && ra->ra_state != RA_SUCCEEDED) {
if (ra->RA_active == 0) {
/* RA not active - checking if RRC is ready to initiate the RA procedure */
@@ -557,6 +548,11 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
if (size_sdu > 0) {
+ // UE Contention Resolution Identity
+ // Store the first 48 bits belonging to the uplink CCCH SDU within Msg3 to determine whether or not the
+ // Random Access Procedure has been successful after reception of Msg4
+ memcpy(ra->cont_res_id, mac_sdus, sizeof(uint8_t) * 6);
+
LOG_D(MAC, "[UE %d][%d.%d]: starting initialisation Random Access Procedure...\n", mod_id, frame, nr_slot_tx);
ra->Msg3_size = size_sdu + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT);
@@ -566,7 +562,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
nr_get_RA_window(mac);
// Fill in preamble and PRACH resources
- if (ra->generate_nr_prach == 1)
+ if (ra->generate_nr_prach == GENERATE_PREAMBLE)
nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, prach_pdu, rach_ConfigDedicated);
offset = nr_generate_ulsch_pdu((uint8_t *) mac_sdus, // sdus buffer
@@ -614,9 +610,13 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
}
if (ra->RA_window_cnt >= 0 && ra->RA_RAPID_found == 1) {
- // Reset RA_active flag: it disables Msg3 retransmission (8.3 of TS 38.213)
- nr_ra_succeeded(mod_id, frame, nr_slot_tx);
+ if(ra->cfra) {
+ // Reset RA_active flag: it disables Msg3 retransmission (8.3 of TS 38.213)
+ nr_ra_succeeded(mod_id, frame, nr_slot_tx);
+ } else {
+ ra->generate_nr_prach = GENERATE_IDLE;
+ }
} else if (ra->RA_window_cnt == 0 && !ra->RA_RAPID_found) {
@@ -638,7 +638,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
ra->RA_backoff_cnt--;
- if ((ra->RA_backoff_cnt > 0 && ra->generate_nr_prach == 1) || ra->RA_backoff_cnt == 0){
+ if ((ra->RA_backoff_cnt > 0 && ra->generate_nr_prach == GENERATE_PREAMBLE) || ra->RA_backoff_cnt == 0){
nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, prach_pdu, rach_ConfigDedicated);
}
@@ -650,7 +650,11 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
nr_ue_contention_resolution(mod_id, CC_id, frame, nr_slot_tx, prach_resources);
}
- return ra->generate_nr_prach;
+ if(ra->generate_nr_prach != GENERATE_IDLE) {
+ return ra->generate_nr_prach;
+ } else {
+ return ra->ra_state;
+ }
}
@@ -744,6 +748,7 @@ void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot){
LOG_I(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CF-RA: RAR successfully received.\n", mod_id, frame, slot);
ra->RA_window_cnt = -1;
+ mac->crnti = ra->t_crnti;
} else {
@@ -751,6 +756,7 @@ void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot){
ra->RA_contention_resolution_cnt = -1;
ra->RA_contention_resolution_timer_active = 0;
+ mac->crnti = ra->t_crnti;
ra->t_crnti = 0;
LOG_D(MAC, "In %s: [UE %d][%d.%d] CB-RA: cleared contention resolution timer...\n", __FUNCTION__, mod_id, frame, slot);
@@ -759,7 +765,7 @@ void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot){
LOG_D(MAC, "In %s: [UE %d] clearing RA_active flag...\n", __FUNCTION__, mod_id);
ra->RA_active = 0;
- ra->generate_nr_prach = 2;
+ ra->generate_nr_prach = GENERATE_IDLE;
ra->ra_state = RA_SUCCEEDED;
}
@@ -774,8 +780,9 @@ void nr_ra_failed(uint8_t mod_id, uint8_t CC_id, NR_PRACH_RESOURCES_t *prach_res
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
RA_config_t *ra = &mac->ra;
- ra->first_Msg3 = 0;
- ra->generate_nr_prach = 3;
+ ra->first_Msg3 = 1;
+ ra->ra_PreambleIndex = -1;
+ ra->generate_nr_prach = RA_FAILED;
ra->ra_state = RA_UE_IDLE;
prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER++;
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c
index 11edc6c20d..f879599f7d 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c
@@ -49,8 +49,6 @@
// #define DEBUG_DCI
-dci_pdu_rel15_t *def_dci_pdu_rel15;
-
void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15) {
LOG_D(MAC,"Filling search candidates for DCI\n");
@@ -72,7 +70,6 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
uint16_t monitoringSymbolsWithinSlot = 0;
uint8_t coreset_id = 1;
int sps = 0;
- def_dci_pdu_rel15 = calloc(1,2*sizeof(dci_pdu_rel15_t));
AssertFatal(mac->scc != NULL, "scc is null\n");
NR_BWP_Id_t bwp_id = mac->DL_BWP_Id;
NR_ServingCellConfigCommon_t *scc = mac->scc;
@@ -88,7 +85,11 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
} else {
ss = mac->search_space_zero;
coreset = mac->coreset0;
- rel15->coreset.CoreSetType = NFAPI_NR_CSET_CONFIG_MIB_SIB1;
+ if(rnti_type == NR_RNTI_SI) {
+ rel15->coreset.CoreSetType = NFAPI_NR_CSET_CONFIG_MIB_SIB1;
+ } else {
+ rel15->coreset.CoreSetType = NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG_CSET_0;
+ }
}
rel15->coreset.duration = coreset->duration;
@@ -135,7 +136,7 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
rel15->SubcarrierSpacing = bwp_Common->genericParameters.subcarrierSpacing;
for (int i = 0; i < rel15->num_dci_options; i++) {
- rel15->dci_length_options[i] = nr_dci_size(scc, mac->scg, def_dci_pdu_rel15+i, rel15->dci_format_options[i], NR_RNTI_C, rel15->BWPSize, bwp_id);
+ rel15->dci_length_options[i] = nr_dci_size(scc, mac->scg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[i]], rel15->dci_format_options[i], NR_RNTI_C, rel15->BWPSize, bwp_id);
}
break;
case NR_RNTI_RA:
@@ -144,15 +145,27 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps));
rel15->rnti = ra->ra_rnti;
rel15->BWPSize = NRRIV2BW(initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
- rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); //NRRIV2PRBOFFSET(initialDownlinkBWP->genericParameters.locationAndBandwidth, 275);
+ if (get_softmodem_params()->sa) {
+ rel15->BWPStart = NRRIV2PRBOFFSET(initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+ } else { // NSA mode is not using the Initial BWP
+ rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+ }
rel15->SubcarrierSpacing = initialDownlinkBWP->genericParameters.subcarrierSpacing;
- rel15->dci_length_options[0] = nr_dci_size(scc, mac->scg, def_dci_pdu_rel15, rel15->dci_format_options[0], NR_RNTI_RA, rel15->BWPSize, bwp_id);
+ rel15->dci_length_options[0] = nr_dci_size(scc, mac->scg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[0]], rel15->dci_format_options[0], NR_RNTI_RA, rel15->BWPSize, bwp_id);
break;
case NR_RNTI_P:
break;
case NR_RNTI_CS:
break;
case NR_RNTI_TC:
+ // we use the initial DL BWP
+ sps = initialDownlinkBWP->genericParameters.cyclicPrefix == NULL ? 14 : 12;
+ monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps));
+ rel15->rnti = ra->t_crnti;
+ rel15->BWPSize = NRRIV2BW(initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+ rel15->BWPStart = NRRIV2PRBOFFSET(initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+ rel15->SubcarrierSpacing = initialDownlinkBWP->genericParameters.subcarrierSpacing;
+ rel15->dci_length_options[0] = nr_dci_size(scc, mac->scg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[0]], rel15->dci_format_options[0], NR_RNTI_TC, rel15->BWPSize, bwp_id);
break;
case NR_RNTI_SP_CSI:
break;
@@ -169,7 +182,7 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t
rel15->SubcarrierSpacing = mac->mib->subCarrierSpacingCommon;
for (int i = 0; i < rel15->num_dci_options; i++) {
- rel15->dci_length_options[i] = nr_dci_size(scc, mac->scg, def_dci_pdu_rel15, rel15->dci_format_options[i], NR_RNTI_SI, rel15->BWPSize, 0);
+ rel15->dci_length_options[i] = nr_dci_size(scc, mac->scg, &mac->def_dci_pdu_rel15[rel15->dci_format_options[i]], rel15->dci_format_options[i], NR_RNTI_SI, rel15->BWPSize, 0);
}
break;
case NR_RNTI_SFI:
@@ -245,14 +258,22 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl
if (ss->searchSpaceId == *pdcch_ConfigCommon->choice.setup->ra_SearchSpace){
switch(ra->ra_state){
case WAIT_RAR:
- LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type1-PDCCH common random access search space\n");
- rel15->num_dci_options = 1;
- rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_0;
- config_dci_pdu(mac, rel15, dl_config, NR_RNTI_RA, ss_id);
- fill_dci_search_candidates(ss, rel15);
- break;
+ LOG_D(NR_MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type1-PDCCH common random access search space (RA-Msg2)\n");
+ rel15->num_dci_options = 1;
+ rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_0;
+ if (get_softmodem_params()->sa) {
+ config_dci_pdu(mac, rel15, dl_config, NR_RNTI_RA, -1);
+ } else {
+ config_dci_pdu(mac, rel15, dl_config, NR_RNTI_RA, ss_id);
+ }
+ fill_dci_search_candidates(ss, rel15);
+ break;
case WAIT_CONTENTION_RESOLUTION:
- LOG_E(MAC, "In %s: CB-RA not implemented yet. Should not have fallen in this case.\n", __FUNCTION__);
+ LOG_D(NR_MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type1-PDCCH common random access search space (RA-Msg4)\n");
+ rel15->num_dci_options = 1;
+ rel15->dci_format_options[0] = NR_DL_DCI_FORMAT_1_0;
+ config_dci_pdu(mac, rel15, dl_config, NR_RNTI_TC, -1);
+ fill_dci_search_candidates(ss, rel15);
break;
default:
break;
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
index 8b8fc4e0c2..03f8109638 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
@@ -73,10 +73,10 @@ int get_rnti_type(NR_UE_MAC_INST_t *mac, uint16_t rnti){
if (rnti == ra->ra_rnti) {
rnti_type = NR_RNTI_RA;
+ } else if (rnti == ra->t_crnti && (ra->ra_state == WAIT_RAR || ra->ra_state == WAIT_CONTENTION_RESOLUTION) ) {
+ rnti_type = NR_RNTI_TC;
} else if (rnti == mac->crnti) {
rnti_type = NR_RNTI_C;
- } else if (rnti == ra->t_crnti) {
- rnti_type = NR_RNTI_TC;
} else if (rnti == 0xFFFE) {
rnti_type = NR_RNTI_P;
} else if (rnti == 0xFFFF) {
@@ -106,7 +106,7 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
NR_ServingCellConfigCommon_t *scc = mac->scc;
frequency_range_t frequency_range;
- nr_mac_rrc_data_ind_ue( module_id, cc_id, gNB_index, NR_BCCH_BCH, (uint8_t *) pduP, 3 ); // fixed 3 bytes MIB PDU
+ nr_mac_rrc_data_ind_ue( module_id, cc_id, gNB_index, 0, 0, 0, NR_BCCH_BCH, (uint8_t *) pduP, 3 ); // fixed 3 bytes MIB PDU
AssertFatal(mac->mib != NULL, "nr_ue_decode_mib() mac->mib == NULL\n");
//if(mac->mib != NULL){
@@ -188,7 +188,7 @@ int8_t nr_ue_decode_BCCH_DL_SCH(module_id_t module_id,
uint8_t *pduP,
uint32_t pdu_len) {
LOG_D(NR_MAC, "Decoding NR-BCCH-DL-SCH-Message (SIB1 or SI)\n");
- nr_mac_rrc_data_ind_ue(module_id, cc_id, gNB_index, NR_BCCH_DL_SCH, (uint8_t *) pduP, pdu_len);
+ nr_mac_rrc_data_ind_ue(module_id, cc_id, gNB_index, 0, 0, 0, NR_BCCH_DL_SCH, (uint8_t *) pduP, pdu_len);
return 0;
}
@@ -264,85 +264,15 @@ int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *p
int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac,
nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu,
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu,
- uint8_t time_domain_ind
- ){
+ uint8_t time_domain_ind,
+ bool use_default){
+
int dmrs_typeA_pos = mac->scc->dmrs_TypeA_Position;
// uint8_t k_offset=0;
uint8_t sliv_S=0;
uint8_t sliv_L=0;
- uint8_t table_5_1_2_1_1_2_time_dom_res_alloc_A[16][3]={ // for PDSCH from TS 38.214 subclause 5.1.2.1.1
- {0,(dmrs_typeA_pos == 0)?2:3, (dmrs_typeA_pos == 0)?12:11}, // row index 1
- {0,(dmrs_typeA_pos == 0)?2:3, (dmrs_typeA_pos == 0)?10:9}, // row index 2
- {0,(dmrs_typeA_pos == 0)?2:3, (dmrs_typeA_pos == 0)?9:8}, // row index 3
- {0,(dmrs_typeA_pos == 0)?2:3, (dmrs_typeA_pos == 0)?7:6}, // row index 4
- {0,(dmrs_typeA_pos == 0)?2:3, (dmrs_typeA_pos == 0)?5:4}, // row index 5
- {0,(dmrs_typeA_pos == 0)?9:10,(dmrs_typeA_pos == 0)?4:4}, // row index 6
- {0,(dmrs_typeA_pos == 0)?4:6, (dmrs_typeA_pos == 0)?4:4}, // row index 7
- {0,5,7}, // row index 8
- {0,5,2}, // row index 9
- {0,9,2}, // row index 10
- {0,12,2}, // row index 11
- {0,1,13}, // row index 12
- {0,1,6}, // row index 13
- {0,2,4}, // row index 14
- {0,4,7}, // row index 15
- {0,8,4} // row index 16
- };
- /*uint8_t table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP[16][3]={ // for PDSCH from TS 38.214 subclause 5.1.2.1.1
- {0,(dmrs_typeA_pos == 0)?2:3, (dmrs_typeA_pos == 0)?6:5}, // row index 1
- {0,(dmrs_typeA_pos == 0)?2:3, (dmrs_typeA_pos == 0)?10:9}, // row index 2
- {0,(dmrs_typeA_pos == 0)?2:3, (dmrs_typeA_pos == 0)?9:8}, // row index 3
- {0,(dmrs_typeA_pos == 0)?2:3, (dmrs_typeA_pos == 0)?7:6}, // row index 4
- {0,(dmrs_typeA_pos == 0)?2:3, (dmrs_typeA_pos == 0)?5:4}, // row index 5
- {0,(dmrs_typeA_pos == 0)?6:8, (dmrs_typeA_pos == 0)?4:2}, // row index 6
- {0,(dmrs_typeA_pos == 0)?4:6, (dmrs_typeA_pos == 0)?4:4}, // row index 7
- {0,5,6}, // row index 8
- {0,5,2}, // row index 9
- {0,9,2}, // row index 10
- {0,10,2}, // row index 11
- {0,1,11}, // row index 12
- {0,1,6}, // row index 13
- {0,2,4}, // row index 14
- {0,4,6}, // row index 15
- {0,8,4} // row index 16
- };*/
- /*uint8_t table_5_1_2_1_1_4_time_dom_res_alloc_B[16][3]={ // for PDSCH from TS 38.214 subclause 5.1.2.1.1
- {0,2,2}, // row index 1
- {0,4,2}, // row index 2
- {0,6,2}, // row index 3
- {0,8,2}, // row index 4
- {0,10,2}, // row index 5
- {1,2,2}, // row index 6
- {1,4,2}, // row index 7
- {0,2,4}, // row index 8
- {0,4,4}, // row index 9
- {0,6,4}, // row index 10
- {0,8,4}, // row index 11
- {0,10,4}, // row index 12
- {0,2,7}, // row index 13
- {0,(dmrs_typeA_pos == 0)?2:3,(dmrs_typeA_pos == 0)?12:11}, // row index 14
- {1,2,4}, // row index 15
- {0,0,0} // row index 16
- };*/
- /*uint8_t table_5_1_2_1_1_5_time_dom_res_alloc_C[16][3]={ // for PDSCH from TS 38.214 subclause 5.1.2.1.1
- {0,2,2}, // row index 1
- {0,4,2}, // row index 2
- {0,6,2}, // row index 3
- {0,8,2}, // row index 4
- {0,10,2}, // row index 5
- {0,0,0}, // row index 6
- {0,0,0}, // row index 7
- {0,2,4}, // row index 8
- {0,4,4}, // row index 9
- {0,6,4}, // row index 10
- {0,8,4}, // row index 11
- {0,10,4}, // row index 12
- {0,2,7}, // row index 13
- {0,(dmrs_typeA_pos == 0)?2:3,(dmrs_typeA_pos == 0)?12:11}, // row index 14
- {0,0,6}, // row index 15
- {0,2,6} // row index 16
- };*/
uint8_t mu_pusch = 1;
+
// definition table j Table 6.1.2.1.1-4
uint8_t j = (mu_pusch==3)?3:(mu_pusch==2)?2:1;
uint8_t table_6_1_2_1_1_2_time_dom_res_alloc_A[16][3]={ // for PUSCH from TS 38.214 subclause 6.1.2.1.1
@@ -391,7 +321,7 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac,
pdsch_TimeDomainAllocationList = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList->choice.setup;
else if (mac->DLbwp[0]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList)
pdsch_TimeDomainAllocationList = mac->DLbwp[0]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
- if (pdsch_TimeDomainAllocationList) {
+ if (pdsch_TimeDomainAllocationList && use_default==false) {
if (time_domain_ind >= pdsch_TimeDomainAllocationList->list.count) {
LOG_E(MAC, "time_domain_ind %d >= pdsch->TimeDomainAllocationList->list.count %d\n",
@@ -414,8 +344,15 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac,
}
else {// Default configuration from tables
// k_offset = table_5_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][0];
- sliv_S = table_5_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][1];
- sliv_L = table_5_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][2];
+
+ if(dmrs_typeA_pos == 0) {
+ sliv_S = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos2[time_domain_ind][1];
+ sliv_L = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos2[time_domain_ind][2];
+ } else {
+ sliv_S = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos3[time_domain_ind][1];
+ sliv_L = table_5_1_2_1_1_2_time_dom_res_alloc_A_dmrs_typeA_pos3[time_domain_ind][2];
+ }
+
// k_offset = table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][0];
// sliv_S = table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][1];
// sliv_L = table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][2];
@@ -440,7 +377,7 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac,
pusch_TimeDomainAllocationList = mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
}
- if (pusch_TimeDomainAllocationList) {
+ if (pusch_TimeDomainAllocationList && use_default==false) {
if (time_domain_ind >= pusch_TimeDomainAllocationList->list.count) {
LOG_E(MAC, "time_domain_ind %d >= pusch->TimeDomainAllocationList->list.count %d\n",
time_domain_ind, pusch_TimeDomainAllocationList->list.count);
@@ -457,8 +394,8 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac,
}
else {
// k_offset = table_6_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][0];
- sliv_S = table_6_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][1];
- sliv_L = table_6_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind-1][2];
+ sliv_S = table_6_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind][1];
+ sliv_L = table_6_1_2_1_1_2_time_dom_res_alloc_A[time_domain_ind][2];
// k_offset = table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][0];
// sliv_S = table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][1];
// sliv_L = table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][2];
@@ -476,9 +413,9 @@ int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_in
LOG_D(MAC,"Received dci indication (rnti %x,dci format %d,n_CCE %d,payloadSize %d,payload %llx)\n",
dci->rnti,dci->dci_format,dci->n_CCE,dci->payloadSize,*(unsigned long long*)dci->payloadBits);
- if (nr_extract_dci_info(mac, dci->dci_format, dci->payloadSize, dci->rnti, (uint64_t *)dci->payloadBits, def_dci_pdu_rel15))
+ if (nr_extract_dci_info(mac, dci->dci_format, dci->payloadSize, dci->rnti, (uint64_t *)dci->payloadBits, &mac->def_dci_pdu_rel15[dci->dci_format]))
return -1;
- return (nr_ue_process_dci(module_id, cc_id, gNB_index, frame, slot, def_dci_pdu_rel15, dci->rnti, dci->dci_format));
+ return (nr_ue_process_dci(module_id, cc_id, gNB_index, frame, slot, &mac->def_dci_pdu_rel15[dci->dci_format], dci->rnti, dci->dci_format));
}
int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, frame_t frame, int slot, dci_pdu_rel15_t *dci, uint16_t rnti, uint8_t dci_format){
@@ -497,7 +434,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
AssertFatal(mac->DLbwp[0]!=NULL,"DLbwp[0] should not be zero here!\n");
AssertFatal(mac->ULbwp[0]!=NULL,"DLbwp[0] should not be zero here!\n");
- const uint16_t n_RB_DLBWP = (ra->ra_state == WAIT_RAR) ? NRRIV2BW(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE) : NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+ const uint16_t n_RB_DLBWP = (ra->ra_state == WAIT_RAR || ra->ra_state == WAIT_CONTENTION_RESOLUTION) ? NRRIV2BW(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE) : NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
LOG_D(MAC, "In %s: Processing received DCI format %s (DL BWP %d)\n", __FUNCTION__, dci_formats[dci_format], n_RB_DLBWP);
@@ -543,10 +480,6 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
// Config PUSCH PDU
ret = nr_config_pusch_pdu(mac, pusch_config_pdu, dci, NULL, rnti, &dci_format);
- if (ret != -1 && ra->RA_active && mac->crnti){
- nr_ra_succeeded(module_id, frame, slot);
- }
-
}
break;
@@ -606,10 +539,6 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
// Config PUSCH PDU
ret = nr_config_pusch_pdu(mac, pusch_config_pdu, dci, NULL, rnti, &dci_format);
- if (ret != -1 && ra->RA_active && mac->crnti){
- nr_ra_succeeded(module_id, frame, slot);
- }
-
}
break;
}
@@ -668,7 +597,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.rnti = rnti;
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu_1_0 = &dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.dlsch_config_rel15;
- NR_PDSCH_Config_t *pdsch_config=mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup;
+ NR_PDSCH_Config_t *pdsch_config = NULL;
uint16_t BWPSize = 0;
if(rnti == SI_RNTI) {
@@ -676,7 +605,6 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
dlsch_config_pdu_1_0->BWPSize = mac->type0_PDCCH_CSS_config.num_rbs;
dlsch_config_pdu_1_0->BWPStart = mac->type0_PDCCH_CSS_config.cset_start_rb;
dlsch_config_pdu_1_0->SubcarrierSpacing = mac->mib->subCarrierSpacingCommon;
- pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NULL; // For PDSCH with mapping type A, the UE shall assume dmrs-AdditionalPosition='pos2'
BWPSize = dlsch_config_pdu_1_0->BWPSize;
} else {
if (ra->RA_window_cnt >= 0 && rnti == ra->ra_rnti){
@@ -684,9 +612,20 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
} else {
dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH;
}
- dlsch_config_pdu_1_0->BWPSize = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
- dlsch_config_pdu_1_0->BWPStart = NRRIV2PRBOFFSET(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
- dlsch_config_pdu_1_0->SubcarrierSpacing = mac->DLbwp[0]->bwp_Common->genericParameters.subcarrierSpacing;
+ if( (ra->RA_window_cnt >= 0 && rnti == ra->ra_rnti) || (rnti == ra->t_crnti) ) {
+ dlsch_config_pdu_1_0->BWPSize = NRRIV2BW(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+ if (get_softmodem_params()->sa) {
+ dlsch_config_pdu_1_0->BWPStart = NRRIV2PRBOFFSET(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+ } else { // NSA mode is not using the Initial BWP
+ dlsch_config_pdu_1_0->BWPStart = NRRIV2PRBOFFSET(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+ pdsch_config = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup;
+ }
+ } else {
+ dlsch_config_pdu_1_0->BWPSize = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+ dlsch_config_pdu_1_0->BWPStart = NRRIV2PRBOFFSET(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+ dlsch_config_pdu_1_0->SubcarrierSpacing = mac->DLbwp[0]->bwp_Common->genericParameters.subcarrierSpacing;
+ pdsch_config = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup;
+ }
BWPSize = n_RB_DLBWP;
}
@@ -697,15 +636,16 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
return -1;
}
/* TIME_DOM_RESOURCE_ASSIGNMENT */
- if (nr_ue_process_dci_time_dom_resource_assignment(mac,NULL,dlsch_config_pdu_1_0,dci->time_domain_assignment.val) < 0) {
+ if (nr_ue_process_dci_time_dom_resource_assignment(mac,NULL,dlsch_config_pdu_1_0,dci->time_domain_assignment.val,rnti==SI_RNTI) < 0) {
LOG_W(MAC, "[%d.%d] Invalid time_domain_assignment. Possibly due to false DCI. Ignoring DCI!\n", frame, slot);
return -1;
}
/* dmrs symbol positions*/
dlsch_config_pdu_1_0->dlDmrsSymbPos = fill_dmrs_mask(pdsch_config,
mac->scc->dmrs_TypeA_Position,
- dlsch_config_pdu_1_0->start_symbol+dlsch_config_pdu_1_0->number_symbols);
- dlsch_config_pdu_1_0->dmrsConfigType = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1;
+ dlsch_config_pdu_1_0->number_symbols,
+ dlsch_config_pdu_1_0->start_symbol);
+ dlsch_config_pdu_1_0->dmrsConfigType = (pdsch_config) ? (mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1) : 0;
/* number of DM-RS CDM groups without data according to subclause 5.1.6.2 of 3GPP TS 38.214 version 15.9.0 Release 15 */
if (dlsch_config_pdu_1_0->number_symbols == 2)
dlsch_config_pdu_1_0->n_dmrs_cdm_groups = 1;
@@ -714,7 +654,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
/* VRB_TO_PRB_MAPPING */
dlsch_config_pdu_1_0->vrb_to_prb_mapping = (dci->vrb_to_prb_mapping.val == 0) ? vrb_to_prb_mapping_non_interleaved:vrb_to_prb_mapping_interleaved;
/* MCS TABLE INDEX */
- dlsch_config_pdu_1_0->mcs_table = (pdsch_config->mcs_Table) ? (*pdsch_config->mcs_Table + 1) : 0;
+ dlsch_config_pdu_1_0->mcs_table = (pdsch_config) ? ((pdsch_config->mcs_Table) ? (*pdsch_config->mcs_Table + 1) : 0) : 0;
/* MCS */
dlsch_config_pdu_1_0->mcs = dci->mcs;
// Basic sanity check for MCS value to check for a false or erroneous DCI
@@ -767,7 +707,7 @@ 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 (only if CRC scrambled by C-RNTI or CS-RNTI or new-RNTI)*/
- dlsch_config_pdu_1_0->pdsch_to_harq_feedback_time_ind = dci->pdsch_to_harq_feedback_timing_indicator.val;
+ dlsch_config_pdu_1_0->pdsch_to_harq_feedback_time_ind = mac->ULbwp[mac->UL_BWP_Id-1]->bwp_Dedicated->pucch_Config->choice.setup->dl_DataToUL_ACK->list.array[dci->pdsch_to_harq_feedback_timing_indicator.val][0];
LOG_D(MAC,"(nr_ue_procedures.c) rnti = %x dl_config->number_pdus = %d\n",
dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.rnti,
@@ -797,6 +737,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
LOG_D(MAC,"(nr_ue_procedures.c) pdu_type=%d\n\n",dl_config->dl_config_list[dl_config->number_pdus].pdu_type);
dl_config->number_pdus = dl_config->number_pdus + 1;
+
break;
}
@@ -862,20 +803,21 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
return -1;
}
/* TIME_DOM_RESOURCE_ASSIGNMENT */
- if (nr_ue_process_dci_time_dom_resource_assignment(mac,NULL,dlsch_config_pdu_1_1,dci->time_domain_assignment.val) < 0) {
+ if (nr_ue_process_dci_time_dom_resource_assignment(mac,NULL,dlsch_config_pdu_1_1,dci->time_domain_assignment.val,false) < 0) {
LOG_W(MAC, "[%d.%d] Invalid time_domain_assignment. Possibly due to false DCI. Ignoring DCI!\n", frame, slot);
return -1;
}
/* dmrs symbol positions*/
dlsch_config_pdu_1_1->dlDmrsSymbPos = fill_dmrs_mask(pdsch_config,
mac->scc->dmrs_TypeA_Position,
- dlsch_config_pdu_1_1->number_symbols);
+ dlsch_config_pdu_1_1->number_symbols,
+ dlsch_config_pdu_1_1->start_symbol);
dlsch_config_pdu_1_1->dmrsConfigType = mac->DLbwp[dl_bwp_id-1]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1;
/* TODO: fix number of DM-RS CDM groups without data according to subclause 5.1.6.2 of 3GPP TS 38.214,
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;
@@ -934,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];
@@ -946,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];
@@ -970,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];
@@ -990,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];
@@ -1333,7 +1283,7 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
} //end else
break;
-
+
case NR_RNTI_P:
/*
// Short Messages Indicator E2 bits
@@ -1402,41 +1352,74 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
break;
case NR_RNTI_TC:
- // indicating a DL DCI format 1bit
+
+ // indicating a DL DCI format - 1 bit
pos++;
dci_pdu_rel15->format_indicator = (*dci_pdu>>(dci_size-pos))&1;
+
if (dci_pdu_rel15->format_indicator == 0)
return 1; // discard dci, format indicator not corresponding to dci_format
- // Freq domain assignment 0-16 bit
+
+ // Freq domain assignment 0-16 bit
fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) );
pos+=fsize;
dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<time_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&0xf;
- // VRB to PRB mapping 1 bit
+
+ // VRB to PRB mapping - 1 bit
+ pos++;
dci_pdu_rel15->vrb_to_prb_mapping.val = (*dci_pdu>>(dci_size-pos))&1;
+
// MCS 5bit //bit over 32, so dci_pdu ++
pos+=5;
dci_pdu_rel15->mcs = (*dci_pdu>>(dci_size-pos))&0x1f;
- // New data indicator 1bit
+
+ // New data indicator - 1 bit
+ pos++;
dci_pdu_rel15->ndi = (*dci_pdu>>(dci_size-pos))&1;
- // Redundancy version 2bit
+
+ // Redundancy version - 2 bits
pos+=2;
dci_pdu_rel15->rv = (*dci_pdu>>(dci_size-pos))&3;
- // HARQ process number 4bit
+
+ // HARQ process number - 4 bits
pos+=4;
dci_pdu_rel15->harq_pid = (*dci_pdu>>(dci_size-pos))&0xf;
- // Downlink assignment index E2 bits
+
+ // Downlink assignment index - 2 bits
pos+=2;
dci_pdu_rel15->dai[0].val = (*dci_pdu>>(dci_size-pos))&3;
- // TPC command for scheduled PUCCH E2 bits
+
+ // TPC command for scheduled PUCCH - 2 bits
pos+=2;
dci_pdu_rel15->tpc = (*dci_pdu>>(dci_size-pos))&3;
- // PDSCH-to-HARQ_feedback timing indicator E3 bits
+
+ // PUCCH resource indicator - 3 bits
+ pos+=3;
+ dci_pdu_rel15->pucch_resource_indicator = (*dci_pdu>>(dci_size-pos))&7;
+
+ // PDSCH-to-HARQ_feedback timing indicator - 3 bits
pos+=3;
dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val = (*dci_pdu>>(dci_size-pos))&7;
-
+
+ LOG_D(NR_MAC,"N_RB = %i\n", N_RB);
+ LOG_D(NR_MAC,"dci_size = %i\n", dci_size);
+ LOG_D(NR_MAC,"fsize = %i\n", fsize);
+ LOG_D(NR_MAC,"dci_pdu_rel15->format_indicator = %i\n", dci_pdu_rel15->format_indicator);
+ LOG_D(NR_MAC,"dci_pdu_rel15->frequency_domain_assignment.val = %i\n", dci_pdu_rel15->frequency_domain_assignment.val);
+ LOG_D(NR_MAC,"dci_pdu_rel15->time_domain_assignment.val = %i\n", dci_pdu_rel15->time_domain_assignment.val);
+ LOG_D(NR_MAC,"dci_pdu_rel15->vrb_to_prb_mapping.val = %i\n", dci_pdu_rel15->vrb_to_prb_mapping.val);
+ LOG_D(NR_MAC,"dci_pdu_rel15->mcs = %i\n", dci_pdu_rel15->mcs);
+ LOG_D(NR_MAC,"dci_pdu_rel15->rv = %i\n", dci_pdu_rel15->rv);
+ LOG_D(NR_MAC,"dci_pdu_rel15->harq_pid = %i\n", dci_pdu_rel15->harq_pid);
+ LOG_D(NR_MAC,"dci_pdu_rel15->dai[0].val = %i\n", dci_pdu_rel15->dai[0].val);
+ LOG_D(NR_MAC,"dci_pdu_rel15->tpc = %i\n", dci_pdu_rel15->tpc);
+ LOG_D(NR_MAC,"dci_pdu_rel15->pucch_resource_indicator = %i\n", dci_pdu_rel15->pucch_resource_indicator);
+ LOG_D(NR_MAC,"dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val = %i\n", dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val);
+
break;
}
break;
@@ -1800,16 +1783,41 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
// MAC CE
case DL_SCH_LCID_CCCH:
- // MSG4 RRC Connection Setup 38.331
- // varialbe length
- mac_ce_len |= (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L;
+ // MSG4 RRC Setup 38.331
+ // variable length
+ if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
+ mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *) pduP)->L1 & 0x7f) << 8)
+ | ((uint16_t)((NR_MAC_SUBHEADER_LONG *) pduP)->L2 & 0xff);
+ mac_subheader_len = 3;
+ } else {
+ mac_sdu_len = ((NR_MAC_SUBHEADER_SHORT *) pduP)->L;
mac_subheader_len = 2;
- if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){
- mac_ce_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8;
- mac_subheader_len = 3;
- }
+ }
+ // Check if it is a valid CCCH message, we get all 00's messages very often
+ int i = 0;
+ for(i=0; i<(mac_subheader_len+mac_sdu_len); i++) {
+ if(pduP[i] != 0) {
+ break;
+ }
+ }
+ if (i == (mac_subheader_len+mac_sdu_len)) {
+ LOG_D(NR_MAC, "%s() Invalid CCCH message!, pdu_len: %d\n", __func__, pdu_len);
+ done = 1;
break;
+ }
+
+ if ( mac_sdu_len > 0 ) {
+ LOG_D(NR_MAC,"DL_SCH_LCID_CCCH (e.g. RRCSetup) with payload len %d\n", mac_sdu_len);
+ for (int i = 0; i < mac_subheader_len; i++) {
+ LOG_D(NR_MAC, "MAC header %d: 0x%x\n", i, pduP[i]);
+ }
+ for (int i = 0; i < mac_sdu_len; i++) {
+ LOG_D(NR_MAC, "%d: 0x%x\n", i, pduP[mac_subheader_len + i]);
+ }
+ nr_mac_rrc_data_ind_ue(module_idP, CC_id, gNB_index, frameP, 0, mac->crnti, CCCH, pduP+mac_subheader_len, mac_sdu_len);
+ }
+ break;
case DL_SCH_LCID_TCI_STATE_ACT_UE_SPEC_PDSCH:
@@ -1916,17 +1924,34 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
break;
case DL_SCH_LCID_CON_RES_ID:
- // Clause 5.1.5 and 6.1.3.3 of 3GPP TS 38.321 version 16.2.1 Release 16
- // WIP todo: handle CCCH_pdu
- mac_ce_len = 6;
-
- LOG_I(MAC, "[UE %d][RAPROC] Frame %d : received contention resolution msg: %x.%x.%x.%x.%x.%x, Terminating RA procedure\n", module_idP, frameP, pduP[0], pduP[1], pduP[2], pduP[3], pduP[4], pduP[5]);
+ // Clause 5.1.5 and 6.1.3.3 of 3GPP TS 38.321 version 16.2.1 Release 16
+ // MAC Header: 1 byte (R/R/LCID)
+ // MAC SDU: 6 bytes (UE Contention Resolution Identity)
+ mac_ce_len = 6;
- if (ra->RA_active == 1) {
- nr_ra_succeeded(module_idP, frameP, slot);
+ if(ra->ra_state == WAIT_CONTENTION_RESOLUTION) {
+ LOG_I(MAC, "[UE %d][RAPROC] Frame %d : received contention resolution identity: 0x%02x%02x%02x%02x%02x%02x Terminating RA procedure\n",
+ module_idP, frameP, pduP[1], pduP[2], pduP[3], pduP[4], pduP[5], pduP[6]);
+
+ bool ra_success = true;
+ for(int i = 0; icont_res_id[i] != pduP[i+1]) {
+ ra_success = false;
+ break;
+ }
}
- break;
+ if ( (ra->RA_active == 1) && ra_success) {
+ nr_ra_succeeded(module_idP, frameP, slot);
+ } else if (!ra_success){
+ // TODO: Handle failure of RA procedure @ MAC layer
+ // nr_ra_failed(module_idP, CC_id, prach_resources, frameP, slot); // prach_resources is a PHY structure
+ ra->ra_state = RA_UE_IDLE;
+ ra->RA_active = 0;
+ }
+ }
+
+ break;
case DL_SCH_LCID_PADDING:
done = 1;
// end of MAC PDU, can ignore the rest.
@@ -2044,8 +2069,9 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload,
last_size = 3;
}
} else { // UL CCCH SDU
- mac_pdu_ptr->R = 0;
- mac_pdu_ptr->LCID = sdu_lcids[i];
+ ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->R = 0;
+ ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->LCID = sdu_lcids[i];
+ last_size = 1;
}
mac_pdu_ptr += last_size;
@@ -2221,27 +2247,32 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t
NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 1); // RAR subPDU pointer
uint8_t preamble_index = get_ra_PreambleIndex(mod_id, cc_id, gNB_id); //prach_resources->ra_PreambleIndex;
- LOG_D(MAC, "In %s:[%d.%d]: [UE %d][RAPROC] invoking MAC for received RAR (current preamble %d)\n", __FUNCTION__, frame, slot, mod_id, preamble_index);
+ LOG_D(NR_MAC, "In %s:[%d.%d]: [UE %d][RAPROC] invoking MAC for received RAR (current preamble %d)\n", __FUNCTION__, frame, slot, mod_id, preamble_index);
while (1) {
n_subheaders++;
if (rarh->T == 1) {
n_subPDUs++;
- LOG_D(MAC, "[UE %d][RAPROC] Got RAPID RAR subPDU\n", mod_id);
+ LOG_I(NR_MAC, "[UE %d][RAPROC] Got RAPID RAR subPDU\n", mod_id);
} else {
- n_subPDUs++;
ra->RA_backoff_indicator = table_7_2_1[((NR_RA_HEADER_BI *)rarh)->BI];
ra->RA_BI_found = 1;
- LOG_D(MAC, "[UE %d][RAPROC] Got BI RAR subPDU %d\n", mod_id, ra->RA_backoff_indicator);
+ LOG_I(NR_MAC, "[UE %d][RAPROC] Got BI RAR subPDU %d ms\n", mod_id, ra->RA_backoff_indicator);
+ if ( ((NR_RA_HEADER_BI *)rarh)->E == 1) {
+ rarh += sizeof(NR_RA_HEADER_BI);
+ continue;
+ } else {
+ break;
+ }
}
if (rarh->RAPID == preamble_index) {
- LOG_I(MAC, "[UE %d][RAPROC][%d.%d] Found RAR with the intended RAPID %d\n", mod_id, frame, slot, rarh->RAPID);
+ LOG_I(NR_MAC, "[UE %d][RAPROC][%d.%d] Found RAR with the intended RAPID %d\n", mod_id, frame, slot, rarh->RAPID);
rar = (NR_MAC_RAR *) (dlsch_buffer + n_subheaders + (n_subPDUs - 1) * sizeof(NR_MAC_RAR));
ra->RA_RAPID_found = 1;
break;
}
if (rarh->E == 0) {
- LOG_W(PHY,"[UE %d][RAPROC] Received RAR preamble (%d) doesn't match the intended RAPID...\n", mod_id, preamble_index);
+ LOG_W(NR_MAC,"[UE %d][RAPROC][%d.%d] Received RAR preamble (%d) doesn't match the intended RAPID (%d)\n", mod_id, frame, slot, rarh->RAPID, preamble_index);
break;
} else {
rarh += sizeof(NR_MAC_RAR) + 1;
@@ -2317,21 +2348,37 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t
rnti = mac->crnti;
}
- #ifdef DEBUG_RAR
- LOG_D(MAC, "In %s:[%d.%d]: [UE %d] Received RAR with t_alloc %d f_alloc %d ta_command %d mcs %d freq_hopping %d tpc_command %d csi_req %d t_crnti %x \n",
- __FUNCTION__,
- frame,
- slot,
- mod_id,
- rar_grant.Msg3_t_alloc,
- rar_grant.Msg3_f_alloc,
- ul_time_alignment->ta_command,
- rar_grant.mcs,
- rar_grant.freq_hopping,
- tpc_command,
- csi_req,
- ra->t_crnti);
- #endif
+#ifdef DEBUG_RAR
+ LOG_I(NR_MAC, "rarh->E = 0x%x\n", rarh->E);
+ LOG_I(NR_MAC, "rarh->T = 0x%x\n", rarh->T);
+ LOG_I(NR_MAC, "rarh->RAPID = 0x%x (%i)\n", rarh->RAPID, rarh->RAPID);
+
+ LOG_I(NR_MAC, "rar->R = 0x%x\n", rar->R);
+ LOG_I(NR_MAC, "rar->TA1 = 0x%x\n", rar->TA1);
+
+ LOG_I(NR_MAC, "rar->TA2 = 0x%x\n", rar->TA2);
+ LOG_I(NR_MAC, "rar->UL_GRANT_1 = 0x%x\n", rar->UL_GRANT_1);
+
+ LOG_I(NR_MAC, "rar->UL_GRANT_2 = 0x%x\n", rar->UL_GRANT_2);
+ LOG_I(NR_MAC, "rar->UL_GRANT_3 = 0x%x\n", rar->UL_GRANT_3);
+ LOG_I(NR_MAC, "rar->UL_GRANT_4 = 0x%x\n", rar->UL_GRANT_4);
+
+ LOG_I(NR_MAC, "rar->TCRNTI_1 = 0x%x\n", rar->TCRNTI_1);
+ LOG_I(NR_MAC, "rar->TCRNTI_2 = 0x%x\n", rar->TCRNTI_2);
+
+ LOG_I(NR_MAC, "In %s:[%d.%d]: [UE %d] Received RAR with t_alloc %d f_alloc %d ta_command %d mcs %d freq_hopping %d tpc_command %d t_crnti %x \n",
+ __FUNCTION__,
+ frame,
+ slot,
+ mod_id,
+ rar_grant.Msg3_t_alloc,
+ rar_grant.Msg3_f_alloc,
+ ul_time_alignment->ta_command,
+ rar_grant.mcs,
+ rar_grant.freq_hopping,
+ tpc_command,
+ ra->t_crnti);
+#endif
// Schedule Msg3
ret = nr_ue_pusch_scheduler(mac, is_Msg3, frame, slot, &frame_tx, &slot_tx, rar_grant.Msg3_t_alloc);
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
index 844ee95d32..2afbb7de15 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
@@ -149,14 +149,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!!!
@@ -165,43 +176,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];
}
@@ -210,14 +221,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];
}
@@ -225,16 +236,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];
}
@@ -245,7 +256,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;
@@ -269,15 +280,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
@@ -285,27 +288,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
@@ -337,9 +360,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
@@ -375,9 +397,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
@@ -409,9 +431,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
@@ -500,11 +521,13 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
int ibwp_size = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
// BWP start selection according to 8.3 of TS 38.213
- pusch_config_pdu->bwp_size = ibwp_size;
- if ((ibwp_start < abwp_start) || (ibwp_size > abwp_size))
+ if ((ibwp_start < abwp_start) || (ibwp_size > abwp_size)) {
pusch_config_pdu->bwp_start = abwp_start;
- else
+ pusch_config_pdu->bwp_size = abwp_size;
+ } else {
pusch_config_pdu->bwp_start = ibwp_start;
+ pusch_config_pdu->bwp_size = ibwp_size;
+ }
//// Resource assignment from RAR
// Frequency domain allocation according to 8.3 of TS 38.213
@@ -518,7 +541,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
return -1;
// virtual resource block to physical resource mapping for Msg3 PUSCH (6.3.1.7 in 38.211)
- pusch_config_pdu->rb_start += ibwp_start - abwp_start;
+ //pusch_config_pdu->rb_start += ibwp_start - abwp_start;
// Time domain allocation
SLIV2SL(startSymbolAndLength, &StartSymbolIndex, &NrOfSymbols);
@@ -567,7 +590,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
@@ -645,12 +667,12 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
return -1;
}
/* TIME_DOM_RESOURCE_ASSIGNMENT */
- if (nr_ue_process_dci_time_dom_resource_assignment(mac, pusch_config_pdu, NULL, dci->time_domain_assignment.val) < 0) {
+ if (nr_ue_process_dci_time_dom_resource_assignment(mac, pusch_config_pdu, NULL, dci->time_domain_assignment.val,false) < 0) {
return -1;
}
/* 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;
}
@@ -887,7 +909,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
uint16_t TBS_bytes = ulcfg_pdu->pusch_config_pdu.pusch_data.tb_size;
- if (ra->ra_state == WAIT_RAR){
+ if (ra->ra_state == WAIT_RAR && !ra->cfra){
memcpy(ulsch_input_buffer, mac->ulsch_pdu.payload, TBS_bytes);
LOG_D(NR_MAC,"[RAPROC] Msg3 to be transmitted:\n");
for (int k = 0; k < TBS_bytes; k++) {
@@ -913,10 +935,9 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
//and block this traffic from being forwarded to the upper layers at the gNB
LOG_D(PHY, "In %s: Random data to be transmitted: TBS_bytes %d \n", __FUNCTION__, TBS_bytes);
- //Give the first byte a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2)
- //in order to distinguish the PHY random packets at the MAC layer of the gNB receiver from the normal packets that should
- //have a valid LCID (nr_process_mac_pdu function)
- ulsch_input_buffer[0] = 0x31;
+ // Make the first byte padding so that gNB ignores the PHY random
+ // data in the TB for the PHY at the MAC layer
+ ulsch_input_buffer[0] = UL_SCH_LCID_PADDING;
for (int i = 1; i < TBS_bytes; i++) {
ulsch_input_buffer[i] = (unsigned char) rand();
@@ -941,7 +962,8 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
tx_req.tx_request_body[0].pdu_index = j;
tx_req.tx_request_body[0].pdu = ulsch_input_buffer;
- if (ra->ra_state != RA_SUCCEEDED && !ra->cfra){
+ if (ra->ra_state == WAIT_RAR && !ra->cfra){
+ LOG_I(NR_MAC,"[RAPROC] RA-Msg3 transmitted\n");
nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, ul_info->frame_tx, ul_info->gNB_index);
}
@@ -981,7 +1003,7 @@ int nr_ue_pusch_scheduler(NR_UE_MAC_INST_t *mac,
struct NR_PUSCH_TimeDomainResourceAllocationList *pusch_TimeDomainAllocationList = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
// k2 as per 3GPP TS 38.214 version 15.9.0 Release 15 ch 6.1.2.1.1
// PUSCH time domain resource allocation is higher layer configured from uschTimeDomainAllocationList in either pusch-ConfigCommon
- uint8_t k2;
+ int k2;
if (is_Msg3) {
k2 = *pusch_TimeDomainAllocationList->list.array[tda_id]->k2;
@@ -1668,7 +1690,7 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric;
ra->RA_offset = 2; // to compensate the rx frame offset at the gNB
- ra->generate_nr_prach = 0; // Reset flag for PRACH generation
+ ra->generate_nr_prach = GENERATE_IDLE; // Reset flag for PRACH generation
if (is_nr_UL_slot(scc, slotP, mac->frame_type)) {
@@ -1685,7 +1707,7 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
if (is_nr_prach_slot && ra->ra_state == RA_UE_IDLE) {
AssertFatal(NULL != prach_occasion_info_p,"PRACH Occasion Info not returned in a valid NR Prach Slot\n");
- ra->generate_nr_prach = 1;
+ ra->generate_nr_prach = GENERATE_PREAMBLE;
format = prach_occasion_info_p->format;
format0 = format & 0xff; // single PRACH format
diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c
index d0a8037307..528edc64aa 100644
--- a/openair2/LAYER2/NR_MAC_gNB/config.c
+++ b/openair2/LAYER2/NR_MAC_gNB/config.c
@@ -208,8 +208,12 @@ void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts
cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l839;
cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index.tl.tag = NFAPI_NR_CONFIG_PRACH_ROOT_SEQUENCE_INDEX_TAG;
cfg->num_tlv++;
- cfg->prach_config.num_prach_fd_occasions_list[i].k1.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart + (get_N_RA_RB( cfg->prach_config.prach_sub_c_spacing.value, scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing ) * i);
-//k1= msg1_FrequencyStart + 12 (no. of FDM)(RB for PRACH occasion);
+ cfg->prach_config.num_prach_fd_occasions_list[i].k1.value = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE) + scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart + (get_N_RA_RB( cfg->prach_config.prach_sub_c_spacing.value, scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing ) * i);
+ if (get_softmodem_params()->sa) {
+ cfg->prach_config.num_prach_fd_occasions_list[i].k1.value = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE) + scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart + (get_N_RA_RB( cfg->prach_config.prach_sub_c_spacing.value, scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing ) * i);
+ } else {
+ cfg->prach_config.num_prach_fd_occasions_list[i].k1.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart + (get_N_RA_RB( cfg->prach_config.prach_sub_c_spacing.value, scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing ) * i);
+ }
cfg->prach_config.num_prach_fd_occasions_list[i].k1.tl.tag = NFAPI_NR_CONFIG_K1_TAG;
cfg->num_tlv++;
cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig;
@@ -406,12 +410,53 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
find_SSB_and_RO_available(Mod_idP);
+ const NR_TDD_UL_DL_Pattern_t *tdd = &scc->tdd_UL_DL_ConfigurationCommon->pattern1;
+ const int nr_mix_slots = tdd->nrofDownlinkSymbols != 0 || tdd->nrofUplinkSymbols != 0;
+ const int nr_slots_period = tdd->nrofDownlinkSlots + tdd->nrofUplinkSlots + nr_mix_slots;
+ const int nr_dlmix_slots = tdd->nrofDownlinkSlots + (tdd->nrofDownlinkSymbols != 0);
+ const int nr_ulstart_slot = tdd->nrofDownlinkSlots + (tdd->nrofUplinkSymbols == 0);
+ for (int slot = 0; slot < n; ++slot) {
+ /* FIXME: it seems there is a problem with slot 0/10/slots right after UL:
+ * we just get retransmissions. Thus, do not schedule such slots in DL */
+ if (slot % nr_slots_period != 0)
+ RC.nrmac[Mod_idP]->dlsch_slot_bitmap[slot / 64] |= ((slot % nr_slots_period) < nr_dlmix_slots) << (slot % 64);
+ RC.nrmac[Mod_idP]->ulsch_slot_bitmap[slot / 64] |= ((slot % nr_slots_period) >= nr_ulstart_slot) << (slot % 64);
+ LOG_D(MAC,
+ "slot %d DL %d UL %d\n",
+ slot,
+ (RC.nrmac[Mod_idP]->dlsch_slot_bitmap[slot / 64] & (1 << (slot % 64))) != 0,
+ (RC.nrmac[Mod_idP]->ulsch_slot_bitmap[slot / 64] & (1 << (slot % 64))) != 0);
+ }
+
+ if (get_softmodem_params()->phy_test) {
+ RC.nrmac[Mod_idP]->pre_processor_dl = nr_preprocessor_phytest;
+ RC.nrmac[Mod_idP]->pre_processor_ul = nr_ul_preprocessor_phytest;
+ } else {
+ RC.nrmac[Mod_idP]->pre_processor_dl = nr_init_fr1_dlsch_preprocessor(Mod_idP, 0);
+ RC.nrmac[Mod_idP]->pre_processor_ul = nr_init_fr1_ulsch_preprocessor(Mod_idP, 0);
+ }
}
if (secondaryCellGroup) {
RC.nrmac[Mod_idP]->secondaryCellGroupCommon = secondaryCellGroup;
+ const NR_ServingCellConfig_t *servingCellConfig = secondaryCellGroup->spCellConfig->spCellConfigDedicated;
+ const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig->downlinkBWP_ToAddModList;
+ AssertFatal(bwpList->list.count > 0, "downlinkBWP_ToAddModList has no BWPs!\n");
+ for (int i = 0; i < bwpList->list.count; ++i) {
+ const NR_BWP_Downlink_t *bwp = bwpList->list.array[i];
+ calculate_preferred_dl_tda(Mod_idP, bwp);
+ }
+
+ const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList =
+ servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList;
+ AssertFatal(ubwpList->list.count > 0, "downlinkBWP_ToAddModList no BWPs!\n");
+ for (int i = 0; i < ubwpList->list.count; ++i) {
+ const NR_BWP_Uplink_t *ubwp = ubwpList->list.array[i];
+ calculate_preferred_ul_tda(Mod_idP, ubwp);
+ }
+
NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
if (add_ue == 1 && get_softmodem_params()->phy_test) {
const int UE_id = add_new_nr_ue(Mod_idP, rnti, secondaryCellGroup);
@@ -449,6 +494,13 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
}
}
}
+ } else {
+ ra->cfra = false;
+ ra->rnti = 0;
+ ra->preambles.num_preambles = MAX_NUM_NR_PRACH_PREAMBLES;
+ ra->preambles.preamble_list = (uint8_t *) malloc(MAX_NUM_NR_PRACH_PREAMBLES*sizeof(uint8_t));
+ for (int i = 0; i < MAX_NUM_NR_PRACH_PREAMBLES; i++)
+ ra->preambles.preamble_list[i] = i;
}
LOG_I(PHY,"Added new RA process for UE RNTI %04x with initial secondaryCellGroup\n", rnti);
} else { // secondaryCellGroup has been updated
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
index 584648c67f..7175a129ba 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
@@ -53,6 +53,7 @@
#include "executables/softmodem-common.h"
#include "nfapi/oai_integration/vendor_ext.h"
+#include "executables/nr-softmodem.h"
uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 };
@@ -65,7 +66,13 @@ void dump_mac_stats(gNB_MAC_INST *gNB)
NR_UE_info_t *UE_info = &gNB->UE_info;
int num = 1;
for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
- LOG_I(MAC, "UE ID %d RNTI %04x (%d/%d)\n", UE_id, UE_info->rnti[UE_id], num++, UE_info->num_UEs);
+ LOG_I(MAC, "UE ID %d RNTI %04x (%d/%d) PH %d dB PCMAX %d dBm\n",
+ UE_id,
+ UE_info->rnti[UE_id],
+ num++,
+ UE_info->num_UEs,
+ UE_info->UE_sched_ctrl[UE_id].ph,
+ UE_info->UE_sched_ctrl[UE_id].pcmax);
NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id];
const int avg_rsrp = stats->num_rsrp_meas > 0 ? stats->cumul_rsrp / stats->num_rsrp_meas : 0;
LOG_I(MAC, "UE %d: dlsch_rounds %d/%d/%d/%d, dlsch_errors %d, average RSRP %d (%d meas)\n",
@@ -76,10 +83,15 @@ void dump_mac_stats(gNB_MAC_INST *gNB)
stats->num_rsrp_meas = 0;
stats->cumul_rsrp = 0 ;
LOG_I(MAC, "UE %d: dlsch_total_bytes %d\n", UE_id, stats->dlsch_total_bytes);
- LOG_I(MAC, "UE %d: ulsch_rounds %d/%d/%d/%d, ulsch_errors %d\n",
+ const NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
+ LOG_I(MAC, "UE %d: ulsch_rounds %d/%d/%d/%d, ulsch_errors %d, PUSCH SNR %2.1f dB, PUCCH SNR %2.1f dB, noise rssi %2.1f dB\n",
UE_id,
stats->ulsch_rounds[0], stats->ulsch_rounds[1],
- stats->ulsch_rounds[2], stats->ulsch_rounds[3], stats->ulsch_errors);
+ stats->ulsch_rounds[2], stats->ulsch_rounds[3],
+ stats->ulsch_errors,
+ (float) sched_ctrl->pusch_snrx10 / 10,
+ (float) sched_ctrl->pucch_snrx10 / 10,
+ (float) (sched_ctrl->raw_rssi - 1280) / 10);
LOG_I(MAC,
"UE %d: ulsch_total_bytes_scheduled %d, ulsch_total_bytes_received %d\n",
UE_id,
@@ -91,6 +103,7 @@ void dump_mac_stats(gNB_MAC_INST *gNB)
LOG_I(MAC, "UE %d: LCID %d: %d bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]);
}
}
+ print_meas(&gNB->eNB_scheduler, "DL & UL scheduling timing stats", NULL, NULL);
}
void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
@@ -312,62 +325,23 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
protocol_ctxt_t ctxt;
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frame, slot,module_idP);
- int nb_periods_per_frame;
-
const int bwp_id = 1;
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = gNB->common_channels;
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
- NR_TDD_UL_DL_Pattern_t *tdd_pattern = &scc->tdd_UL_DL_ConfigurationCommon->pattern1;
-
- switch(scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity) {
- case 0:
- nb_periods_per_frame = 20; // 10ms/0p5ms
- break;
-
- case 1:
- nb_periods_per_frame = 16; // 10ms/0p625ms
- break;
-
- case 2:
- nb_periods_per_frame = 10; // 10ms/1ms
- break;
-
- case 3:
- nb_periods_per_frame = 8; // 10ms/1p25ms
- break;
-
- case 4:
- nb_periods_per_frame = 5; // 10ms/2ms
- break;
-
- case 5:
- nb_periods_per_frame = 4; // 10ms/2p5ms
- break;
-
- case 6:
- nb_periods_per_frame = 2; // 10ms/5ms
- break;
-
- case 7:
- nb_periods_per_frame = 1; // 10ms/10ms
- break;
-
- default:
- AssertFatal(1==0,"Undefined tdd period %ld\n", scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity);
- }
if (slot==0 && (*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]>=257)) {
+ const NR_TDD_UL_DL_Pattern_t *tdd = &scc->tdd_UL_DL_ConfigurationCommon->pattern1;
+ const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
+ const int nr_mix_slots = tdd->nrofDownlinkSymbols != 0 || tdd->nrofUplinkSymbols != 0;
+ const int nr_slots_period = tdd->nrofDownlinkSlots + tdd->nrofUplinkSlots + nr_mix_slots;
+ const int nb_periods_per_frame = n / nr_slots_period;
// re-initialization of tdd_beam_association at beginning of frame (only for FR2)
for (int i=0; itdd_beam_association[i] = -1;
}
- int num_slots_per_tdd = (nr_slots_per_frame[*scc->ssbSubcarrierSpacing])/nb_periods_per_frame;
-
- const int nr_ulmix_slots = tdd_pattern->nrofUplinkSlots + (tdd_pattern->nrofUplinkSymbols!=0);
-
start_meas(&RC.nrmac[module_idP]->eNB_scheduler);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_IN);
@@ -381,17 +355,6 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
nr_rrc_trigger(&ctxt, 0 /*CC_id*/, frame, slot >> *scc->ssbSubcarrierSpacing);
}
-#define BIT(x) (1 << (x))
- const uint64_t dlsch_in_slot_bitmap = BIT( 1) | BIT( 2) | BIT( 3) | BIT( 4) | BIT( 5) | BIT( 6)
- | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16);
-
- uint8_t prach_config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex;
- uint64_t ulsch_in_slot_bitmap;
- if (prach_config_index==4) //this is the PRACH config used in the Benetel RRU. TODO: make this generic for any PRACH config.
- ulsch_in_slot_bitmap = BIT( 8) | BIT( 9);
- else
- ulsch_in_slot_bitmap = BIT( 8) | BIT(18);
-
memset(RC.nrmac[module_idP]->cce_list[bwp_id][0],0,MAX_NUM_CCE*sizeof(int)); // coreset0
memset(RC.nrmac[module_idP]->cce_list[bwp_id][1],0,MAX_NUM_CCE*sizeof(int)); // coresetid 1
NR_UE_info_t *UE_info = &RC.nrmac[module_idP]->UE_info;
@@ -417,7 +380,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
// This schedules MIB
- schedule_nr_mib(module_idP, frame, slot, nr_slots_per_frame[*scc->ssbSubcarrierSpacing],nb_periods_per_frame);
+ schedule_nr_mib(module_idP, frame, slot);
// This schedules SIB1
if ( get_softmodem_params()->sa == 1 )
@@ -452,14 +415,10 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
}
// This schedules the DCI for Uplink and subsequently PUSCH
- {
- nr_schedule_ulsch(module_idP, frame, slot, num_slots_per_tdd, nr_ulmix_slots, ulsch_in_slot_bitmap);
- }
+ nr_schedule_ulsch(module_idP, frame, slot);
// This schedules the DCI for Downlink and PDSCH
- if (is_xlsch_in_slot(dlsch_in_slot_bitmap, slot))
- nr_schedule_ue_spec(module_idP, frame, slot);
-
+ nr_schedule_ue_spec(module_idP, frame, slot);
nr_schedule_pucch(module_idP, frame, slot);
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
index bc297225af..cdf7eb24ff 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
@@ -65,7 +65,7 @@ int16_t ssb_index_from_prach(module_id_t module_idP,
uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex;
uint8_t fdm = cfg->prach_config.num_prach_fd_occasions.value;
- uint8_t total_RApreambles = 64;
+ uint8_t total_RApreambles = MAX_NUM_NR_PRACH_PREAMBLES;
if( scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL)
total_RApreambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles;
@@ -130,7 +130,7 @@ int16_t ssb_index_from_prach(module_id_t module_idP,
}
}
- LOG_D(MAC, "Frame %d, Slot %d: Prach Occasion id = %d ssb per RO = %f number of active SSB %u index = %d fdm %u symbol index %u freq_index %u total_RApreambles %u\n",
+ LOG_D(NR_MAC, "Frame %d, Slot %d: Prach Occasion id = %d ssb per RO = %f number of active SSB %u index = %d fdm %u symbol index %u freq_index %u total_RApreambles %u\n",
frameP, slotP, prach_occasion_id, num_ssb_per_RO, num_active_ssb, index, fdm, start_symbol_index, freq_index, total_RApreambles);
return index;
@@ -227,7 +227,7 @@ void find_SSB_and_RO_available(module_id_t module_idP) {
cc->total_prach_occasions = total_RA_occasions - unused_RA_occasion;
cc->num_active_ssb = num_active_ssb;
- LOG_I(MAC,
+ LOG_I(NR_MAC,
"Total available RO %d, num of active SSB %d: unused RO = %d association_period %u N_RA_sfn %u total_prach_occasions_per_config_period %u\n",
cc->total_prach_occasions,
cc->num_active_ssb,
@@ -313,7 +313,7 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP
format0,
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig);
- LOG_D(MAC, "Frame %d, Slot %d: Prach Occasion id = %u fdm index = %u start symbol = %u slot index = %u subframe index = %u \n",
+ LOG_D(NR_MAC, "Frame %d, Slot %d: Prach Occasion id = %u fdm index = %u start symbol = %u slot index = %u subframe index = %u \n",
frameP, slotP,
prach_occasion_id, prach_pdu->num_ra,
prach_pdu->prach_start_symbol,
@@ -377,6 +377,16 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP
}
}
}
+
+ // block resources in vrb_map_UL
+ const NR_RACH_ConfigGeneric_t *rach_ConfigGeneric =
+ &scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric;
+ const uint8_t mu_pusch =
+ scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
+ const int16_t N_RA_RB = get_N_RA_RB(cfg->prach_config.prach_sub_c_spacing.value, mu_pusch);
+ uint16_t *vrb_map_UL = &cc->vrb_map_UL[slotP * MAX_BWP_SIZE];
+ for (int i = 0; i < N_RA_RB * fdm; ++i)
+ vrb_map_UL[rach_ConfigGeneric->msg1_FrequencyStart + i] = 0xff; // all symbols
}
}
}
@@ -444,19 +454,19 @@ void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot,
uint8_t start_next_period = (rach_slot-(rach_slot%tdd_period_slot)+tdd_period_slot)%nr_slots_per_frame[mu];
*msg2_slot = start_next_period + last_dl_slot_period; // initializing scheduling of slot to next mixed (or last dl) slot
- *msg2_frame = (*msg2_slot>(rach_slot))? rach_frame : (rach_frame +1);
+ *msg2_frame = ((*msg2_slot>(rach_slot))? rach_frame : (rach_frame+1))%1024;
// we can't schedule msg2 before sl_ahead since prach
int eff_slot = *msg2_slot+(*msg2_frame-rach_frame)*nr_slots_per_frame[mu];
if ((eff_slot-rach_slot)<=sl_ahead) {
*msg2_slot = (*msg2_slot+tdd_period_slot)%nr_slots_per_frame[mu];
- *msg2_frame = (*msg2_slot>(rach_slot))? rach_frame : (rach_frame +1);
+ *msg2_frame = ((*msg2_slot>(rach_slot))? rach_frame : (rach_frame+1))%1024;
}
if (FR==nr_FR2) {
int num_tdd_period = *msg2_slot/tdd_period_slot;
while((tdd_beam_association[num_tdd_period]!=-1)&&(tdd_beam_association[num_tdd_period]!=beam_index)) {
*msg2_slot = (*msg2_slot+tdd_period_slot)%nr_slots_per_frame[mu];
- *msg2_frame = (*msg2_slot>(rach_slot))? rach_frame : (rach_frame +1);
+ *msg2_frame = ((*msg2_slot>(rach_slot))? rach_frame : (rach_frame+1))%1024;
num_tdd_period = *msg2_slot/tdd_period_slot;
}
if(tdd_beam_association[num_tdd_period] == -1)
@@ -491,13 +501,13 @@ void nr_initiate_ra_proc(module_id_t module_idP,
NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
- uint8_t total_RApreambles = 64;
- uint8_t num_ssb_per_RO = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present;
+ uint8_t total_RApreambles = MAX_NUM_NR_PRACH_PREAMBLES;
+ uint8_t num_ssb_per_RO = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present;
int pr_found;
if( scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL)
- total_RApreambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles;
-
+ total_RApreambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles;
+
if(num_ssb_per_RO > 3) { /*num of ssb per RO >= 1*/
num_ssb_per_RO -= 3;
total_RApreambles = total_RApreambles/num_ssb_per_RO ;
@@ -528,14 +538,15 @@ void nr_initiate_ra_proc(module_id_t module_idP,
else
ra_rnti = 1 + symbol + (slotP * 14) + (freq_index * 14 * 80) + (ul_carrier_id * 14 * 80 * 8);
- // This should be handled differently when we use the initialBWP for RA
ra->bwp_id = 1;
- NR_BWP_Downlink_t *bwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList
- ->list.array[ra->bwp_id - 1];
+ NR_BWP_Downlink_t *bwp = NULL; // For SA we use InitialBWP
+ if(get_softmodem_params()->sa != 1) {
+ bwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id-1];
+ }
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1);
- LOG_I(MAC,
+ LOG_D(NR_MAC,
"[gNB %d][RAPROC] CC_id %d Frame %d, Slot %d Initiating RA procedure for preamble index %d\n",
module_idP,
CC_id,
@@ -550,26 +561,33 @@ void nr_initiate_ra_proc(module_id_t module_idP,
// if the preamble received correspond to one of the listed
if (!(preamble_index == ra->preambles.preamble_list[beam_index])) {
LOG_E(
- MAC,
+ NR_MAC,
"[gNB %d][RAPROC] FAILURE: preamble %d does not correspond to any of the ones in rach_ConfigDedicated\n",
module_idP,
preamble_index);
continue; // if the PRACH preamble does not correspond to any of the ones sent through RRC abort RA proc
}
}
- int loop = 0;
- LOG_D(MAC, "Frame %d, Slot %d: Activating RA process \n", frameP, slotP);
+ LOG_D(NR_MAC, "Frame %d, Slot %d: Activating RA process \n", frameP, slotP);
ra->state = Msg2;
ra->timing_offset = timing_offset;
ra->preamble_slot = slotP;
- struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList =
- bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList;
+ NR_SearchSpaceId_t ra_SearchSpace = 0;
+ struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = NULL;
+ if(bwp) {
+ commonSearchSpaceList = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList;
+ ra_SearchSpace = *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace;
+ } else {
+ commonSearchSpaceList = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList;
+ ra_SearchSpace = *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->ra_SearchSpace;
+ }
AssertFatal(commonSearchSpaceList->list.count > 0, "common SearchSpace list has 0 elements\n");
+
// Common searchspace list
for (int i = 0; i < commonSearchSpaceList->list.count; i++) {
ss = commonSearchSpaceList->list.array[i];
- if (ss->searchSpaceId == *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace)
+ if (ss->searchSpaceId == ra_SearchSpace)
ra->ra_ss = ss;
}
@@ -590,8 +608,11 @@ void nr_initiate_ra_proc(module_id_t module_idP,
ra->Msg2_frame = msg2_frame;
ra->Msg2_slot = msg2_slot;
- LOG_I(MAC, "%s() Msg2[%04d%d] SFN/SF:%04d%d\n", __FUNCTION__, ra->Msg2_frame, ra->Msg2_slot, frameP, slotP);
- if (!ra->cfra) {
+ LOG_D(NR_MAC, "%s() Msg2[%04d%d] SFN/SF:%04d%d\n", __FUNCTION__, ra->Msg2_frame, ra->Msg2_slot, frameP, slotP);
+
+ int loop = 0;
+ // This condition allows for the usage of a preconfigured rnti for the first UE
+ if (!ra->cfra || ra->rnti == 0) {
do {
ra->rnti = (taus() % 65518) + 1;
loop++;
@@ -599,15 +620,16 @@ void nr_initiate_ra_proc(module_id_t module_idP,
&& !((find_nr_UE_id(module_idP, ra->rnti) == -1) && (find_nr_RA_id(module_idP, CC_id, ra->rnti) == -1)
&& ra->rnti >= 1 && ra->rnti <= 65519));
if (loop == 100) {
- LOG_E(MAC, "%s:%d:%s: [RAPROC] initialisation random access aborted\n", __FILE__, __LINE__, __FUNCTION__);
+ LOG_E(NR_MAC, "%s:%d:%s: [RAPROC] initialisation random access aborted\n", __FILE__, __LINE__, __FUNCTION__);
abort();
}
}
+
ra->RA_rnti = ra_rnti;
ra->preamble_index = preamble_index;
ra->beam_id = beam_index;
- LOG_I(MAC,
+ LOG_D(NR_MAC,
"[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x SSB "
"index %u\n",
module_idP,
@@ -621,38 +643,38 @@ void nr_initiate_ra_proc(module_id_t module_idP,
return;
}
}
- LOG_E(MAC, "[gNB %d][RAPROC] FAILURE: CC_id %d Frame %d initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, preamble_index);
+ LOG_E(NR_MAC, "[gNB %d][RAPROC] FAILURE: CC_id %d Frame %d initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, preamble_index);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0);
}
-void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
-{
- gNB_MAC_INST *mac = RC.nrmac[module_idP];
+ void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
+ {
+ gNB_MAC_INST *mac = RC.nrmac[module_idP];
- start_meas(&mac->schedule_ra);
- for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
- NR_COMMON_channels_t *cc = &mac->common_channels[CC_id];
- for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
- NR_RA_t *ra = &cc->ra[i];
- LOG_D(MAC, "RA[state:%d]\n", ra->state);
- switch (ra->state) {
- case Msg2:
- nr_generate_Msg2(module_idP, CC_id, frameP, slotP, ra);
- break;
- case Msg4:
- // generate_Msg4(module_idP, CC_id, frameP, slotP);
- break;
- case WAIT_Msg4_ACK:
- // check_Msg4_retransmission(module_idP, CC_id, frameP, slotP);
- break;
- default:
- break;
+ start_meas(&mac->schedule_ra);
+ for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+ NR_COMMON_channels_t *cc = &mac->common_channels[CC_id];
+ for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
+ NR_RA_t *ra = &cc->ra[i];
+ LOG_D(NR_MAC, "RA[state:%d]\n", ra->state);
+ switch (ra->state) {
+ case Msg2:
+ nr_generate_Msg2(module_idP, CC_id, frameP, slotP, ra);
+ break;
+ case Msg4:
+ nr_generate_Msg4(module_idP, CC_id, frameP, slotP, ra);
+ break;
+ case WAIT_Msg4_ACK:
+ nr_check_Msg4_Ack(module_idP, CC_id, frameP, slotP, ra);
+ break;
+ default:
+ break;
+ }
}
}
+ stop_meas(&mac->schedule_ra);
}
- stop_meas(&mac->schedule_ra);
-}
void nr_get_Msg3alloc(module_id_t module_id,
int CC_id,
@@ -663,33 +685,33 @@ void nr_get_Msg3alloc(module_id_t module_id,
NR_RA_t *ra,
int16_t *tdd_beam_association) {
- // msg3 is schedulend in mixed slot in the following TDD period
+ // msg3 is schedulend in mixed slot in the following TDD period
- uint16_t msg3_nb_rb = 8 + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); // sdu has 6 or 8 bytes
+ uint16_t msg3_nb_rb = 8 + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); // sdu has 6 or 8 bytes
- int mu = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
- int StartSymbolIndex, NrOfSymbols, startSymbolAndLength, temp_slot;
- ra->Msg3_tda_id = 16; // initialization to a value above limit
+ int mu = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
+ int StartSymbolIndex, NrOfSymbols, startSymbolAndLength, temp_slot;
+ ra->Msg3_tda_id = 16; // initialization to a value above limit
- for (int i=0; ibwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.count; i++) {
- startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength;
- SLIV2SL(startSymbolAndLength, &StartSymbolIndex, &NrOfSymbols);
- // we want to transmit in the uplink symbols of mixed slot
- if (NrOfSymbols == scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols) {
- ra->Msg3_tda_id = i;
- break;
+ for (int i=0; ibwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.count; i++) {
+ startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength;
+ SLIV2SL(startSymbolAndLength, &StartSymbolIndex, &NrOfSymbols);
+ // we want to transmit in the uplink symbols of mixed slot
+ if (NrOfSymbols == scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols) {
+ ra->Msg3_tda_id = i;
+ break;
+ }
}
- }
- AssertFatal(ra->Msg3_tda_id<16,"Unable to find Msg3 time domain allocation in list\n");
+ AssertFatal(ra->Msg3_tda_id<16,"Unable to find Msg3 time domain allocation in list\n");
- uint8_t k2 = *ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->k2;
+ uint8_t k2 = *ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->k2;
- temp_slot = current_slot + k2 + DELTA[mu]; // msg3 slot according to 8.3 in 38.213
- ra->Msg3_slot = temp_slot%nr_slots_per_frame[mu];
- if (nr_slots_per_frame[mu]>temp_slot)
- ra->Msg3_frame = current_frame;
- else
- ra->Msg3_frame = current_frame + (temp_slot/nr_slots_per_frame[mu]);
+ temp_slot = current_slot + k2 + DELTA[mu]; // msg3 slot according to 8.3 in 38.213
+ ra->Msg3_slot = temp_slot%nr_slots_per_frame[mu];
+ if (nr_slots_per_frame[mu]>temp_slot)
+ ra->Msg3_frame = current_frame;
+ else
+ ra->Msg3_frame = (current_frame + (temp_slot/nr_slots_per_frame[mu]))%1024;
// beam association for FR2
if (*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0] >= 257) {
@@ -703,12 +725,12 @@ void nr_get_Msg3alloc(module_id_t module_id,
tdd_beam_association[num_tdd_period] = ra->beam_id;
}
- LOG_I(MAC, "[RAPROC] Msg3 slot %d: current slot %u Msg3 frame %u k2 %u Msg3_tda_id %u start symbol index %u\n", ra->Msg3_slot, current_slot, ra->Msg3_frame, k2,ra->Msg3_tda_id, StartSymbolIndex);
+ LOG_D(NR_MAC, "[RAPROC] Msg3 slot %d: current slot %u Msg3 frame %u k2 %u Msg3_tda_id %u start symbol index %u\n", ra->Msg3_slot, current_slot, ra->Msg3_frame, k2,ra->Msg3_tda_id, StartSymbolIndex);
uint16_t *vrb_map_UL =
&RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[ra->Msg3_slot * MAX_BWP_SIZE];
const uint16_t bwpSize = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
- /* search msg3_nb_rb free RBs */
+ /* search msg3_nb_rb free RBs */
int rbSize = 0;
int rbStart = 0;
while (rbSize < msg3_nb_rb) {
@@ -733,7 +755,7 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
if (ra->state == RA_IDLE) {
- LOG_W(MAC,"RA is not active for RA %X. skipping msg3 scheduling\n", ra->rnti);
+ LOG_W(NR_MAC,"RA is not active for RA %X. skipping msg3 scheduling\n", ra->rnti);
return;
}
@@ -748,7 +770,7 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
vrb_map_UL[i + ra->msg3_first_rb] = 1;
}
- LOG_I(MAC, "[gNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA is active, Msg3 in (%d,%d)\n", module_idP, frameP, slotP, CC_id, ra->Msg3_frame, ra->Msg3_slot);
+ LOG_D(NR_MAC, "[gNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA is active, Msg3 in (%d,%d)\n", module_idP, frameP, slotP, CC_id, ra->Msg3_frame, ra->Msg3_slot);
nfapi_nr_ul_tti_request_t *future_ul_tti_req = &RC.nrmac[module_idP]->UL_tti_req_ahead[CC_id][ra->Msg3_slot];
AssertFatal(future_ul_tti_req->SFN == ra->Msg3_frame
@@ -770,7 +792,7 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
AssertFatal(ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
"downlinkBWP_ToAddModList has %d BWP!\n", ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
NR_BWP_Uplink_t *ubwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id - 1];
- LOG_D(MAC, "Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d,%d) for rnti: %d\n",
+ LOG_D(NR_MAC, "Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d,%d) for rnti: %d\n",
frameP,
slotP,
ra->Msg3_frame,
@@ -815,7 +837,8 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
pusch_pdu->dmrs_ports = 1; // 6.2.2 in 38.214 only port 0 to be used
pusch_pdu->num_dmrs_cdm_grps_no_data = 2; // no data in dmrs symbols as in 6.2.2 in 38.214
pusch_pdu->resource_alloc = 1; //type 1
- pusch_pdu->rb_start = ra->msg3_first_rb + ibwp_start - abwp_start; // as for 6.3.1.7 in 38.211
+ //pusch_pdu->rb_start = ra->msg3_first_rb + ibwp_start - abwp_start; // as for 6.3.1.7 in 38.211
+ pusch_pdu->rb_start = ra->msg3_first_rb;
if (ra->msg3_nb_rb > pusch_pdu->bwp_size)
AssertFatal(1==0,"MSG3 allocated number of RBs exceed the BWP size\n");
else
@@ -850,85 +873,87 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra)
{
- int mcsIndex;
- int startSymbolAndLength = 0, StartSymbolIndex = -1, NrOfSymbols = 14, StartSymbolIndex_tmp, NrOfSymbols_tmp, x_Overhead, time_domain_assignment = 0;
- gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
- NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
- NR_SearchSpace_t *ss = ra->ra_ss;
- // This code from this point on will not work on initialBWP or CORESET0
- AssertFatal(ra->bwp_id > 0, "cannot work on initialBWP for now\n");
-
- AssertFatal(ra->secondaryCellGroup, "no secondaryCellGroup for RNTI %04x\n", ra->crnti);
- AssertFatal(ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
- "downlinkBWP_ToAddModList has %d BWP!\n",
- ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
-
- uint16_t RA_rnti = ra->RA_rnti;
- long locationAndBandwidth;
-
- // check if UE is doing RA on CORESET0 , InitialBWP or configured BWP from SCD
- // get the BW of the PDCCH for PDCCH size and RAR PDSCH size
-
- NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
- int dci10_bw = 0;
-
- if (ra->coreset0_configured == 1) {
- AssertFatal(1==0,"This is a standalone condition\n");
- }
- else { // on configured BWP or initial LDBWP, bandwidth parameters in DCI correspond size of initialBWP
- locationAndBandwidth = scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth;
- dci10_bw = NRRIV2BW(locationAndBandwidth, MAX_BWP_SIZE);
- }
+ gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
+ NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
if ((ra->Msg2_frame == frameP) && (ra->Msg2_slot == slotP)) {
+ uint8_t time_domain_assignment = 1;
+ uint8_t mcsIndex = 0;
+ int rbStart = 0;
+ int rbSize = 8;
+
+ NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
+ NR_SearchSpace_t *ss = ra->ra_ss;
+
+ long BWPSize = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+
+ NR_BWP_Downlink_t *bwp = NULL; // For SA we use InitialBWP
+ if(get_softmodem_params()->sa != 1) {
+ bwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id-1];
+ }
+
+ NR_ControlResourceSet_t *coreset = NULL;
+ if(bwp) {
+ coreset = get_coreset(bwp, ss, 0);
+ } else {
+ coreset = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonControlResourceSet;
+ }
+
+ long BWPStart = 0;
+ if (get_softmodem_params()->sa != 1) {
+ BWPStart = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+ } else {
+ BWPStart = NRRIV2PRBOFFSET(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+ }
+
uint16_t *vrb_map = cc[CC_id].vrb_map;
- int rbStart = 0, rbSize = 6;
- for (int i = 0; (i < rbSize) && (rbStart <= (dci10_bw - rbSize)); i++) {
+ for (int i = 0; (i < rbSize) && (rbStart <= (BWPSize - rbSize)); i++) {
if (vrb_map[rbStart + i]) {
rbStart += i;
i = 0;
}
}
- if (rbStart > (dci10_bw - rbSize)) {
- LOG_E(MAC, "%s(): cannot find free vrb_map for RA RNTI %04x!\n", __func__, ra->RA_rnti);
+
+ if (rbStart > (BWPSize - rbSize)) {
+ LOG_E(NR_MAC, "%s(): cannot find free vrb_map for RA RNTI %04x!\n", __func__, ra->RA_rnti);
return;
}
+ // Checking if the DCI allocation is feasible in current subframe
nfapi_nr_dl_tti_request_body_t *dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body;
- // Checking if the DCI allocation is feasible in current subframe: we might
- // need to need up to two (PDCCH + PDSCH) messages, so check that we can
- // always allocate both (this might be an overestimation, since the PDCCH
- // message might already exist)
if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) {
- LOG_I(MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, RA_rnti);
+ LOG_I(NR_MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, ra->RA_rnti);
return;
}
- uint8_t nr_of_candidates, aggregation_level;
+ uint8_t aggregation_level;
+ uint8_t nr_of_candidates;
find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss);
- NR_BWP_Downlink_t *bwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id - 1];
- NR_ControlResourceSet_t *coreset = get_coreset(bwp, ss, 0 /* common */);
- int CCEIndex = allocate_nr_CCEs(nr_mac,
- bwp,
- coreset,
- aggregation_level,
- 0, // Y
- 0, // m
- nr_of_candidates);
-
+ int CCEIndex = allocate_nr_CCEs(nr_mac, bwp, coreset, aggregation_level,0,0,nr_of_candidates);
if (CCEIndex < 0) {
- LOG_E(MAC, "%s(): cannot find free CCE for RA RNTI %04x!\n", __func__, ra->rnti);
+ LOG_E(NR_MAC, "%s(): cannot find free CCE for RA RNTI %04x!\n", __func__, ra->rnti);
return;
}
- /* look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not
- * exist, create it. This is especially important if we have multiple RAs,
- * and the DLSCH has to reuse them, so we need to mark them */
- const int bwpid = bwp->bwp_Id;
+ // Calculate number of symbols
+ int startSymbolIndex, nrOfSymbols;
+ const int startSymbolAndLength = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->
+ downlinkBWP_ToAddModList->list.array[ra->bwp_id-1]->bwp_Common->pdsch_ConfigCommon->choice.setup->
+ pdsch_TimeDomainAllocationList->list.array[time_domain_assignment]->startSymbolAndLength;
+ SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
+ AssertFatal(startSymbolIndex >= 0, "StartSymbolIndex is negative\n");
+
+ uint8_t numDmrsCdmGrpsNoData = 2;
+ if (nrOfSymbols == 2) {
+ numDmrsCdmGrpsNoData = 1;
+ }
+
+ // look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not exist, create it. This is especially
+ // important if we have multiple RAs, and the DLSCH has to reuse them, so we need to mark them
const int coresetid = coreset->controlResourceSetId;
- nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][bwpid][coresetid];
+ nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][ra->bwp_id][coresetid];
if (!pdcch_pdu_rel15) {
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
memset(dl_tti_pdcch_pdu, 0, sizeof(nfapi_nr_dl_tti_request_pdu_t));
@@ -937,7 +962,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
dl_req->nPDUs += 1;
pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
nr_configure_pdcch(pdcch_pdu_rel15, ss, coreset, scc, bwp);
- nr_mac->pdcch_pdu_idx[CC_id][bwpid][coresetid] = pdcch_pdu_rel15;
+ nr_mac->pdcch_pdu_idx[CC_id][ra->bwp_id][coresetid] = pdcch_pdu_rel15;
}
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
@@ -947,49 +972,350 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
dl_req->nPDUs+=1;
nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15;
- LOG_I(MAC,"[gNB %d] [RAPROC] CC_id %d Frame %d, slotP %d: Generating RAR DCI, state %d\n", module_idP, CC_id, frameP, slotP, ra->state);
+ LOG_I(NR_MAC,"[gNB %d][RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg2 DCI, rnti 0x%x, state %d\n",
+ module_idP, CC_id, frameP, slotP, ra->RA_rnti, ra->state);
- NR_BWP_Uplink_t *ubwp=ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1];
+ AssertFatal(ra->secondaryCellGroup, "no secondaryCellGroup for RNTI %04x\n", ra->RA_rnti);
- LOG_I(MAC, "[RAPROC] Scheduling common search space DCI type 1 dlBWP BW %d\n", dci10_bw);
+ AssertFatal(ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
+ "downlinkBWP_ToAddModList has %d BWP!\n",
+ ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
- // Qm>2 not allowed for RAR
- if (get_softmodem_params()->do_ra)
- mcsIndex = 9;
- else
- mcsIndex = 0;
-
- pdsch_pdu_rel15->pduBitmap = 0;
- pdsch_pdu_rel15->rnti = RA_rnti;
- /* SCF222: PDU index incremented for each PDSCH PDU sent in TX control
- * message. This is used to associate control information to data and is
- * reset every slot. */
+ // SCF222: PDU index incremented for each PDSCH PDU sent in TX control message. This is used to associate control
+ // information to data and is reset every slot.
const int pduindex = nr_mac->pdu_index[CC_id]++;
- pdsch_pdu_rel15->pduIndex = pduindex;
-
- pdsch_pdu_rel15->BWPSize = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
- pdsch_pdu_rel15->BWPStart = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
- pdsch_pdu_rel15->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing;
- pdsch_pdu_rel15->CyclicPrefix = 0;
- pdsch_pdu_rel15->NrOfCodewords = 1;
- pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(mcsIndex,0);
- pdsch_pdu_rel15->qamModOrder[0] = 2;
- pdsch_pdu_rel15->mcsIndex[0] = mcsIndex;
- if (bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table == NULL)
- pdsch_pdu_rel15->mcsTable[0] = 0;
+ uint8_t mcsTableIdx = 0;
+ if (bwp==NULL || bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table == NULL)
+ mcsTableIdx = 0;
else{
if (*bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table == 0)
- pdsch_pdu_rel15->mcsTable[0] = 1;
+ mcsTableIdx = 1;
else
- pdsch_pdu_rel15->mcsTable[0] = 2;
+ mcsTableIdx = 2;
}
+
+ AssertFatal(numDmrsCdmGrpsNoData == 1 || numDmrsCdmGrpsNoData == 2,
+ "nr_mac->schedCtrlCommon->numDmrsCdmGrpsNoData %d is not possible",
+ numDmrsCdmGrpsNoData);
+
+ pdsch_pdu_rel15->pduBitmap = 0;
+ pdsch_pdu_rel15->rnti = ra->RA_rnti;
+ pdsch_pdu_rel15->pduIndex = pduindex;
+ pdsch_pdu_rel15->BWPSize = BWPSize;
+ pdsch_pdu_rel15->BWPStart = BWPStart;
+ pdsch_pdu_rel15->SubcarrierSpacing = bwp!=NULL ? bwp->bwp_Common->genericParameters.subcarrierSpacing : scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing;
+ pdsch_pdu_rel15->CyclicPrefix = 0;
+ pdsch_pdu_rel15->NrOfCodewords = 1;
+ pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(mcsIndex,mcsTableIdx);
+ pdsch_pdu_rel15->qamModOrder[0] = 2;
+ pdsch_pdu_rel15->mcsIndex[0] = mcsIndex;
+ pdsch_pdu_rel15->mcsTable[0] = mcsTableIdx;
pdsch_pdu_rel15->rvIndex[0] = 0;
pdsch_pdu_rel15->dataScramblingId = *scc->physCellId;
pdsch_pdu_rel15->nrOfLayers = 1;
pdsch_pdu_rel15->transmissionScheme = 0;
pdsch_pdu_rel15->refPoint = 0;
- pdsch_pdu_rel15->dmrsConfigType = 0;//Reconfigure Msg2 to use pdsch_dmrs_type1
+ pdsch_pdu_rel15->dmrsConfigType = bwp!=NULL ? (bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1) : 0;
+ pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId;
+ pdsch_pdu_rel15->SCID = 0;
+ pdsch_pdu_rel15->numDmrsCdmGrpsNoData = numDmrsCdmGrpsNoData;
+ pdsch_pdu_rel15->dmrsPorts = 1;
+ pdsch_pdu_rel15->resourceAlloc = 1;
+ pdsch_pdu_rel15->rbStart = rbStart;
+ pdsch_pdu_rel15->rbSize = rbSize;
+ pdsch_pdu_rel15->VRBtoPRBMapping = 0;
+ pdsch_pdu_rel15->StartSymbolIndex = startSymbolIndex;
+ pdsch_pdu_rel15->NrOfSymbols = nrOfSymbols;
+ pdsch_pdu_rel15->dlDmrsSymbPos = fill_dmrs_mask(NULL,
+ nr_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position,
+ nrOfSymbols,
+ startSymbolIndex);
+
+ int x_Overhead = 0;
+ uint8_t tb_scaling = 0;
+ nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead, pdsch_pdu_rel15->numDmrsCdmGrpsNoData, tb_scaling);
+
+ // Fill PDCCH DL DCI PDU
+ nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci];
+ pdcch_pdu_rel15->numDlDci++;
+ dci_pdu->RNTI = ra->RA_rnti;
+ dci_pdu->ScramblingId = *scc->physCellId;
+ dci_pdu->ScramblingRNTI = 0;
+ dci_pdu->AggregationLevel = aggregation_level;
+ dci_pdu->CceIndex = CCEIndex;
+ dci_pdu->beta_PDCCH_1_0 = 0;
+ dci_pdu->powerControlOffsetSS = 1;
+
+ dci_pdu_rel15_t dci_payload;
+ dci_payload.frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pdsch_pdu_rel15->rbSize,
+ pdsch_pdu_rel15->rbStart,
+ pdsch_pdu_rel15->BWPSize);
+
+ dci_payload.time_domain_assignment.val = time_domain_assignment;
+ dci_payload.vrb_to_prb_mapping.val = 0;
+ dci_payload.mcs = pdsch_pdu_rel15->mcsIndex[0];
+ dci_payload.tb_scaling = tb_scaling;
+
+ LOG_D(NR_MAC,
+ "[RAPROC] DCI type 1 payload: freq_alloc %d (%d,%d,%d), time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d \n",
+ dci_payload.frequency_domain_assignment.val,
+ pdsch_pdu_rel15->rbStart,
+ pdsch_pdu_rel15->rbSize,
+ pdsch_pdu_rel15->BWPSize,
+ dci_payload.time_domain_assignment.val,
+ dci_payload.vrb_to_prb_mapping.val,
+ dci_payload.mcs,
+ dci_payload.tb_scaling);
+
+ LOG_D(NR_MAC,
+ "[RAPROC] DCI params: rnti 0x%x, rnti_type %d, dci_format %d coreset params: FreqDomainResource %llx, start_symbol %d n_symb %d\n",
+ pdcch_pdu_rel15->dci_pdu[0].RNTI,
+ NR_RNTI_RA,
+ NR_DL_DCI_FORMAT_1_0,
+ (unsigned long long)pdcch_pdu_rel15->FreqDomainResource,
+ pdcch_pdu_rel15->StartSymbolIndex,
+ pdcch_pdu_rel15->DurationSymbols);
+
+ fill_dci_pdu_rel15(scc,
+ nr_mac->secondaryCellGroupCommon,
+ &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci - 1],
+ &dci_payload,
+ NR_DL_DCI_FORMAT_1_0,
+ NR_RNTI_RA,
+ pdsch_pdu_rel15->BWPSize,
+ ra->bwp_id);
+
+ // DL TX request
+ nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs];
+
+ // Program UL processing for Msg3
+ NR_BWP_Uplink_t *ubwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1];
+ nr_get_Msg3alloc(module_idP, CC_id, scc, ubwp, slotP, frameP, ra, nr_mac->tdd_beam_association);
+ nr_add_msg3(module_idP, CC_id, frameP, slotP, ra, (uint8_t *) &tx_req->TLVs[0].value.direct[0]);
+
+ if(ra->cfra) {
+ LOG_I(NR_MAC, "Frame %d, Subframe %d: Setting RA-Msg3 reception for Frame %d Subframe %d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot);
+ }
+
+ T(T_GNB_MAC_DL_RAR_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(ra->RA_rnti), T_INT(frameP),
+ T_INT(slotP), T_INT(0), T_BUFFER(&tx_req->TLVs[0].value.direct[0], tx_req->TLVs[0].length));
+
+ tx_req->PDU_length = pdsch_pdu_rel15->TBSize[0];
+ tx_req->PDU_index = pduindex;
+ tx_req->num_TLV = 1;
+ tx_req->TLVs[0].length = tx_req->PDU_length + 2;
+ nr_mac->TX_req[CC_id].SFN = frameP;
+ nr_mac->TX_req[CC_id].Number_of_PDUs++;
+ nr_mac->TX_req[CC_id].Slot = slotP;
+
+ // Mark the corresponding RBs as used
+ for (int rb = 0; rb < rbSize; rb++) {
+ vrb_map[rb + rbStart] = 1;
+ }
+
+ ra->state = WAIT_Msg3;
+ LOG_I(NR_MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: RA state %d\n", module_idP, frameP, slotP, ra->state);
+ }
+}
+
+void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra) {
+
+ gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
+ NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
+
+ if (ra->Msg4_frame == frameP && ra->Msg4_slot == slotP ) {
+
+ uint8_t time_domain_assignment = 0;
+ uint8_t mcsIndex = 0;
+
+ NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
+ NR_SearchSpace_t *ss = ra->ra_ss;
+
+ NR_BWP_Downlink_t *bwp = NULL; // For SA we use InitialBWP
+ if(get_softmodem_params()->sa != 1) {
+ bwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id-1];
+ }
+
+ NR_ControlResourceSet_t *coreset = NULL;
+ if(bwp) {
+ coreset = get_coreset(bwp, ss, 0);
+ } else {
+ coreset = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonControlResourceSet;
+ }
+
+ int UE_id = find_nr_UE_id(module_idP, ra->rnti);
+ NR_UE_info_t *UE_info = &nr_mac->UE_info;
+ NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
+
+ long BWPSize = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+ long BWPStart = NRRIV2PRBOFFSET(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+
+ // HARQ management
+ AssertFatal(sched_ctrl->available_dl_harq.head >= 0,
+ "UE context not initialized: no HARQ processes found\n");
+ int current_harq_pid = sched_ctrl->available_dl_harq.head;
+ remove_front_nr_list(&sched_ctrl->available_dl_harq);
+ NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid];
+ DevAssert(!harq->is_waiting);
+ add_tail_nr_list(&sched_ctrl->feedback_dl_harq, current_harq_pid);
+ harq->is_waiting = true;
+ ra->harq_pid = current_harq_pid;
+
+ nr_acknack_scheduling(module_idP, UE_id, frameP, slotP);
+ harq->feedback_slot = sched_ctrl->sched_pucch->ul_slot;
+ harq->feedback_frame = sched_ctrl->sched_pucch->frame;
+
+ // Bytes to be transmitted
+ uint8_t *buf = (uint8_t *) harq->tb;
+ uint16_t mac_pdu_length = nr_write_ce_dlsch_pdu(module_idP, nr_mac->sched_ctrlCommon, buf, 255, ra->cont_res_id);
+ LOG_D(NR_MAC,"Encoded contention resolution mac_pdu_length %d\n",mac_pdu_length);
+ uint16_t mac_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, CCCH, ra->rnti, 1, &buf[mac_pdu_length+2]);
+ ((NR_MAC_SUBHEADER_SHORT *) &buf[mac_pdu_length])->R = 0;
+ ((NR_MAC_SUBHEADER_SHORT *) &buf[mac_pdu_length])->F = 0;
+ ((NR_MAC_SUBHEADER_SHORT *) &buf[mac_pdu_length])->LCID = DL_SCH_LCID_CCCH;
+ ((NR_MAC_SUBHEADER_SHORT *) &buf[mac_pdu_length])->L = mac_sdu_length;
+ mac_pdu_length = mac_pdu_length + mac_sdu_length + sizeof(NR_MAC_SUBHEADER_SHORT);
+
+ LOG_D(NR_MAC,"Encoded RRCSetup Piggyback (%d + 2 bytes), mac_pdu_length %d\n",mac_sdu_length,mac_pdu_length);
+
+ // Calculate number of symbols
+ int startSymbolIndex, nrOfSymbols;
+ const int startSymbolAndLength = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->
+ downlinkBWP_ToAddModList->list.array[ra->bwp_id-1]->bwp_Common->pdsch_ConfigCommon->choice.setup->
+ pdsch_TimeDomainAllocationList->list.array[time_domain_assignment]->startSymbolAndLength;
+ SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
+ AssertFatal(startSymbolIndex >= 0, "StartSymbolIndex is negative\n");
+
+ uint16_t dlDmrsSymbPos = fill_dmrs_mask(NULL,
+ nr_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position,
+ nrOfSymbols,
+ startSymbolIndex);
+
+ uint16_t N_DMRS_SLOT = get_num_dmrs(dlDmrsSymbPos);
+
+ long dmrsConfigType = bwp!=NULL ? (bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1) : 0;
+
+ nr_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData = 2;
+ if (nrOfSymbols == 2) {
+ nr_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData = 1;
+ }
+
+ AssertFatal(nr_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData == 1
+ || nr_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData == 2,
+ "nr_mac->schedCtrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData %d is not possible",
+ nr_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData);
+
+ uint8_t N_PRB_DMRS = 0;
+ if (dmrsConfigType==NFAPI_NR_DMRS_TYPE1) {
+ N_PRB_DMRS = nr_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData * 6;
+ }
+ else {
+ N_PRB_DMRS = nr_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData * 4;
+ }
+
+ uint8_t mcsTableIdx = 0;
+ if (bwp==NULL || bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table == NULL)
+ mcsTableIdx = 0;
+ else{
+ if (*bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table == 0)
+ mcsTableIdx = 1;
+ else
+ mcsTableIdx = 2;
+ }
+
+ int rbStart = 0;
+ int rbSize = 0;
+ uint8_t tb_scaling = 0;
+ uint16_t *vrb_map = cc[CC_id].vrb_map;
+ do {
+ rbSize++;
+ LOG_D(NR_MAC,"Calling nr_compute_tbs with N_PRB_DMRS %d, N_DMRS_SLOT %d\n",N_PRB_DMRS,N_DMRS_SLOT);
+ harq->tb_size = nr_compute_tbs(nr_get_Qm_dl(mcsIndex, mcsTableIdx),
+ nr_get_code_rate_dl(mcsIndex, mcsTableIdx),
+ rbSize, nrOfSymbols, N_PRB_DMRS * N_DMRS_SLOT, 0, tb_scaling,1) >> 3;
+ } while (rbStart + rbSize < BWPSize && !vrb_map[rbStart + rbSize] && harq->tb_size < mac_pdu_length);
+
+ for (int i = 0; (i < rbSize) && (rbStart <= (BWPSize - rbSize)); i++) {
+ if (vrb_map[rbStart + i]) {
+ rbStart += i;
+ i = 0;
+ }
+ }
+
+ if (rbStart > (BWPSize - rbSize)) {
+ LOG_E(NR_MAC, "%s(): cannot find free vrb_map for RNTI %04x!\n", __func__, ra->rnti);
+ return;
+ }
+
+ // Checking if the DCI allocation is feasible in current subframe
+ nfapi_nr_dl_tti_request_body_t *dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body;
+ if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) {
+ LOG_I(NR_MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, ra->rnti);
+ return;
+ }
+
+ uint8_t aggregation_level;
+ uint8_t nr_of_candidates;
+ find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss);
+ int CCEIndex = allocate_nr_CCEs(nr_mac, bwp, coreset, aggregation_level,0,0,nr_of_candidates);
+ if (CCEIndex < 0) {
+ LOG_E(NR_MAC, "%s(): cannot find free CCE for RA RNTI %04x!\n", __func__, ra->rnti);
+ return;
+ }
+
+ // look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not exist, create it. This is especially
+ // important if we have multiple RAs, and the DLSCH has to reuse them, so we need to mark them
+ const int coresetid = coreset->controlResourceSetId;
+ nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][ra->bwp_id][coresetid];
+ if (!pdcch_pdu_rel15) {
+ nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
+ memset(dl_tti_pdcch_pdu, 0, sizeof(nfapi_nr_dl_tti_request_pdu_t));
+ dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE;
+ dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2 + sizeof(nfapi_nr_dl_tti_pdcch_pdu));
+ dl_req->nPDUs += 1;
+ pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15;
+ nr_configure_pdcch(pdcch_pdu_rel15, ss, coreset, scc, bwp);
+ nr_mac->pdcch_pdu_idx[CC_id][ra->bwp_id][coresetid] = pdcch_pdu_rel15;
+ }
+
+ 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));
+ dl_tti_pdsch_pdu->PDUType = NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE;
+ dl_tti_pdsch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdsch_pdu));
+ dl_req->nPDUs+=1;
+ nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15;
+
+ LOG_I(NR_MAC,"[gNB %d] [RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg4 DCI, state %d\n", module_idP, CC_id, frameP, slotP, ra->state);
+
+ AssertFatal(ra->secondaryCellGroup, "no secondaryCellGroup for RNTI %04x\n", ra->rnti);
+
+ AssertFatal(ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
+ "downlinkBWP_ToAddModList has %d BWP!\n",
+ ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
+
+ // SCF222: PDU index incremented for each PDSCH PDU sent in TX control message. This is used to associate control
+ // information to data and is reset every slot.
+ const int pduindex = nr_mac->pdu_index[CC_id]++;
+
+ pdsch_pdu_rel15->pduBitmap = 0;
+ pdsch_pdu_rel15->rnti = ra->rnti;
+ pdsch_pdu_rel15->pduIndex = pduindex;
+ pdsch_pdu_rel15->BWPSize = BWPSize;
+ pdsch_pdu_rel15->BWPStart = BWPStart;
+ pdsch_pdu_rel15->SubcarrierSpacing = bwp!=NULL ? bwp->bwp_Common->genericParameters.subcarrierSpacing : scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing;
+ pdsch_pdu_rel15->CyclicPrefix = 0;
+ pdsch_pdu_rel15->NrOfCodewords = 1;
+ pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(mcsIndex,mcsTableIdx);
+ pdsch_pdu_rel15->qamModOrder[0] = 2;
+ pdsch_pdu_rel15->mcsIndex[0] = mcsIndex;
+ pdsch_pdu_rel15->mcsTable[0] = mcsTableIdx;
+ pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[harq->round];
+ pdsch_pdu_rel15->dataScramblingId = *scc->physCellId;
+ pdsch_pdu_rel15->nrOfLayers = 1;
+ pdsch_pdu_rel15->transmissionScheme = 0;
+ pdsch_pdu_rel15->refPoint = 0;
+ pdsch_pdu_rel15->dmrsConfigType = dmrsConfigType;
pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId;
pdsch_pdu_rel15->SCID = 0;
pdsch_pdu_rel15->numDmrsCdmGrpsNoData = 2;
@@ -997,23 +1323,13 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
pdsch_pdu_rel15->resourceAlloc = 1;
pdsch_pdu_rel15->rbStart = rbStart;
pdsch_pdu_rel15->rbSize = rbSize;
- pdsch_pdu_rel15->VRBtoPRBMapping = 0; // non interleaved
+ pdsch_pdu_rel15->VRBtoPRBMapping = 0;
+ pdsch_pdu_rel15->StartSymbolIndex = startSymbolIndex;
+ pdsch_pdu_rel15->NrOfSymbols = nrOfSymbols;
+ pdsch_pdu_rel15->dlDmrsSymbPos = dlDmrsSymbPos;
- for (int i=0; ibwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count; i++) {
- startSymbolAndLength = bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength;
- SLIV2SL(startSymbolAndLength, &StartSymbolIndex_tmp, &NrOfSymbols_tmp);
- if (NrOfSymbols_tmp < NrOfSymbols) {
- NrOfSymbols = NrOfSymbols_tmp;
- StartSymbolIndex = StartSymbolIndex_tmp;
- time_domain_assignment = i; // this is short PDSCH added to the config to fit mixed slot
- }
- }
-
- AssertFatal(StartSymbolIndex >= 0, "StartSymbolIndex is negative\n");
-
- pdsch_pdu_rel15->StartSymbolIndex = StartSymbolIndex;
- pdsch_pdu_rel15->NrOfSymbols = NrOfSymbols;
- pdsch_pdu_rel15->dlDmrsSymbPos = fill_dmrs_mask(NULL, scc->dmrs_TypeA_Position, NrOfSymbols);
+ int x_Overhead = 0;
+ nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead, pdsch_pdu_rel15->numDmrsCdmGrpsNoData, tb_scaling);
pdsch_pdu_rel15->precodingAndBeamforming.num_prgs=1;
pdsch_pdu_rel15->precodingAndBeamforming.prg_size=275;
@@ -1024,10 +1340,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
/* Fill PDCCH DL DCI PDU */
nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci];
pdcch_pdu_rel15->numDlDci++;
- dci_pdu->RNTI = RA_rnti;
- /* TODO: remove next line */
- AssertFatal(ss->searchSpaceType->present != NR_SearchSpace__searchSpaceType_PR_ue_Specific,
- "shouldn't the RA SS be common?\n");
+ dci_pdu->RNTI = ra->rnti;
dci_pdu->ScramblingId = *scc->physCellId;
dci_pdu->ScramblingRNTI = 0;
dci_pdu->AggregationLevel = aggregation_level;
@@ -1037,81 +1350,126 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
dci_pdu_rel15_t dci_payload;
dci_payload.frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pdsch_pdu_rel15->rbSize,
- pdsch_pdu_rel15->rbStart,dci10_bw);
+ pdsch_pdu_rel15->rbStart,
+ pdsch_pdu_rel15->BWPSize);
+
+ dci_payload.format_indicator = 1;
dci_payload.time_domain_assignment.val = time_domain_assignment;
dci_payload.vrb_to_prb_mapping.val = 0;
dci_payload.mcs = pdsch_pdu_rel15->mcsIndex[0];
- dci_payload.tb_scaling = 0;
+ dci_payload.tb_scaling = tb_scaling;
+ dci_payload.rv = pdsch_pdu_rel15->rvIndex[0];
+ dci_payload.harq_pid = current_harq_pid;
+ dci_payload.ndi = harq->ndi;
+ dci_payload.dai[0].val = (sched_ctrl->sched_pucch->dai_c-1)&3;
+ dci_payload.tpc = sched_ctrl->tpc1; // TPC for PUCCH: table 7.2.1-1 in 38.213
+ dci_payload.pucch_resource_indicator = sched_ctrl->sched_pucch->resource_indicator;
+ dci_payload.pdsch_to_harq_feedback_timing_indicator.val = sched_ctrl->sched_pucch->timing_indicator;
- LOG_I(MAC,
+ LOG_D(NR_MAC,
"[RAPROC] DCI type 1 payload: freq_alloc %d (%d,%d,%d), time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d \n",
dci_payload.frequency_domain_assignment.val,
pdsch_pdu_rel15->rbStart,
pdsch_pdu_rel15->rbSize,
- dci10_bw,
+ pdsch_pdu_rel15->BWPSize,
dci_payload.time_domain_assignment.val,
dci_payload.vrb_to_prb_mapping.val,
dci_payload.mcs,
dci_payload.tb_scaling);
- LOG_I(MAC, "Frame %d: Subframe %d : Adding common DL DCI for RA_RNTI %x\n", frameP, slotP, RA_rnti);
-
- const int dci_format = NR_DL_DCI_FORMAT_1_0;
- const int rnti_type = NR_RNTI_RA;
-
- LOG_I(MAC,
- "[RAPROC] DCI params: rnti %d, rnti_type %d, dci_format %d coreset params: FreqDomainResource %llx, start_symbol %d n_symb %d\n",
+ LOG_D(NR_MAC,
+ "[RAPROC] DCI params: rnti 0x%x, rnti_type %d, dci_format %d coreset params: FreqDomainResource %llx, start_symbol %d n_symb %d\n",
pdcch_pdu_rel15->dci_pdu[0].RNTI,
- rnti_type,
- dci_format,
+ NR_RNTI_TC,
+ NR_DL_DCI_FORMAT_1_0,
(unsigned long long)pdcch_pdu_rel15->FreqDomainResource,
pdcch_pdu_rel15->StartSymbolIndex,
pdcch_pdu_rel15->DurationSymbols);
fill_dci_pdu_rel15(scc,
- ra->secondaryCellGroup,
- dci_pdu,
+ nr_mac->secondaryCellGroupCommon,
+ &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci - 1],
&dci_payload,
- dci_format,
- rnti_type,
- dci10_bw,
+ NR_DL_DCI_FORMAT_1_0,
+ NR_RNTI_TC,
+ pdsch_pdu_rel15->BWPSize,
ra->bwp_id);
+ // Add padding header and zero rest out if there is space left
+ if (mac_pdu_length < harq->tb_size) {
+ NR_MAC_SUBHEADER_FIXED *padding = (NR_MAC_SUBHEADER_FIXED *) &buf[mac_pdu_length];
+ padding->R = 0;
+ padding->LCID = DL_SCH_LCID_PADDING;
+ for(int k = mac_pdu_length+1; ktb_size; k++) {
+ buf[k] = 0;
+ }
+ }
+
// DL TX request
nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs];
- tx_req->PDU_length = pdsch_pdu_rel15->TBSize[0];
+ memcpy(tx_req->TLVs[0].value.direct, harq->tb, sizeof(uint8_t) * harq->tb_size);
+ tx_req->PDU_length = harq->tb_size;
tx_req->PDU_index = pduindex;
tx_req->num_TLV = 1;
- tx_req->TLVs[0].length = 8;
+ tx_req->TLVs[0].length = harq->tb_size + 2;
nr_mac->TX_req[CC_id].SFN = frameP;
nr_mac->TX_req[CC_id].Number_of_PDUs++;
nr_mac->TX_req[CC_id].Slot = slotP;
- // Program UL processing for Msg3
- nr_get_Msg3alloc(module_idP, CC_id, scc, ubwp, slotP, frameP, ra, nr_mac->tdd_beam_association);
- LOG_I(MAC, "Frame %d, Slot %d: Setting Msg3 reception for Frame %d Slot %d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot);
- nr_add_msg3(module_idP, CC_id, frameP, slotP, ra, (uint8_t *) &tx_req->TLVs[0].value.direct[0]);
- ra->state = WAIT_Msg3;
- LOG_I(MAC,"[gNB %d][RAPROC] Frame %d, Slot %d: RA state %d\n", module_idP, frameP, slotP, ra->state);
+ // Mark the corresponding RBs as used
+ for (int rb = 0; rb < pdsch_pdu_rel15->rbSize; rb++) {
+ vrb_map[rb + pdsch_pdu_rel15->rbStart] = 1;
+ }
- x_Overhead = 0;
- nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead, pdsch_pdu_rel15->numDmrsCdmGrpsNoData, dci_payload.tb_scaling);
+ LOG_D(NR_MAC,"BWPSize: %i\n", pdcch_pdu_rel15->BWPSize);
+ LOG_D(NR_MAC,"BWPStart: %i\n", pdcch_pdu_rel15->BWPStart);
+ LOG_D(NR_MAC,"SubcarrierSpacing: %i\n", pdcch_pdu_rel15->SubcarrierSpacing);
+ LOG_D(NR_MAC,"CyclicPrefix: %i\n", pdcch_pdu_rel15->CyclicPrefix);
+ LOG_D(NR_MAC,"StartSymbolIndex: %i\n", pdcch_pdu_rel15->StartSymbolIndex);
+ LOG_D(NR_MAC,"DurationSymbols: %i\n", pdcch_pdu_rel15->DurationSymbols);
+ for(int n=0;n<6;n++) LOG_D(NR_MAC,"FreqDomainResource[%i]: %x\n",n, pdcch_pdu_rel15->FreqDomainResource[n]);
+ LOG_D(NR_MAC,"CceRegMappingType: %i\n", pdcch_pdu_rel15->CceRegMappingType);
+ LOG_D(NR_MAC,"RegBundleSize: %i\n", pdcch_pdu_rel15->RegBundleSize);
+ LOG_D(NR_MAC,"InterleaverSize: %i\n", pdcch_pdu_rel15->InterleaverSize);
+ LOG_D(NR_MAC,"CoreSetType: %i\n", pdcch_pdu_rel15->CoreSetType);
+ LOG_D(NR_MAC,"ShiftIndex: %i\n", pdcch_pdu_rel15->ShiftIndex);
+ LOG_D(NR_MAC,"precoderGranularity: %i\n", pdcch_pdu_rel15->precoderGranularity);
+ LOG_D(NR_MAC,"numDlDci: %i\n", pdcch_pdu_rel15->numDlDci);
- T(T_GNB_MAC_DL_RAR_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id),
- T_INT(RA_rnti), T_INT(frameP), T_INT(slotP), T_INT(0) /* harq pid, meaningful? */,
- T_BUFFER(&tx_req->TLVs[0].value.direct[0], tx_req->TLVs[0].length));
-
- /* mark the corresponding RBs as used */
- for (int rb = 0; rb < rbSize; rb++)
- vrb_map[rb + rbStart] = 1;
+ ra->state = WAIT_Msg4_ACK;
+ LOG_I(NR_MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: RA state %d\n", module_idP, frameP, slotP, ra->state);
}
}
-void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP){
-
- NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[0];
- LOG_D(MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Clear Random access information rnti %x\n", module_idP, CC_id, frameP, ra->rnti);
- ra->state = IDLE;
+void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t slot, NR_RA_t *ra) {
+
+ int UE_id = find_nr_UE_id(module_id, ra->rnti);
+ const int current_harq_pid = ra->harq_pid;
+
+ NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
+ NR_UE_harq_t *harq = &UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid];
+
+ LOG_D(NR_MAC, "ue %d, rnti %d, harq is waiting %d, round %d, frame %d %d, harq id %d\n", UE_id, ra->rnti, harq->is_waiting, harq->round, frame, slot, current_harq_pid);
+
+ if (harq->is_waiting == 0)
+ {
+ if (harq->round == 0)
+ {
+ LOG_I(NR_MAC, "(ue %i, rnti 0x%04x) Received Ack of RA-Msg4. CBRA procedure succeeded!\n", UE_id, ra->rnti);
+ nr_clear_ra_proc(module_id, CC_id, frame, ra);
+ UE_info->active[UE_id] = true;
+ }
+ else
+ {
+ ra->state = Msg4;
+ }
+ }
+
+}
+
+void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, NR_RA_t *ra){
+ LOG_D(NR_MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Clear Random access information rnti %x\n", module_idP, CC_id, frameP, ra->rnti);
+ ra->state = RA_IDLE;
ra->timing_offset = 0;
ra->RRC_timer = 20;
ra->rnti = 0;
@@ -1154,9 +1512,10 @@ void nr_fill_rar(uint8_t Mod_idP,
uint8_t * dlsch_buffer,
nfapi_nr_pusch_pdu_t *pusch_pdu){
- LOG_I(MAC, "[gNB] Generate RAR MAC PDU frame %d slot %d preamble index %u TA command %d \n", ra->Msg2_frame, ra-> Msg2_slot, ra->preamble_index, ra->timing_offset);
- NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) dlsch_buffer;
- NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 1);
+ LOG_I(NR_MAC, "[gNB] Generate RAR MAC PDU frame %d slot %d preamble index %u TA command %d \n", ra->Msg2_frame, ra-> Msg2_slot, ra->preamble_index, ra->timing_offset);
+ NR_RA_HEADER_BI *rarbi = (NR_RA_HEADER_BI *) dlsch_buffer;
+ NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) (dlsch_buffer + 1);
+ NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 2);
unsigned char csi_req = 0, tpc_command;
//uint8_t N_UL_Hop;
uint8_t valid_bits;
@@ -1165,6 +1524,16 @@ void nr_fill_rar(uint8_t Mod_idP,
tpc_command = 3; // this is 0 dB
+ /// E/T/R/R/BI subheader ///
+ // E = 1, MAC PDU includes another MAC sub-PDU (RAPID)
+ // T = 0, Back-off indicator subheader
+ // R = 2, Reserved
+ // BI = 0, 5ms
+ rarbi->E = 1;
+ rarbi->T = 0;
+ rarbi->R = 0;
+ rarbi->BI = 0;
+
/// E/T/RAPID subheader ///
// E = 0, one only RAR, first and last
// T = 1, RAPID
@@ -1211,4 +1580,50 @@ void nr_fill_rar(uint8_t Mod_idP,
rar->UL_GRANT_3 = (uint8_t) (ul_grant >> 8) & 0xff;
rar->UL_GRANT_4 = (uint8_t) ul_grant & 0xff;
+#ifdef DEBUG_RAR
+ //LOG_I(NR_MAC, "rarbi->E = 0x%x\n", rarbi->E);
+ //LOG_I(NR_MAC, "rarbi->T = 0x%x\n", rarbi->T);
+ //LOG_I(NR_MAC, "rarbi->R = 0x%x\n", rarbi->R);
+ //LOG_I(NR_MAC, "rarbi->BI = 0x%x\n", rarbi->BI);
+
+ LOG_I(NR_MAC, "rarh->E = 0x%x\n", rarh->E);
+ LOG_I(NR_MAC, "rarh->T = 0x%x\n", rarh->T);
+ LOG_I(NR_MAC, "rarh->RAPID = 0x%x (%i)\n", rarh->RAPID, rarh->RAPID);
+
+ LOG_I(NR_MAC, "rar->R = 0x%x\n", rar->R);
+ LOG_I(NR_MAC, "rar->TA1 = 0x%x\n", rar->TA1);
+
+ LOG_I(NR_MAC, "rar->TA2 = 0x%x\n", rar->TA2);
+ LOG_I(NR_MAC, "rar->UL_GRANT_1 = 0x%x\n", rar->UL_GRANT_1);
+
+ LOG_I(NR_MAC, "rar->UL_GRANT_2 = 0x%x\n", rar->UL_GRANT_2);
+ LOG_I(NR_MAC, "rar->UL_GRANT_3 = 0x%x\n", rar->UL_GRANT_3);
+ LOG_I(NR_MAC, "rar->UL_GRANT_4 = 0x%x\n", rar->UL_GRANT_4);
+
+ LOG_I(NR_MAC, "rar->TCRNTI_1 = 0x%x\n", rar->TCRNTI_1);
+ LOG_I(NR_MAC, "rar->TCRNTI_2 = 0x%x\n", rar->TCRNTI_2);
+#endif
+
+ int mcs = (unsigned char) (rar->UL_GRANT_4 >> 4);
+ // time alloc
+ int Msg3_t_alloc = (unsigned char) (rar->UL_GRANT_3 & 0x07);
+ // frequency alloc
+ int Msg3_f_alloc = (uint16_t) ((rar->UL_GRANT_3 >> 4) | (rar->UL_GRANT_2 << 4) | ((rar->UL_GRANT_1 & 0x03) << 12));
+ // frequency hopping
+ int freq_hopping = (unsigned char) (rar->UL_GRANT_1 >> 2);
+ // TA command
+ int ta_command = rar->TA2 + (rar->TA1 << 5);
+ // TC-RNTI
+ int t_crnti = rar->TCRNTI_2 + (rar->TCRNTI_1 << 8);
+
+ LOG_I(NR_MAC, "In %s: Transmitted RAR with t_alloc %d f_alloc %d ta_command %d mcs %d freq_hopping %d tpc_command %d csi_req %d t_crnti %x \n",
+ __FUNCTION__,
+ Msg3_t_alloc,
+ Msg3_f_alloc,
+ ta_command,
+ mcs,
+ freq_hopping,
+ tpc_command,
+ csi_req,
+ t_crnti);
}
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
index 444eabb789..3b120bc7d2 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
@@ -139,8 +139,8 @@ void schedule_ssb(frame_t frame, sub_frame_t slot,
}
-void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, uint8_t slots_per_frame, int nb_periods_per_frame){
-
+void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
+{
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc;
nfapi_nr_dl_tti_request_t *dl_tti_request;
@@ -153,13 +153,14 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP,
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
cc = &gNB->common_channels[CC_id];
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
+ const int slots_per_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
dl_tti_request = &gNB->DL_req[CC_id];
dl_req = &dl_tti_request->dl_tti_request_body;
// get MIB every 8 frames
if((slotP == 0) && (frameP & 7) == 0) {
- mib_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, MIBCH, 1, &cc->MIB_pdu.payload[0]);
+ mib_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, MIBCH, 0, 1, &cc->MIB_pdu.payload[0]);
LOG_D(MAC,
"[gNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes\n",
@@ -259,7 +260,10 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP,
if ((ssb_start_symbol/14) == rel_slot){
schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, ssbSubcarrierOffset, offset_pointa, (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1));
fill_ssb_vrb_map(cc, offset_pointa, ssb_start_symbol, CC_id);
- num_tdd_period = rel_slot/(slots_per_frame/nb_periods_per_frame);
+ const NR_TDD_UL_DL_Pattern_t *tdd = &scc->tdd_UL_DL_ConfigurationCommon->pattern1;
+ const int nr_mix_slots = tdd->nrofDownlinkSymbols != 0 || tdd->nrofUplinkSymbols != 0;
+ const int nr_slots_period = tdd->nrofDownlinkSlots + tdd->nrofUplinkSlots + nr_mix_slots;
+ num_tdd_period = rel_slot/nr_slots_period;
gNB->tdd_beam_association[num_tdd_period]=i_ssb;
num_ssb++;
AssertFatal(num_ssb<2,"beamforming currently not supported for more than one SSB per slot\n");
@@ -320,6 +324,7 @@ void schedule_control_sib1(module_id_t module_id,
uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map;
if (gNB_mac->sched_ctrlCommon == NULL){
+ LOG_D(NR_MAC,"schedule_control_common: Filling nr_mac->sched_ctrlCommon\n");
gNB_mac->sched_ctrlCommon = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon));
gNB_mac->sched_ctrlCommon->search_space = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->search_space));
gNB_mac->sched_ctrlCommon->coreset = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->coreset));
@@ -328,11 +333,10 @@ void schedule_control_sib1(module_id_t module_id,
fill_default_coresetZero(gNB_mac->sched_ctrlCommon->coreset,servingcellconfigcommon);
fill_default_initialDownlinkBWP(gNB_mac->sched_ctrlCommon->active_bwp,servingcellconfigcommon);
}
- gNB_mac->sched_ctrlCommon->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NULL;
- gNB_mac->sched_ctrlCommon->time_domain_allocation = time_domain_allocation;
- gNB_mac->sched_ctrlCommon->mcsTableIdx = mcsTableIdx;
- gNB_mac->sched_ctrlCommon->mcs = mcs;
+ gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation = time_domain_allocation;
+ gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx = mcsTableIdx;
+ gNB_mac->sched_ctrlCommon->sched_pdsch.mcs = mcs;
gNB_mac->sched_ctrlCommon->num_total_bytes = num_total_bytes;
uint8_t nr_of_candidates;
@@ -351,43 +355,48 @@ void schedule_control_sib1(module_id_t module_id,
const uint16_t bwpSize = type0_PDCCH_CSS_config->num_rbs;
int rbStart = type0_PDCCH_CSS_config->cset_start_rb;
- // Calculate number of symbols
- struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = gNB_mac->sched_ctrlCommon->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
- const int startSymbolAndLength = tdaList->list.array[gNB_mac->sched_ctrlCommon->time_domain_allocation]->startSymbolAndLength;
- int startSymbolIndex, nrOfSymbols;
- SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
+ 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];
+ }
if (nrOfSymbols == 2) {
- gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData = 1;
+ gNB_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData = 1;
} else {
- gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData = 2;
+ gNB_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData = 2;
}
// Calculate number of PRB_DMRS
- uint8_t N_PRB_DMRS = gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData * 6;
- uint16_t dlDmrsSymbPos = fill_dmrs_mask(gNB_mac->sched_ctrlCommon->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup, gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, startSymbolIndex+nrOfSymbols);
+ 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);
int rbSize = 0;
uint32_t TBS = 0;
do {
rbSize++;
- TBS = nr_compute_tbs(nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx),
- nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx),
+ 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),
rbSize, nrOfSymbols, N_PRB_DMRS * dmrs_length,0, 0,1) >> 3;
} while (rbStart + rbSize < bwpSize && !vrb_map[rbStart + rbSize] && TBS < gNB_mac->sched_ctrlCommon->num_total_bytes);
- gNB_mac->sched_ctrlCommon->rbSize = rbSize;
- gNB_mac->sched_ctrlCommon->rbStart = 0;
+ gNB_mac->sched_ctrlCommon->sched_pdsch.rbSize = rbSize;
+ gNB_mac->sched_ctrlCommon->sched_pdsch.rbStart = 0;
- LOG_D(MAC,"SLIV = %i\n", startSymbolAndLength);
LOG_D(MAC,"startSymbolIndex = %i\n", startSymbolIndex);
LOG_D(MAC,"nrOfSymbols = %i\n", nrOfSymbols);
- LOG_D(MAC,"rbSize = %i\n", gNB_mac->sched_ctrlCommon->rbSize);
+ LOG_D(MAC, "rbSize = %i\n", gNB_mac->sched_ctrlCommon->sched_pdsch.rbSize);
LOG_D(MAC,"TBS = %i\n", TBS);
// Mark the corresponding RBs as used
- for (int rb = 0; rb < gNB_mac->sched_ctrlCommon->rbSize; rb++) {
+ for (int rb = 0; rb < gNB_mac->sched_ctrlCommon->sched_pdsch.rbSize; rb++) {
vrb_map[rb + rbStart] = 1;
}
}
@@ -418,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));
@@ -445,31 +454,32 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
}
pdsch_pdu_rel15->NrOfCodewords = 1;
- pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->mcs,0);
+ pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->sched_pdsch.mcs, 0);
pdsch_pdu_rel15->qamModOrder[0] = 2;
- pdsch_pdu_rel15->mcsIndex[0] = gNB_mac->sched_ctrlCommon->mcs;
+ pdsch_pdu_rel15->mcsIndex[0] = gNB_mac->sched_ctrlCommon->sched_pdsch.mcs;
pdsch_pdu_rel15->mcsTable[0] = 0;
pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[0];
pdsch_pdu_rel15->dataScramblingId = *scc->physCellId;
pdsch_pdu_rel15->nrOfLayers = 1;
pdsch_pdu_rel15->transmissionScheme = 0;
pdsch_pdu_rel15->refPoint = 1;
- pdsch_pdu_rel15->dmrsConfigType = gNB_mac->sched_ctrlCommon->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1;
+ pdsch_pdu_rel15->dmrsConfigType = 0;
pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId;
pdsch_pdu_rel15->SCID = 0;
- pdsch_pdu_rel15->numDmrsCdmGrpsNoData = gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData;
+ pdsch_pdu_rel15->numDmrsCdmGrpsNoData = gNB_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData;
pdsch_pdu_rel15->dmrsPorts = 1;
pdsch_pdu_rel15->resourceAlloc = 1;
- pdsch_pdu_rel15->rbStart = gNB_mac->sched_ctrlCommon->rbStart;
- pdsch_pdu_rel15->rbSize = gNB_mac->sched_ctrlCommon->rbSize;
+ pdsch_pdu_rel15->rbStart = gNB_mac->sched_ctrlCommon->sched_pdsch.rbStart;
+ pdsch_pdu_rel15->rbSize = gNB_mac->sched_ctrlCommon->sched_pdsch.rbSize;
pdsch_pdu_rel15->VRBtoPRBMapping = 0;
- pdsch_pdu_rel15->qamModOrder[0] = nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx);
+ pdsch_pdu_rel15->qamModOrder[0] = nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->sched_pdsch.mcs,
+ gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx);
pdsch_pdu_rel15->TBSize[0] = TBS;
- pdsch_pdu_rel15->mcsTable[0] = gNB_mac->sched_ctrlCommon->mcsTableIdx;
+ pdsch_pdu_rel15->mcsTable[0] = gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx;
pdsch_pdu_rel15->StartSymbolIndex = StartSymbolIndex;
pdsch_pdu_rel15->NrOfSymbols = NrOfSymbols;
- pdsch_pdu_rel15->dlDmrsSymbPos = fill_dmrs_mask(bwp->bwp_Dedicated->pdsch_Config->choice.setup, scc->dmrs_TypeA_Position, pdsch_pdu_rel15->StartSymbolIndex+pdsch_pdu_rel15->NrOfSymbols);
+ pdsch_pdu_rel15->dlDmrsSymbPos = fill_dmrs_mask(NULL, scc->dmrs_TypeA_Position, pdsch_pdu_rel15->NrOfSymbols, pdsch_pdu_rel15->StartSymbolIndex);
LOG_D(MAC,"dlDmrsSymbPos = 0x%x\n", pdsch_pdu_rel15->dlDmrsSymbPos);
@@ -494,8 +504,8 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
dci_payload.frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(
pdsch_pdu_rel15->rbSize, pdsch_pdu_rel15->rbStart, type0_PDCCH_CSS_config->num_rbs);
- dci_payload.time_domain_assignment.val = gNB_mac->sched_ctrlCommon->time_domain_allocation;
- dci_payload.mcs = gNB_mac->sched_ctrlCommon->mcs;
+ dci_payload.time_domain_assignment.val = gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation;
+ dci_payload.mcs = gNB_mac->sched_ctrlCommon->sched_pdsch.mcs;
dci_payload.rv = pdsch_pdu_rel15->rvIndex[0];
dci_payload.harq_pid = 0;
dci_payload.ndi = 0;
@@ -537,8 +547,6 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) {
- LOG_D(MAC,"Schedule_nr_sib1: frameP = %i, slotP = %i\n", frameP, slotP);
-
// TODO: Get these values from RRC
const int CC_id = 0;
int time_domain_allocation = 0;
@@ -574,33 +582,37 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
(type0_PDCCH_CSS_config->num_rbs > 0) &&
(type0_PDCCH_CSS_config->active == true)) {
- LOG_D(MAC,"> SIB1 transmission\n");
+ LOG_D(NR_MAC,"(%d.%d) SIB1 transmission: ssb_index %d\n", frameP, slotP, type0_PDCCH_CSS_config->ssb_index);
// Get SIB1
uint8_t sib1_payload[NR_MAX_SIB_LENGTH/8];
- uint8_t sib1_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, BCCH, 1, sib1_payload);
- LOG_D(MAC,"sib1_sdu_length = %i\n", sib1_sdu_length);
- LOG_D(MAC,"SIB1: \n");
- for (int i=0;isched_ctrlCommon->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
- const int startSymbolAndLength = tdaList->list.array[gNB_mac->sched_ctrlCommon->time_domain_allocation]->startSymbolAndLength;
- SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
+ 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->numDmrsCdmGrpsNoData * 6;
- uint16_t dlDmrsSymbPos = fill_dmrs_mask(gNB_mac->sched_ctrlCommon->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup,
- gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, startSymbolIndex+nrOfSymbols);
+ 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->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx),
- nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx),
- gNB_mac->sched_ctrlCommon->rbSize, nrOfSymbols, N_PRB_DMRS * dmrs_length,0 ,0 ,1 ) >> 3;
+ 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),
+ gNB_mac->sched_ctrlCommon->sched_pdsch.rbSize, nrOfSymbols, N_PRB_DMRS * dmrs_length,0 ,0 ,1 ) >> 3;
nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body;
nr_fill_nfapi_dl_sib1_pdu(module_idP, dl_req, type0_PDCCH_CSS_config, TBS, startSymbolIndex, nrOfSymbols);
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
index 30a89cce77..e17fb5e346 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
@@ -56,6 +56,82 @@
#define WORD 32
//#define SIZE_OF_POINTER sizeof (void *)
+void calculate_preferred_dl_tda(module_id_t module_id, const NR_BWP_Downlink_t *bwp)
+{
+ gNB_MAC_INST *nrmac = RC.nrmac[module_id];
+ const int bwp_id = bwp->bwp_Id;
+ if (nrmac->preferred_dl_tda[bwp_id])
+ return;
+
+ /* there is a mixed slot only when in TDD */
+ NR_ServingCellConfigCommon_t *scc = nrmac->common_channels->ServingCellConfigCommon;
+ const NR_TDD_UL_DL_Pattern_t *tdd =
+ scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
+ const int symb_dlMixed = tdd ? (1 << tdd->nrofDownlinkSymbols) - 1 : 0;
+
+ const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
+ const NR_SearchSpace_t *search_space = get_searchspace(bwp, target_ss);
+ const NR_ControlResourceSet_t *coreset = get_coreset(bwp, search_space, 1 /* dedicated */);
+ // get coreset symbol "map"
+ const uint16_t symb_coreset = (1 << coreset->duration) - 1;
+
+ /* check that TDA index 0 fits into DL and does not overlap CORESET */
+ const struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList =
+ bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
+ AssertFatal(tdaList->list.count >= 1, "need to have at least one TDA for DL slots\n");
+ const NR_PDSCH_TimeDomainResourceAllocation_t *tdaP_DL = tdaList->list.array[0];
+ AssertFatal(!tdaP_DL->k0 || *tdaP_DL->k0 == 0,
+ "TimeDomainAllocation at index 1: non-null k0 (%ld) is not supported by the scheduler\n",
+ *tdaP_DL->k0);
+ int start, len;
+ SLIV2SL(tdaP_DL->startSymbolAndLength, &start, &len);
+ const uint16_t symb_tda = ((1 << len) - 1) << start;
+ // check whether coreset and TDA overlap: then we cannot use it. Note that
+ // here we assume that the coreset is scheduled every slot (which it
+ // currently is) and starting at symbol 0
+ AssertFatal((symb_coreset & symb_tda) == 0, "TDA index 0 for DL overlaps with CORESET\n");
+
+ /* check that TDA index 1 fits into DL part of mixed slot, if it exists */
+ int tdaMi = -1;
+ if (tdaList->list.count > 1) {
+ const NR_PDSCH_TimeDomainResourceAllocation_t *tdaP_Mi = tdaList->list.array[1];
+ AssertFatal(!tdaP_Mi->k0 || *tdaP_Mi->k0 == 0,
+ "TimeDomainAllocation at index 1: non-null k0 (%ld) is not supported by the scheduler\n",
+ *tdaP_Mi->k0);
+ int start, len;
+ SLIV2SL(tdaP_Mi->startSymbolAndLength, &start, &len);
+ const uint16_t symb_tda = ((1 << len) - 1) << start;
+ // check whether coreset and TDA overlap: then, we cannot use it. Also,
+ // check whether TDA is entirely within mixed slot DL. Note that
+ // here we assume that the coreset is scheduled every slot (which it
+ // currently is)
+ if ((symb_coreset & symb_tda) == 0 && (symb_dlMixed & symb_tda) == symb_tda) {
+ tdaMi = 1;
+ } else {
+ LOG_E(MAC,
+ "TDA index 1 DL overlaps with CORESET or is not entirely in mixed slot (symb_coreset %x symb_dlMixed %x symb_tda %x), won't schedule DL mixed slot\n",
+ symb_coreset,
+ symb_dlMixed,
+ symb_tda);
+ }
+ }
+
+ const uint8_t slots_per_frame[5] = {10, 20, 40, 80, 160};
+ const int n = slots_per_frame[*scc->ssbSubcarrierSpacing];
+ nrmac->preferred_dl_tda[bwp_id] = malloc(n * sizeof(*nrmac->preferred_dl_tda[bwp_id]));
+
+ const int nr_mix_slots = tdd ? tdd->nrofDownlinkSymbols != 0 || tdd->nrofUplinkSymbols != 0 : 0;
+ const int nr_slots_period = tdd ? tdd->nrofDownlinkSlots + tdd->nrofUplinkSlots + nr_mix_slots : n;
+ for (int i = 0; i < n; ++i) {
+ nrmac->preferred_dl_tda[bwp_id][i] = -1;
+ if (!tdd || i % nr_slots_period < tdd->nrofDownlinkSlots)
+ nrmac->preferred_dl_tda[bwp_id][i] = 0;
+ else if (tdd && nr_mix_slots && i % nr_slots_period == tdd->nrofDownlinkSlots)
+ nrmac->preferred_dl_tda[bwp_id][i] = tdaMi;
+ LOG_I(MAC, "slot %d preferred_dl_tda %d\n", i, nrmac->preferred_dl_tda[bwp_id][i]);
+ }
+}
+
// Compute and write all MAC CEs and subheaders, and return number of written
// bytes
int nr_write_ce_dlsch_pdu(module_id_t module_idP,
@@ -302,35 +378,6 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
return offset;
}
-int getNrOfSymbols(NR_BWP_Downlink_t *bwp, int tda) {
- struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList =
- bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
- AssertFatal(tda < tdaList->list.count,
- "time_domain_allocation %d>=%d\n",
- tda,
- tdaList->list.count);
-
- const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength;
- int startSymbolIndex, nrOfSymbols;
- SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
- return nrOfSymbols;
-}
-
-nfapi_nr_dmrs_type_e getDmrsConfigType(NR_BWP_Downlink_t *bwp) {
- return bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1;
-}
-
-uint8_t getN_PRB_DMRS(NR_BWP_Downlink_t *bwp, int numDmrsCdmGrpsNoData) {
- const nfapi_nr_dmrs_type_e dmrsConfigType = getDmrsConfigType(bwp);
- if (dmrsConfigType == NFAPI_NR_DMRS_TYPE1) {
- // if no data in dmrs cdm group is 1 only even REs have no data
- // if no data in dmrs cdm group is 2 both odd and even REs have no data
- return numDmrsCdmGrpsNoData * 6;
- } else {
- return numDmrsCdmGrpsNoData * 4;
- }
-}
-
void nr_store_dlsch_buffer(module_id_t module_id,
frame_t frame,
sub_frame_t slot) {
@@ -365,61 +412,125 @@ void nr_store_dlsch_buffer(module_id_t module_id,
}
}
-bool allocate_retransmission(module_id_t module_id,
- uint8_t *rballoc_mask,
- int *n_rb_sched,
- int UE_id,
- int current_harq_pid){
- NR_UE_sched_ctrl_t *sched_ctrl = &RC.nrmac[module_id]->UE_info.UE_sched_ctrl[UE_id];
- NR_UE_ret_info_t *retInfo = &sched_ctrl->retInfo[current_harq_pid];
+bool allocate_dl_retransmission(module_id_t module_id,
+ frame_t frame,
+ sub_frame_t slot,
+ uint8_t *rballoc_mask,
+ int *n_rb_sched,
+ int UE_id,
+ int current_harq_pid)
+{
+ const NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels->ServingCellConfigCommon;
+ NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
+ NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
+ NR_sched_pdsch_t *retInfo = &sched_ctrl->harq_processes[current_harq_pid].sched_pdsch;
const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
int rbStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+ const uint8_t num_dmrs_cdm_grps_no_data = 1;
- sched_ctrl->time_domain_allocation = retInfo->time_domain_allocation;
-
- /* ensure that there is a free place for RB allocation */
int rbSize = 0;
- while (rbSize < retInfo->rbSize) {
- rbStart += rbSize; /* last iteration rbSize was not enough, skip it */
- rbSize = 0;
- while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++;
- if (rbStart >= bwpSize) {
- LOG_D(MAC,
- "cannot allocate retransmission for UE %d/RNTI %04x: no resources\n",
- UE_id,
- RC.nrmac[module_id]->UE_info.rnti[UE_id]);
- return false;
+ const int tda = RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_bwp->bwp_Id][slot];
+ if (tda == retInfo->time_domain_allocation) {
+ /* Check that there are enough resources for retransmission */
+ while (rbSize < retInfo->rbSize) {
+ rbStart += rbSize; /* last iteration rbSize was not enough, skip it */
+ rbSize = 0;
+ while (rbStart < bwpSize && !rballoc_mask[rbStart])
+ rbStart++;
+ if (rbStart >= bwpSize) {
+ LOG_D(MAC, "cannot allocate retransmission for UE %d/RNTI %04x: no resources\n", UE_id, UE_info->rnti[UE_id]);
+ return false;
+ }
+ while (rbStart + rbSize < bwpSize && rballoc_mask[rbStart + rbSize] && rbSize < retInfo->rbSize)
+ rbSize++;
}
- while (rbStart + rbSize < bwpSize
- && rballoc_mask[rbStart + rbSize]
- && rbSize < retInfo->rbSize)
+ /* check whether we need to switch the TDA allocation since the last
+ * (re-)transmission */
+ NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
+ if (ps->time_domain_allocation != tda || ps->numDmrsCdmGrpsNoData != num_dmrs_cdm_grps_no_data)
+ nr_set_pdsch_semi_static(
+ scc, UE_info->secondaryCellGroup[UE_id], sched_ctrl->active_bwp, tda, num_dmrs_cdm_grps_no_data, ps);
+ } else {
+ /* the retransmission will use a different time domain allocation, check
+ * that we have enough resources */
+ while (rbStart < bwpSize && !rballoc_mask[rbStart])
+ rbStart++;
+ while (rbStart + rbSize < bwpSize && rballoc_mask[rbStart + rbSize])
rbSize++;
+ NR_pdsch_semi_static_t temp_ps;
+ nr_set_pdsch_semi_static(
+ scc, UE_info->secondaryCellGroup[UE_id], sched_ctrl->active_bwp, tda, num_dmrs_cdm_grps_no_data, &temp_ps);
+ uint32_t new_tbs;
+ uint16_t new_rbSize;
+ bool success = nr_find_nb_rb(retInfo->Qm,
+ retInfo->R,
+ temp_ps.nrOfSymbols,
+ temp_ps.N_PRB_DMRS * temp_ps.N_DMRS_SLOT,
+ retInfo->tb_size,
+ rbSize,
+ &new_tbs,
+ &new_rbSize);
+ if (!success || new_tbs != retInfo->tb_size) {
+ LOG_D(MAC, "%s(): new TBsize %d of new TDA does not match old TBS %d\n", __func__, new_tbs, retInfo->tb_size);
+ return false; /* the maximum TBsize we might have is smaller than what we need */
+ }
+ /* we can allocate it. Overwrite the time_domain_allocation, the number
+ * of RBs, and the new TB size. The rest is done below */
+ retInfo->tb_size = new_tbs;
+ retInfo->rbSize = new_rbSize;
+ retInfo->time_domain_allocation = tda;
+ sched_ctrl->pdsch_semi_static = temp_ps;
}
- sched_ctrl->rbSize = retInfo->rbSize;
- sched_ctrl->rbStart = rbStart;
- /* MCS etc: just reuse from previous scheduling opportunity */
- sched_ctrl->mcsTableIdx = retInfo->mcsTableIdx;
- sched_ctrl->mcs = retInfo->mcs;
- sched_ctrl->numDmrsCdmGrpsNoData = retInfo->numDmrsCdmGrpsNoData;
+ /* Find a free CCE */
+ bool freeCCE = find_free_CCE(module_id, slot, UE_id);
+ if (!freeCCE) {
+ LOG_D(MAC, "%4d.%2d could not find CCE for DL DCI retransmission UE %d/RNTI %04x\n",
+ frame, slot, UE_id, UE_info->rnti[UE_id]);
+ return false;
+ }
+
+ /* Find PUCCH occasion: if it fails, undo CCE allocation (undoing PUCCH
+ * allocation after CCE alloc fail would be more complex) */
+ const bool alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot);
+ if (!alloc) {
+ LOG_D(MAC,
+ "%s(): could not find PUCCH for UE %d/%04x@%d.%d\n",
+ __func__,
+ UE_id,
+ UE_info->rnti[UE_id],
+ frame,
+ slot);
+ int cid = sched_ctrl->coreset->controlResourceSetId;
+ UE_info->num_pdcch_cand[UE_id][cid]--;
+ int *cce_list = RC.nrmac[module_id]->cce_list[sched_ctrl->active_bwp->bwp_Id][cid];
+ for (int i = 0; i < sched_ctrl->aggregation_level; i++)
+ cce_list[sched_ctrl->cce_index + i] = 0;
+ return false;
+ }
+
+ /* just reuse from previous scheduling opportunity, set new start RB */
+ sched_ctrl->sched_pdsch = *retInfo;
+ sched_ctrl->sched_pdsch.rbStart = rbStart;
/* retransmissions: directly allocate */
- *n_rb_sched -= sched_ctrl->rbSize;
- for (int rb = 0; rb < sched_ctrl->rbSize; rb++)
- rballoc_mask[rb+sched_ctrl->rbStart] = 0;
+ *n_rb_sched -= sched_ctrl->sched_pdsch.rbSize;
+ for (int rb = 0; rb < sched_ctrl->sched_pdsch.rbSize; rb++)
+ rballoc_mask[rb + sched_ctrl->sched_pdsch.rbStart] = 0;
return true;
}
float thr_ue[MAX_MOBILES_PER_GNB];
+uint32_t pf_tbs[3][28]; // pre-computed, approximate TBS values for PF coefficient
void pf_dl(module_id_t module_id,
frame_t frame,
sub_frame_t slot,
NR_list_t *UE_list,
+ int max_num_ue,
int n_rb_sched,
- uint8_t *rballoc_mask,
- int max_num_ue) {
-
+ uint8_t *rballoc_mask) {
+ const NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels->ServingCellConfigCommon;
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
float coeff_ue[MAX_MOBILES_PER_GNB];
// UEs that could be scheduled
@@ -429,11 +540,10 @@ void pf_dl(module_id_t module_id,
/* Loop UE_info->list to check retransmission */
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];
- sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, NR_SearchSpace__searchSpaceType_PR_ue_Specific);
- sched_ctrl->coreset = get_coreset(sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */);
+ NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
+ NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
/* get the PID of a HARQ process awaiting retrnasmission, or -1 otherwise */
- sched_ctrl->dl_harq_pid = sched_ctrl->retrans_dl_harq.head;
- const rnti_t rnti = UE_info->rnti[UE_id];
+ sched_pdsch->dl_harq_pid = sched_ctrl->retrans_dl_harq.head;
/* Calculate Throughput */
const float a = 0.0005f; // corresponds to 200ms window
@@ -441,33 +551,10 @@ void pf_dl(module_id_t module_id,
thr_ue[UE_id] = (1 - a) * thr_ue[UE_id] + a * b;
/* retransmission */
- if (sched_ctrl->dl_harq_pid >= 0) {
- /* Find a free CCE */
- bool freeCCE = find_free_CCE(module_id, slot, UE_id);
- if (!freeCCE){
- LOG_D(MAC, "%4d.%2d could not find CCE for DL DCI retransmission UE %d/RNTI %04x\n", frame, slot, UE_id, rnti);
- continue;
- }
- /* Find PUCCH occasion: if it fails, undo CCE allocation (undoing PUCCH
- * allocation after CCE alloc fail would be more complex) */
- const bool alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot);
- if (!alloc) {
- LOG_W(MAC,
- "%s(): could not find PUCCH for UE %d/%04x@%d.%d\n",
- __func__,
- UE_id,
- rnti,
- frame,
- slot);
- int cid = sched_ctrl->coreset->controlResourceSetId;
- UE_info->num_pdcch_cand[UE_id][cid]--;
- int *cce_list = RC.nrmac[module_id]->cce_list[sched_ctrl->active_bwp->bwp_Id][cid];
- for (int i = 0; i < sched_ctrl->aggregation_level; i++)
- cce_list[sched_ctrl->cce_index + i] = 0;
- return;
- }
+ if (sched_pdsch->dl_harq_pid >= 0) {
/* Allocate retransmission */
- bool r = allocate_retransmission(module_id, rballoc_mask, &n_rb_sched, UE_id, sched_ctrl->dl_harq_pid);
+ bool r = allocate_dl_retransmission(
+ module_id, frame, slot, rballoc_mask, &n_rb_sched, UE_id, sched_pdsch->dl_harq_pid);
if (!r) {
LOG_D(MAC, "%4d.%2d retransmission can NOT be allocated\n", frame, slot);
continue;
@@ -481,23 +568,8 @@ void pf_dl(module_id_t module_id,
continue;
/* Calculate coeff */
- sched_ctrl->time_domain_allocation = 2;
- sched_ctrl->mcsTableIdx = 0;
- sched_ctrl->mcs = 9;
- sched_ctrl->numDmrsCdmGrpsNoData = 1;
- uint8_t N_PRB_DMRS =
- getN_PRB_DMRS(sched_ctrl->active_bwp, sched_ctrl->numDmrsCdmGrpsNoData);
- int nrOfSymbols = getNrOfSymbols(sched_ctrl->active_bwp,
- sched_ctrl->time_domain_allocation);
- uint32_t tbs = nr_compute_tbs(nr_get_Qm_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx),
- nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx),
- 1, // rbSize
- nrOfSymbols,
- N_PRB_DMRS, // FIXME // This should be multiplied by the
- // number of dmrs symbols
- 0 /* N_PRB_oh, 0 for initialBWP */, 0 /* tb_scaling */,
- 1 /* nrOfLayers */)
- >> 3;
+ sched_pdsch->mcs = 9;
+ uint32_t tbs = pf_tbs[ps->mcsTableIdx][sched_pdsch->mcs];
coeff_ue[UE_id] = (float) tbs / thr_ue[UE_id];
LOG_D(MAC,"b %d, thr_ue[%d] %f, tbs %d, coeff_ue[%d] %f\n",
b, UE_id, thr_ue[UE_id], tbs, UE_id, coeff_ue[UE_id]);
@@ -545,7 +617,7 @@ void pf_dl(module_id_t module_id,
* allocation after CCE alloc fail would be more complex) */
const bool alloc = nr_acknack_scheduling(module_id, UE_id, frame, slot);
if (!alloc) {
- LOG_W(MAC,
+ LOG_D(MAC,
"%s(): could not find PUCCH for UE %d/%04x@%d.%d\n",
__func__,
UE_id,
@@ -560,57 +632,48 @@ void pf_dl(module_id_t module_id,
return;
}
- /* Allocate transmission */
- // Time-domain allocation
- sched_ctrl->time_domain_allocation = 2;
-
- // modulation scheme
- sched_ctrl->mcsTableIdx = 0;
- sched_ctrl->mcs = 9;
- sched_ctrl->numDmrsCdmGrpsNoData = 1;
-
// Freq-demain allocation
while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++;
+ uint16_t max_rbSize = 1;
+ while (rbStart + max_rbSize < bwpSize && rballoc_mask[rbStart + max_rbSize])
+ max_rbSize++;
- const uint8_t N_PRB_DMRS =
- getN_PRB_DMRS(sched_ctrl->active_bwp, sched_ctrl->numDmrsCdmGrpsNoData);
- const int nrOfSymbols = getNrOfSymbols(sched_ctrl->active_bwp,
- sched_ctrl->time_domain_allocation);
- const NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels->ServingCellConfigCommon;
- const uint8_t N_DMRS_SLOT = get_num_dmrs_symbols(
- sched_ctrl->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup,
- scc->dmrs_TypeA_Position,
- nrOfSymbols);
+ /* MCS has been set above */
+ const uint8_t num_dmrs_cdm_grps_no_data = 1;
+ const int tda = RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_bwp->bwp_Id][slot];
+ NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
+ NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
+ if (ps->time_domain_allocation != tda || ps->numDmrsCdmGrpsNoData != num_dmrs_cdm_grps_no_data)
+ nr_set_pdsch_semi_static(
+ scc, UE_info->secondaryCellGroup[UE_id], sched_ctrl->active_bwp, tda, num_dmrs_cdm_grps_no_data, ps);
+ sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx);
+ sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx);
- int rbSize = 0;
uint32_t TBS = 0;
+ uint16_t rbSize;
const int oh = 2 + (sched_ctrl->num_total_bytes >= 256)
+ 2 * (frame == (sched_ctrl->ta_frame + 10) % 1024);
- do {
- rbSize++;
- TBS = nr_compute_tbs(nr_get_Qm_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx),
- nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx),
- rbSize,
- nrOfSymbols,
- N_PRB_DMRS * N_DMRS_SLOT,
- 0 /* N_PRB_oh, 0 for initialBWP */,
- 0 /* tb_scaling */,
- 1 /* nrOfLayers */)
- >> 3;
- } while (rbStart + rbSize < bwpSize && rballoc_mask[rbStart + rbSize] && TBS < sched_ctrl->num_total_bytes + oh);
- sched_ctrl->rbSize = rbSize;
- sched_ctrl->rbStart = rbStart;
+ nr_find_nb_rb(sched_pdsch->Qm,
+ sched_pdsch->R,
+ ps->nrOfSymbols,
+ ps->N_PRB_DMRS * ps->N_DMRS_SLOT,
+ sched_ctrl->num_total_bytes + oh,
+ max_rbSize,
+ &TBS,
+ &rbSize);
+ sched_pdsch->rbSize = rbSize;
+ sched_pdsch->rbStart = rbStart;
+ sched_pdsch->tb_size = TBS;
/* transmissions: directly allocate */
- n_rb_sched -= sched_ctrl->rbSize;
- for (int rb = 0; rb < sched_ctrl->rbSize; rb++)
- rballoc_mask[rb+sched_ctrl->rbStart] = 0;
+ n_rb_sched -= sched_pdsch->rbSize;
+ for (int rb = 0; rb < sched_pdsch->rbSize; rb++)
+ rballoc_mask[rb + sched_pdsch->rbStart] = 0;
}
}
-void nr_simple_dlsch_preprocessor(module_id_t module_id,
- frame_t frame,
- sub_frame_t slot) {
+void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t slot)
+{
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
if (UE_info->num_UEs == 0)
@@ -622,6 +685,11 @@ void nr_simple_dlsch_preprocessor(module_id_t module_id,
/* Get bwpSize from the first UE */
int UE_id = UE_info->list.head;
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
+
+ const int tda = RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_bwp->bwp_Id][slot];
+ if (tda < 0)
+ return;
+
const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map;
@@ -642,15 +710,45 @@ void nr_simple_dlsch_preprocessor(module_id_t module_id,
frame,
slot,
&UE_info->list,
+ 2,
n_rb_sched,
- rballoc_mask,
- 2);
+ rballoc_mask);
+}
+
+nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(module_id_t module_id, int CC_id)
+{
+ /* in the PF algorithm, we have to use the TBsize to compute the coefficient.
+ * This would include the number of DMRS symbols, which in turn depends on
+ * the time domain allocation. In case we are in a mixed slot, we do not want
+ * to recalculate all these values just, and therefore we provide a look-up
+ * table which should approximately give us the TBsize */
+ for (int mcsTableIdx = 0; mcsTableIdx < 3; ++mcsTableIdx) {
+ for (int mcs = 0; mcs < 29; ++mcs) {
+ if (mcs > 27 && mcsTableIdx == 1)
+ continue;
+ const uint8_t Qm = nr_get_Qm_dl(mcs, mcsTableIdx);
+ const uint16_t R = nr_get_code_rate_dl(mcs, mcsTableIdx);
+ pf_tbs[mcsTableIdx][mcs] = nr_compute_tbs(Qm,
+ R,
+ 1, /* rbSize */
+ 10, /* hypothetical number of slots */
+ 0, /* N_PRB_DMRS * N_DMRS_SLOT */
+ 0 /* N_PRB_oh, 0 for initialBWP */,
+ 0 /* tb_scaling */,
+ 1 /* nrOfLayers */)
+ >> 3;
+ }
+ }
+
+ return nr_fr1_dlsch_preprocessor;
}
void nr_schedule_ue_spec(module_id_t module_id,
frame_t frame,
sub_frame_t slot) {
gNB_MAC_INST *gNB_mac = RC.nrmac[module_id];
+ if (!is_xlsch_in_slot(gNB_mac->dlsch_slot_bitmap[slot / 64], slot))
+ return;
/* PREPROCESSOR */
gNB_mac->pre_processor_dl(module_id, frame, slot);
@@ -664,6 +762,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
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_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
UE_info->mac_stats[UE_id].dlsch_current_bytes = 0;
/* update TA and set ta_apply every 10 frames.
@@ -675,45 +774,23 @@ void nr_schedule_ue_spec(module_id_t module_id,
LOG_D(MAC, "[UE %d][%d.%d] UL timing alignment procedures: setting flag for Timing Advance command\n", UE_id, frame, slot);
}
- if (sched_ctrl->rbSize <= 0)
+ if (sched_pdsch->rbSize <= 0)
continue;
const rnti_t rnti = UE_info->rnti[UE_id];
/* POST processing */
- struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList =
- sched_ctrl->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
- AssertFatal(sched_ctrl->time_domain_allocation < tdaList->list.count,
- "time_domain_allocation %d>=%d\n",
- sched_ctrl->time_domain_allocation,
- tdaList->list.count);
-
- const int startSymbolAndLength =
- tdaList->list.array[sched_ctrl->time_domain_allocation]->startSymbolAndLength;
- int startSymbolIndex, nrOfSymbols;
- SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
-
- uint8_t N_PRB_DMRS =
- getN_PRB_DMRS(sched_ctrl->active_bwp, sched_ctrl->numDmrsCdmGrpsNoData);
- uint8_t N_DMRS_SLOT = get_num_dmrs_symbols(sched_ctrl->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup,
- RC.nrmac[module_id]->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position ,
- nrOfSymbols);
- const nfapi_nr_dmrs_type_e dmrsConfigType = getDmrsConfigType(sched_ctrl->active_bwp);
const int nrOfLayers = 1;
- const uint16_t R = nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx);
- const uint8_t Qm = nr_get_Qm_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx);
- const uint32_t TBS =
- nr_compute_tbs(nr_get_Qm_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx),
- nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx),
- sched_ctrl->rbSize,
- nrOfSymbols,
- N_PRB_DMRS * N_DMRS_SLOT,
- 0 /* N_PRB_oh, 0 for initialBWP */,
- 0 /* tb_scaling */,
- nrOfLayers)
- >> 3;
+ const uint16_t R = sched_pdsch->R;
+ const uint8_t Qm = sched_pdsch->Qm;
+ const uint32_t TBS = sched_pdsch->tb_size;
- int8_t current_harq_pid = sched_ctrl->dl_harq_pid;
+ /* pre-computed PDSCH values that only change if time domain
+ * allocation/DMRS parameters change. Updated in the preprocessor through
+ * nr_set_pdsch_semi_static() */
+ NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
+
+ int8_t current_harq_pid = sched_pdsch->dl_harq_pid;
if (current_harq_pid < 0) {
/* PP has not selected a specific HARQ Process, get a new one */
current_harq_pid = sched_ctrl->available_dl_harq.head;
@@ -721,7 +798,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
"no free HARQ process available for UE %d\n",
UE_id);
remove_front_nr_list(&sched_ctrl->available_dl_harq);
- sched_ctrl->dl_harq_pid = current_harq_pid;
+ sched_pdsch->dl_harq_pid = current_harq_pid;
} else {
/* PP selected a specific HARQ process. Check whether it will be a new
* transmission or a retransmission, and remove from the corresponding
@@ -735,20 +812,21 @@ void nr_schedule_ue_spec(module_id_t module_id,
DevAssert(!harq->is_waiting);
add_tail_nr_list(&sched_ctrl->feedback_dl_harq, current_harq_pid);
NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[0];
+ harq->feedback_frame = pucch->frame;
harq->feedback_slot = pucch->ul_slot;
harq->is_waiting = true;
UE_info->mac_stats[UE_id].dlsch_rounds[harq->round]++;
LOG_D(MAC,
- "%4d.%2d RNTI %04x start %d RBs %d startSymbol %d nb_symbsol %d MCS %d TBS %d HARQ PID %d round %d NDI %d\n",
+ "%4d.%2d RNTI %04x start %3d RBs %3d startSymbol %2d nb_symbol %2d MCS %2d TBS %4d HARQ PID %2d round %d NDI %d\n",
frame,
slot,
rnti,
- sched_ctrl->rbStart,
- sched_ctrl->rbSize,
- startSymbolIndex,
- nrOfSymbols,
- sched_ctrl->mcs,
+ sched_pdsch->rbStart,
+ sched_pdsch->rbSize,
+ ps->startSymbolIndex,
+ ps->nrOfSymbols,
+ sched_pdsch->mcs,
TBS,
current_harq_pid,
harq->round,
@@ -804,8 +882,9 @@ void nr_schedule_ue_spec(module_id_t module_id,
pdsch_pdu->NrOfCodewords = 1;
pdsch_pdu->targetCodeRate[0] = R;
pdsch_pdu->qamModOrder[0] = Qm;
- pdsch_pdu->mcsIndex[0] = sched_ctrl->mcs;
- pdsch_pdu->mcsTable[0] = sched_ctrl->mcsTableIdx;
+ pdsch_pdu->mcsIndex[0] = sched_pdsch->mcs;
+ pdsch_pdu->mcsTable[0] = ps->mcsTableIdx;
+ AssertFatal(harq->round<4,"%d",harq->round);
pdsch_pdu->rvIndex[0] = nr_rv_round_map[harq->round];
pdsch_pdu->TBSize[0] = TBS;
@@ -815,25 +894,22 @@ void nr_schedule_ue_spec(module_id_t module_id,
pdsch_pdu->refPoint = 0; // Point A
// DMRS
- pdsch_pdu->dlDmrsSymbPos =
- fill_dmrs_mask(bwp->bwp_Dedicated->pdsch_Config->choice.setup,
- scc->dmrs_TypeA_Position,
- nrOfSymbols);
- pdsch_pdu->dmrsConfigType = dmrsConfigType;
+ pdsch_pdu->dlDmrsSymbPos = ps->dl_dmrs_symb_pos;
+ pdsch_pdu->dmrsConfigType = ps->dmrsConfigType;
pdsch_pdu->dlDmrsScramblingId = *scc->physCellId;
pdsch_pdu->SCID = 0;
- pdsch_pdu->numDmrsCdmGrpsNoData = sched_ctrl->numDmrsCdmGrpsNoData;
+ pdsch_pdu->numDmrsCdmGrpsNoData = ps->numDmrsCdmGrpsNoData;
pdsch_pdu->dmrsPorts = 1;
// Pdsch Allocation in frequency domain
pdsch_pdu->resourceAlloc = 1;
- pdsch_pdu->rbStart = sched_ctrl->rbStart;
- pdsch_pdu->rbSize = sched_ctrl->rbSize;
+ pdsch_pdu->rbStart = sched_pdsch->rbStart;
+ pdsch_pdu->rbSize = sched_pdsch->rbSize;
pdsch_pdu->VRBtoPRBMapping = 1; // non-interleaved, check if this is ok for initialBWP
// Resource Allocation in time domain
- pdsch_pdu->StartSymbolIndex = startSymbolIndex;
- pdsch_pdu->NrOfSymbols = nrOfSymbols;
+ pdsch_pdu->StartSymbolIndex = ps->startSymbolIndex;
+ pdsch_pdu->NrOfSymbols = ps->nrOfSymbols;
/* Check and validate PTRS values */
struct NR_SetupRelease_PTRS_DownlinkConfig *phaseTrackingRS =
@@ -887,8 +963,8 @@ void nr_schedule_ue_spec(module_id_t module_id,
pdsch_pdu->rbSize,
pdsch_pdu->rbStart,
pdsch_pdu->BWPSize);
- dci_payload.time_domain_assignment.val = sched_ctrl->time_domain_allocation;
- dci_payload.mcs = sched_ctrl->mcs;
+ dci_payload.time_domain_assignment.val = ps->time_domain_allocation;
+ dci_payload.mcs = sched_pdsch->mcs;
dci_payload.rv = pdsch_pdu->rvIndex[0];
dci_payload.harq_pid = current_harq_pid;
dci_payload.ndi = harq->ndi;
@@ -933,29 +1009,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
pdcch_pdu->StartSymbolIndex,
pdcch_pdu->DurationSymbols);
- NR_UE_ret_info_t *retInfo = &sched_ctrl->retInfo[current_harq_pid];
if (harq->round != 0) { /* retransmission */
- if (sched_ctrl->rbSize != retInfo->rbSize)
- LOG_W(MAC,
- "retransmission uses different rbSize (%d vs. orig %d)\n",
- sched_ctrl->rbSize,
- retInfo->rbSize);
- if (sched_ctrl->time_domain_allocation != retInfo->time_domain_allocation)
- LOG_W(MAC,
- "retransmission uses different time_domain_allocation (%d vs. orig %d)\n",
- sched_ctrl->time_domain_allocation,
- retInfo->time_domain_allocation);
- if (sched_ctrl->mcs != retInfo->mcs
- || sched_ctrl->mcsTableIdx != retInfo->mcsTableIdx
- || sched_ctrl->numDmrsCdmGrpsNoData != retInfo->numDmrsCdmGrpsNoData)
- LOG_W(MAC,
- "retransmission uses different table/MCS/numDmrsCdmGrpsNoData (%d/%d/%d vs. orig %d/%d/%d)\n",
- sched_ctrl->mcsTableIdx,
- sched_ctrl->mcs,
- sched_ctrl->numDmrsCdmGrpsNoData,
- retInfo->mcsTableIdx,
- retInfo->mcs,
- retInfo->numDmrsCdmGrpsNoData);
/* we do not have to do anything, since we do not require to get data
* from RLC or encode MAC CEs. The TX_req structure is filled below
* or copy data to FAPI structures */
@@ -968,7 +1022,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
current_harq_pid,
harq->round,
harq->ndi);
- AssertFatal(harq->tb_size == TBS,
+ AssertFatal(harq->sched_pdsch.tb_size == TBS,
"UE %d mismatch between scheduled TBS and buffered TB for HARQ PID %d\n",
UE_id,
current_harq_pid);
@@ -976,7 +1030,6 @@ void nr_schedule_ue_spec(module_id_t module_id,
LOG_D(MAC, "[%s] Initial HARQ transmission in %d.%d\n", __FUNCTION__, frame, slot);
- harq->tb_size = TBS;
uint8_t *buf = (uint8_t *) harq->tb;
/* first, write all CEs that might be there */
@@ -1084,11 +1137,11 @@ void nr_schedule_ue_spec(module_id_t module_id,
UE_info->mac_stats[UE_id].dlsch_current_bytes = TBS;
UE_info->mac_stats[UE_id].lc_bytes_tx[lcid] += dlsch_total_bytes;
- retInfo->rbSize = sched_ctrl->rbSize;
- retInfo->time_domain_allocation = sched_ctrl->time_domain_allocation;
- retInfo->mcsTableIdx = sched_ctrl->mcsTableIdx;
- retInfo->mcs = sched_ctrl->mcs;
- retInfo->numDmrsCdmGrpsNoData = sched_ctrl->numDmrsCdmGrpsNoData;
+ /* save retransmission information */
+ harq->sched_pdsch = *sched_pdsch;
+ /* save which time allocation has been used, to be used on
+ * retransmissions */
+ harq->sched_pdsch.time_domain_allocation = ps->time_domain_allocation;
// ta command is sent, values are reset
if (sched_ctrl->ta_apply) {
@@ -1117,6 +1170,6 @@ void nr_schedule_ue_spec(module_id_t module_id,
gNB_mac->TX_req[CC_id].Slot = slot;
/* mark UE as scheduled */
- sched_ctrl->rbSize = 0;
+ memset(sched_pdsch, 0, sizeof(*sched_pdsch));
}
}
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
index 6487f391b9..21875789a9 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
@@ -164,7 +164,8 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
pdsch_pdu_rel15->NrOfSymbols = NrOfSymbols;
pdsch_pdu_rel15->dlDmrsSymbPos = fill_dmrs_mask(NULL,
scc->dmrs_TypeA_Position,
- NrOfSymbols);
+ NrOfSymbols,
+ StartSymbolIndex);
/*
AssertFatal(k0==0,"k0 is not zero for Initial DL BWP TimeDomain Alloc\n");
@@ -254,16 +255,22 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
}
}
+extern int getNrOfSymbols(NR_BWP_Downlink_t *bwp, int tda);
+extern uint8_t getN_PRB_DMRS(NR_BWP_Downlink_t *bwp, int numDmrsCdmGrpsNoData);
+uint32_t target_dl_mcs = 9;
+uint32_t target_dl_bw = 50;
+uint64_t dlsch_slot_bitmap = (1<<1);
/* schedules whole bandwidth for first user, all the time */
void nr_preprocessor_phytest(module_id_t module_id,
frame_t frame,
sub_frame_t slot)
{
- if (slot != 1)
+ if (!is_xlsch_in_slot(dlsch_slot_bitmap, slot))
return;
+ const int CC_id = 0;
+ const NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[CC_id].ServingCellConfigCommon;
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
const int UE_id = 0;
- const int CC_id = 0;
AssertFatal(UE_info->active[UE_id],
"%s(): expected UE %d to be active\n",
__func__,
@@ -272,24 +279,25 @@ void nr_preprocessor_phytest(module_id_t module_id,
/* find largest unallocated chunk */
const int bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
int rbStart = 0;
- int tStart = 0;
int rbSize = 0;
uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map;
- /* find largest unallocated RB region */
- do {
+ /* loop ensures that we allocate exactly target_dl_bw, or return */
+ while (true) {
/* advance to first free RB */
- while (tStart < bwpSize && vrb_map[tStart])
- tStart++;
- /* find maximum rbSize at current rbStart */
- int tSize = 1;
- while (tStart + tSize < bwpSize && !vrb_map[tStart + tSize])
- tSize++;
- if (tSize > rbSize) {
- rbStart = tStart;
- rbSize = tSize;
- }
- tStart += tSize;
- } while (tStart < bwpSize);
+ while (rbStart < bwpSize && vrb_map[rbStart])
+ rbStart++;
+ rbSize = 1;
+ /* iterate until we are at target_dl_bw or no available RBs */
+ while (rbStart + rbSize < bwpSize && !vrb_map[rbStart + rbSize] && rbSize < target_dl_bw)
+ rbSize++;
+ /* found target_dl_bw? */
+ if (rbSize == target_dl_bw)
+ break;
+ /* at end and below target_dl_bw? */
+ if (rbStart + rbSize >= bwpSize)
+ return;
+ rbStart += rbSize;
+ }
sched_ctrl->num_total_bytes = 0;
const int lcid = DL_SCH_LCID_DTCH;
@@ -308,14 +316,10 @@ void nr_preprocessor_phytest(module_id_t module_id,
0);
sched_ctrl->num_total_bytes += sched_ctrl->rlc_status[lcid].bytes_in_buffer;
- const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
- sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, target_ss);
uint8_t nr_of_candidates;
find_aggregation_candidates(&sched_ctrl->aggregation_level,
&nr_of_candidates,
sched_ctrl->search_space);
- sched_ctrl->coreset = get_coreset(
- sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */);
const int cid = sched_ctrl->coreset->controlResourceSetId;
const uint16_t Y = UE_info->Y[UE_id][cid][slot];
const int m = UE_info->num_pdcch_cand[UE_id][cid];
@@ -351,32 +355,42 @@ void nr_preprocessor_phytest(module_id_t module_id,
"could not find uplink slot for PUCCH (RNTI %04x@%d.%d)!\n",
rnti, frame, slot);
- sched_ctrl->rbStart = rbStart;
- sched_ctrl->rbSize = rbSize;
- sched_ctrl->time_domain_allocation = 2;
- if (!UE_info->secondaryCellGroup[UE_id]->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->mcs_Table)
- sched_ctrl->mcsTableIdx = 0;
- else {
- if (*UE_info->secondaryCellGroup[UE_id]->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->mcs_Table == 0)
- sched_ctrl->mcsTableIdx = 1;
- else
- sched_ctrl->mcsTableIdx = 2;
- }
- sched_ctrl->mcs = 9;
- sched_ctrl->numDmrsCdmGrpsNoData = 1;
+ NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
+ NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
+ sched_pdsch->rbStart = rbStart;
+ sched_pdsch->rbSize = rbSize;
+ const int tda = RC.nrmac[module_id]->preferred_dl_tda[sched_ctrl->active_bwp->bwp_Id][slot];
+ const uint8_t num_dmrs_cdm_grps_no_data = 1;
+ if (ps->time_domain_allocation != tda || ps->numDmrsCdmGrpsNoData != num_dmrs_cdm_grps_no_data)
+ nr_set_pdsch_semi_static(
+ scc, UE_info->secondaryCellGroup[UE_id], sched_ctrl->active_bwp, tda, num_dmrs_cdm_grps_no_data, ps);
+
+ sched_pdsch->mcs = target_dl_mcs;
+ sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx);
+ sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx);
+ sched_pdsch->tb_size = nr_compute_tbs(sched_pdsch->Qm,
+ sched_pdsch->R,
+ sched_pdsch->rbSize,
+ ps->nrOfSymbols,
+ ps->N_PRB_DMRS * ps->N_DMRS_SLOT,
+ 0 /* N_PRB_oh, 0 for initialBWP */,
+ 0 /* tb_scaling */,
+ 1 /* nrOfLayers */)
+ >> 3;
+
/* get the PID of a HARQ process awaiting retransmission, or -1 otherwise */
- sched_ctrl->dl_harq_pid = sched_ctrl->retrans_dl_harq.head;
+ sched_pdsch->dl_harq_pid = sched_ctrl->retrans_dl_harq.head;
/* mark the corresponding RBs as used */
- for (int rb = 0; rb < sched_ctrl->rbSize; rb++)
- vrb_map[rb + sched_ctrl->rbStart] = 1;
+ for (int rb = 0; rb < sched_pdsch->rbSize; rb++)
+ vrb_map[rb + sched_pdsch->rbStart] = 1;
}
-bool nr_ul_preprocessor_phytest(module_id_t module_id,
- frame_t frame,
- sub_frame_t slot,
- int num_slots_per_tdd,
- uint64_t ulsch_in_slot_bitmap) {
+uint32_t target_ul_mcs = 9;
+uint32_t target_ul_bw = 50;
+uint64_t ulsch_slot_bitmap = (1 << 8);
+bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_t slot)
+{
gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
NR_COMMON_channels_t *cc = nr_mac->common_channels;
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
@@ -395,7 +409,9 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id,
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
- const int tda = 1;
+ const int tda = RC.nrmac[module_id]->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot];
+ if (tda < 0)
+ return false;
const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList =
sched_ctrl->active_ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
AssertFatal(tda < tdaList->list.count,
@@ -408,19 +424,29 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id,
/* check if slot is UL, and that slot is 8 (assuming K2=6 because of UE
* limitations). Note that if K2 or the TDD configuration is changed, below
* conditions might exclude each other and never be true */
- if (!(is_xlsch_in_slot(ulsch_in_slot_bitmap, sched_slot) && sched_slot == 8))
+ if (!is_xlsch_in_slot(ulsch_slot_bitmap, sched_slot))
return false;
- const int bw = NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+ const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats;
+ const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0;
+ const uint8_t num_dmrs_cdm_grps_no_data = 1;
+ /* we want to avoid a lengthy deduction of DMRS and other parameters in
+ * every TTI if we can save it, so check whether dci_format, TDA, or
+ * num_dmrs_cdm_grps_no_data has changed and only then recompute */
+ NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static;
+ if (ps->time_domain_allocation != tda
+ || ps->dci_format != dci_format
+ || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data)
+ nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, dci_format, tda, num_dmrs_cdm_grps_no_data, ps);
+
uint16_t rbStart = 0;
- uint16_t rbSize = 50; /* due to OAI UE limitations */
- if (rbSize>bw)
- rbSize = bw;
+ uint16_t rbSize = target_ul_bw;
uint16_t *vrb_map_UL =
&RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[sched_slot * MAX_BWP_SIZE];
+ const uint16_t symb = ((1 << ps->nrOfSymbols) - 1) << ps->startSymbolIndex;
for (int i = rbStart; i < rbStart + rbSize; ++i) {
- if (vrb_map_UL[i]) {
+ if ((vrb_map_UL[i] & symb) != 0) {
LOG_E(MAC,
"%s(): %4d.%2d RB %d is already reserved, cannot schedule UE\n",
__func__,
@@ -434,14 +460,10 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id,
sched_ctrl->sched_pusch.slot = sched_slot;
sched_ctrl->sched_pusch.frame = sched_frame;
- const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
- sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, target_ss);
uint8_t nr_of_candidates;
find_aggregation_candidates(&sched_ctrl->aggregation_level,
&nr_of_candidates,
sched_ctrl->search_space);
- sched_ctrl->coreset = get_coreset(
- sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */);
const int cid = sched_ctrl->coreset->controlResourceSetId;
const uint16_t Y = UE_info->Y[UE_id][cid][slot];
const int m = UE_info->num_pdcch_cand[UE_id][cid];
@@ -458,25 +480,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id,
}
UE_info->num_pdcch_cand[UE_id][cid]++;
- sched_ctrl->sched_pusch.time_domain_allocation = tda;
- const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats;
- const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0;
- const uint8_t num_dmrs_cdm_grps_no_data = 1;
- /* we want to avoid a lengthy deduction of DMRS and other parameters in
- * every TTI if we can save it, so check whether dci_format, TDA, or
- * num_dmrs_cdm_grps_no_data has changed and only then recompute */
- NR_sched_pusch_save_t *ps = &sched_ctrl->pusch_save;
- if (ps->time_domain_allocation != tda
- || ps->dci_format != dci_format
- || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data)
- nr_save_pusch_fields(scc,
- sched_ctrl->active_ubwp,
- dci_format,
- tda,
- num_dmrs_cdm_grps_no_data,
- ps);
-
- const int mcs = 9;
+ const int mcs = target_ul_mcs;
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
sched_pusch->mcs = mcs;
sched_pusch->rbStart = rbStart;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
index 9db78244ba..31ae1cf330 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
@@ -120,11 +120,10 @@ static inline uint8_t get_max_candidates(uint8_t scs) {
static inline uint8_t get_max_cces(uint8_t scs) {
AssertFatal(scs<4, "Invalid PDCCH subcarrier spacing %d\n", scs);
return (nr_max_number_of_cces_per_slot[scs]);
-}
+}
-NR_ControlResourceSet_t *get_coreset(NR_BWP_Downlink_t *bwp,
- NR_SearchSpace_t *ss,
- int ss_type) {
+NR_ControlResourceSet_t *get_coreset(const NR_BWP_Downlink_t *bwp, const NR_SearchSpace_t *ss, int ss_type)
+{
NR_ControlResourceSetId_t coreset_id = *ss->controlResourceSetId;
if (ss_type == 0) { // common search space
AssertFatal(coreset_id != 0, "coreset0 currently not supported\n");
@@ -146,9 +145,8 @@ NR_ControlResourceSet_t *get_coreset(NR_BWP_Downlink_t *bwp,
}
}
-NR_SearchSpace_t *get_searchspace(
- NR_BWP_Downlink_t *bwp,
- NR_SearchSpace__searchSpaceType_PR target_ss) {
+NR_SearchSpace_t *get_searchspace(const NR_BWP_Downlink_t *bwp, NR_SearchSpace__searchSpaceType_PR target_ss)
+{
DevAssert(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList);
DevAssert(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count > 0);
@@ -178,7 +176,7 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
int coreset_id = coreset->controlResourceSetId;
int *cce_list;
- if(bwp->bwp_Id == 0) {
+ if( bwp==NULL || bwp->bwp_Id == 0 ) {
cce_list = nr_mac->cce_list[1][0];
} else {
cce_list = nr_mac->cce_list[bwp->bwp_Id][coreset_id];
@@ -212,12 +210,98 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
}
-void nr_save_pusch_fields(const NR_ServingCellConfigCommon_t *scc,
- const NR_BWP_Uplink_t *ubwp,
- long dci_format,
- int tda,
- uint8_t num_dmrs_cdm_grps_no_data,
- NR_sched_pusch_save_t *ps)
+bool nr_find_nb_rb(uint16_t Qm,
+ uint16_t R,
+ uint16_t nb_symb_sch,
+ uint16_t nb_dmrs_prb,
+ uint32_t bytes,
+ uint16_t nb_rb_max,
+ uint32_t *tbs,
+ uint16_t *nb_rb)
+{
+ /* is the maximum (not even) enough? */
+ *nb_rb = nb_rb_max;
+ *tbs = nr_compute_tbs(Qm, R, *nb_rb, nb_symb_sch, nb_dmrs_prb, 0, 0, 1) >> 3;
+ /* check whether it does not fit, or whether it exactly fits. Some algorithms
+ * might depend on the return value! */
+ if (bytes > *tbs)
+ return false;
+ if (bytes == *tbs)
+ return true;
+
+ /* is the minimum enough? */
+ *nb_rb = 1;
+ *tbs = nr_compute_tbs(Qm, R, *nb_rb, nb_symb_sch, nb_dmrs_prb, 0, 0, 1) >> 3;
+ if (bytes <= *tbs)
+ return true;
+
+ /* perform binary search to allocate all bytes within a TBS up to nb_rb_max
+ * RBs */
+ int hi = nb_rb_max;
+ int lo = 1;
+ for (int p = (hi + lo) / 2; lo + 1 < hi; p = (hi + lo) / 2) {
+ const uint32_t TBS = nr_compute_tbs(Qm, R, p, nb_symb_sch, nb_dmrs_prb, 0, 0, 1) >> 3;
+ if (bytes == TBS) {
+ hi = p;
+ break;
+ } else if (bytes < TBS) {
+ hi = p;
+ } else {
+ lo = p;
+ }
+ }
+ *nb_rb = hi;
+ *tbs = nr_compute_tbs(Qm, R, *nb_rb, nb_symb_sch, nb_dmrs_prb, 0, 0, 1) >> 3;
+ /* return whether we could allocate all bytes and stay below nb_rb_max */
+ return *tbs >= bytes && *nb_rb <= nb_rb_max;
+}
+
+void nr_set_pdsch_semi_static(const NR_ServingCellConfigCommon_t *scc,
+ const NR_CellGroupConfig_t *secondaryCellGroup,
+ const NR_BWP_Downlink_t *bwp,
+ int tda,
+ uint8_t num_dmrs_cdm_grps_no_data,
+ NR_pdsch_semi_static_t *ps)
+{
+ ps->time_domain_allocation = tda;
+
+ const struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList =
+ bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
+ AssertFatal(tda < tdaList->list.count, "time_domain_allocation %d>=%d\n", tda, tdaList->list.count);
+ const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength;
+ SLIV2SL(startSymbolAndLength, &ps->startSymbolIndex, &ps->nrOfSymbols);
+
+ if (!secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup
+ ->mcs_Table)
+ ps->mcsTableIdx = 0;
+ else if (*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup
+ ->mcs_Table
+ == 0)
+ ps->mcsTableIdx = 1;
+ else
+ ps->mcsTableIdx = 2;
+
+ ps->numDmrsCdmGrpsNoData = num_dmrs_cdm_grps_no_data;
+ ps->dmrsConfigType =
+ bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type
+ == NULL
+ ? 0
+ : 1;
+ // if no data in dmrs cdm group is 1 only even REs have no data
+ // if no data in dmrs cdm group is 2 both odd and even REs have no data
+ ps->N_PRB_DMRS = num_dmrs_cdm_grps_no_data * (ps->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6 : 4);
+ ps->N_DMRS_SLOT =
+ get_num_dmrs_symbols(bwp->bwp_Dedicated->pdsch_Config->choice.setup, scc->dmrs_TypeA_Position, ps->nrOfSymbols, ps->startSymbolIndex);
+ ps->dl_dmrs_symb_pos =
+ fill_dmrs_mask(bwp->bwp_Dedicated->pdsch_Config->choice.setup, scc->dmrs_TypeA_Position, ps->nrOfSymbols, ps->startSymbolIndex);
+}
+
+void nr_set_pusch_semi_static(const NR_ServingCellConfigCommon_t *scc,
+ const NR_BWP_Uplink_t *ubwp,
+ long dci_format,
+ int tda,
+ uint8_t num_dmrs_cdm_grps_no_data,
+ NR_pusch_semi_static_t *ps)
{
ps->dci_format = dci_format;
ps->time_domain_allocation = tda;
@@ -563,6 +647,8 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
NR_ServingCellConfigCommon_t *scc,
NR_BWP_Downlink_t *bwp)
{
+ int sps = 0;
+
if (bwp) { // This is not the InitialBWP
pdcch_pdu->BWPSize = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
pdcch_pdu->BWPStart = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
@@ -571,8 +657,18 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
// first symbol
//AssertFatal(pdcch_scs==kHz15, "PDCCH SCS above 15kHz not allowed if a symbol above 2 is monitored");
- int sps = bwp->bwp_Common->genericParameters.cyclicPrefix == NULL ? 14 : 12;
+ sps = bwp->bwp_Common->genericParameters.cyclicPrefix == NULL ? 14 : 12;
+ }
+ else { // this is for InitialBWP
+ pdcch_pdu->BWPSize = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+ pdcch_pdu->BWPStart = NRRIV2PRBOFFSET(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+ pdcch_pdu->SubcarrierSpacing = scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing;
+ pdcch_pdu->CyclicPrefix = (scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.cyclicPrefix==NULL) ? 0 : *scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.cyclicPrefix;
+ // first symbol
+ //AssertFatal(pdcch_scs==kHz15, "PDCCH SCS above 15kHz not allowed if a symbol above 2 is monitored");
+ sps = scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.cyclicPrefix == NULL ? 14 : 12;
+ }
AssertFatal(ss->monitoringSymbolsWithinSlot!=NULL,"ss->monitoringSymbolsWithinSlot is null\n");
AssertFatal(ss->monitoringSymbolsWithinSlot->buf!=NULL,"ss->monitoringSymbolsWithinSlot->buf is null\n");
@@ -617,10 +713,6 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
//precoderGranularity
pdcch_pdu->precoderGranularity = coreset->precoderGranularity;
- }
- else { // this is for InitialBWP
- AssertFatal(1==0,"Fill in InitialBWP PDCCH configuration\n");
- }
}
@@ -1134,6 +1226,7 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
break;
case NR_RNTI_TC:
+ pos = 1;
// indicating a DL DCI format 1bit
*dci_pdu |= ((uint64_t)dci_pdu_rel15->format_indicator & 1) << (dci_size - pos++);
// Freq domain assignment 0-16 bit
@@ -1162,9 +1255,27 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
// TPC command for scheduled PUCCH – 2 bits
for (int i = 0; i < 2; i++)
*dci_pdu |= (((uint64_t)dci_pdu_rel15->tpc >> (1 - i)) & 1) << (dci_size - pos++);
+ // PUCCH resource indicator – 3 bits
+ for (int i = 0; i < 3; i++)
+ *dci_pdu |= (((uint64_t)dci_pdu_rel15->pucch_resource_indicator >> (2 - i)) & 1) << (dci_size - pos++);
// PDSCH-to-HARQ_feedback timing indicator – 3 bits
for (int i = 0; i < 3; i++)
*dci_pdu |= (((uint64_t)dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val >> (2 - i)) & 1) << (dci_size - pos++);
+
+ LOG_D(NR_MAC,"N_RB = %i\n", N_RB);
+ LOG_D(NR_MAC,"dci_size = %i\n", dci_size);
+ LOG_D(NR_MAC,"fsize = %i\n", fsize);
+ LOG_D(NR_MAC,"dci_pdu_rel15->format_indicator = %i\n", dci_pdu_rel15->format_indicator);
+ LOG_D(NR_MAC,"dci_pdu_rel15->frequency_domain_assignment.val = %i\n", dci_pdu_rel15->frequency_domain_assignment.val);
+ LOG_D(NR_MAC,"dci_pdu_rel15->time_domain_assignment.val = %i\n", dci_pdu_rel15->time_domain_assignment.val);
+ LOG_D(NR_MAC,"dci_pdu_rel15->vrb_to_prb_mapping.val = %i\n", dci_pdu_rel15->vrb_to_prb_mapping.val);
+ LOG_D(NR_MAC,"dci_pdu_rel15->mcs = %i\n", dci_pdu_rel15->mcs);
+ LOG_D(NR_MAC,"dci_pdu_rel15->rv = %i\n", dci_pdu_rel15->rv);
+ LOG_D(NR_MAC,"dci_pdu_rel15->harq_pid = %i\n", dci_pdu_rel15->harq_pid);
+ LOG_D(NR_MAC,"dci_pdu_rel15->dai[0].val = %i\n", dci_pdu_rel15->dai[0].val);
+ LOG_D(NR_MAC,"dci_pdu_rel15->tpc = %i\n", dci_pdu_rel15->tpc);
+ LOG_D(NR_MAC,"dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val = %i\n", dci_pdu_rel15->pdsch_to_harq_feedback_timing_indicator.val);
+
break;
}
break;
@@ -1616,6 +1727,24 @@ int get_nrofHARQ_ProcessesForPDSCH(e_NR_PDSCH_ServingCellConfig__nrofHARQ_Proces
}
}
+int get_dl_bwp_id(const NR_ServingCellConfig_t *servingCellConfig)
+{
+ if (servingCellConfig->firstActiveDownlinkBWP_Id)
+ return *servingCellConfig->firstActiveDownlinkBWP_Id;
+ else if (servingCellConfig->defaultDownlinkBWP_Id)
+ return *servingCellConfig->defaultDownlinkBWP_Id;
+ else
+ return 1;
+}
+
+int get_ul_bwp_id(const NR_ServingCellConfig_t *servingCellConfig)
+{
+ if (servingCellConfig->uplinkConfig && servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id)
+ return *servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id;
+ else
+ return 1;
+}
+
//------------------------------------------------------------------------------
int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *secondaryCellGroup)
{
@@ -1644,23 +1773,32 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *secon
sched_ctrl->ta_frame = 0;
sched_ctrl->ta_update = 31;
sched_ctrl->ta_apply = false;
- sched_ctrl->ul_rssi = 0;
/* set illegal time domain allocation to force recomputation of all fields */
- sched_ctrl->pusch_save.time_domain_allocation = -1;
+ sched_ctrl->pdsch_semi_static.time_domain_allocation = -1;
+ sched_ctrl->pusch_semi_static.time_domain_allocation = -1;
const NR_ServingCellConfig_t *servingCellConfig = secondaryCellGroup->spCellConfig->spCellConfigDedicated;
/* Set default BWPs */
const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig->downlinkBWP_ToAddModList;
- AssertFatal(bwpList->list.count == 1,
- "downlinkBWP_ToAddModList has %d BWP!\n",
+ const int bwp_id = get_dl_bwp_id(servingCellConfig);
+ AssertFatal(bwp_id > 0 && bwp_id <= bwpList->list.count,
+ "%s(): illegal bwp_id %d (max %d)!\n",
+ __func__,
+ bwp_id,
bwpList->list.count);
- const int bwp_id = 1;
sched_ctrl->active_bwp = bwpList->list.array[bwp_id - 1];
+ const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific;
+ sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, target_ss);
+ sched_ctrl->coreset = get_coreset(sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */);
+
const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList;
- AssertFatal(ubwpList->list.count == 1,
- "uplinkBWP_ToAddModList has %d BWP!\n",
+ const int ubwp_id = get_ul_bwp_id(servingCellConfig);
+ AssertFatal(ubwp_id > 0 && ubwp_id <= ubwpList->list.count,
+ "%s(): illegal ubwp_id %d (max %d)!\n",
+ __func__,
+ ubwp_id,
ubwpList->list.count);
- sched_ctrl->active_ubwp = ubwpList->list.array[bwp_id - 1];
+ sched_ctrl->active_ubwp = ubwpList->list.array[ubwp_id - 1];
/* get Number of HARQ processes for this UE */
AssertFatal(servingCellConfig->pdsch_ServingCellConfig->present == NR_SetupRelease_PDSCH_ServingCellConfig_PR_setup,
@@ -1682,7 +1820,7 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *secon
add_tail_nr_list(&sched_ctrl->available_ul_harq, harq);
create_nr_list(&sched_ctrl->feedback_ul_harq, 16);
create_nr_list(&sched_ctrl->retrans_ul_harq, 16);
- LOG_I(MAC, "gNB %d] Add NR UE_id %d : rnti %x\n",
+ LOG_I(MAC, "[gNB %d] Add NR UE_id %d : rnti %x\n",
mod_idP,
UE_id,
rntiP);
@@ -1738,7 +1876,7 @@ void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti)
if (pthread_mutex_lock(&rnti_to_remove_mutex)) exit(1);
if (rnti_to_remove_count == 10) exit(1);
rnti_to_remove[rnti_to_remove_count] = rnti;
- LOG_W(MAC, "to remove in mac rnti_to_remove[%d]=%d\n", rnti_to_remove_count, rnti);
+ LOG_W(NR_MAC, "to remove in mac rnti_to_remove[%d] = 0x%04x\n", rnti_to_remove_count, rnti);
rnti_to_remove_count++;
if (pthread_mutex_unlock(&rnti_to_remove_mutex)) exit(1);
}
@@ -1758,6 +1896,16 @@ void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti)
}
}
+void nr_mac_remove_ra_rnti(module_id_t mod_id, rnti_t rnti) {
+ // Hack to remove UE in the phy (following the same procedure as in function mac_remove_nr_ue)
+ if (pthread_mutex_lock(&rnti_to_remove_mutex)) exit(1);
+ if (rnti_to_remove_count == 10) exit(1);
+ rnti_to_remove[rnti_to_remove_count] = rnti;
+ LOG_W(NR_MAC, "to remove in mac rnti_to_remove[%d] = 0x%04x\n", rnti_to_remove_count, rnti);
+ rnti_to_remove_count++;
+ if (pthread_mutex_unlock(&rnti_to_remove_mutex)) exit(1);
+}
+
uint8_t nr_get_tpc(int target, uint8_t cqi, int incr) {
// al values passed to this function are x10
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
index 247a7e2c45..f477066fc6 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
@@ -181,7 +181,7 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_in
else {
uint8_t nb_ssb_resources =0;
//Finding the CSI_RS or SSB Resources
- if (NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP == reportQuantity_type ||
+ if (NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP == reportQuantity_type ||
NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP == reportQuantity_type) {
if (NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled == csi_reportconfig->groupBasedBeamReporting.present) {
@@ -191,18 +191,18 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_in
/*! From Spec 38.331
* nrofReportedRS
* The number (N) of measured RS resources to be reported per report setting in a non-group-based report. N <= N_max, where N_max is either 2 or 4 depending on UE
- * capability. FFS: The signaling mechanism for the gNB to select a subset of N beams for the UE to measure and report.
+ * capability. FFS: The signaling mechanism for the gNB to select a subset of N beams for the UE to measure and report.
* When the field is absent the UE applies the value 1
*/
csi_report->CSI_report_bitlen.nb_ssbri_cri= 1;
- }else
+ }else
csi_report->CSI_report_bitlen.nb_ssbri_cri= 2;
if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP == csi_report->reportQuantity_type) {
for ( csi_ssb_idx = 0; csi_ssb_idx < csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.count; csi_ssb_idx++) {
if (csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceSetId ==
*(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.array[0])){
-
+
///We can configure only one SSB resource set from spec 38.331 IE CSI-ResourceConfig
nb_ssb_resources= csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceList.list.count;
csi_report->SSB_Index_list = csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceList.list.array;
@@ -226,12 +226,12 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_in
if (nb_ssb_resources) {
csi_report->CSI_report_bitlen.cri_ssbri_bitlen =ceil(log2 (nb_ssb_resources));
- csi_report->CSI_report_bitlen.rsrp_bitlen = 7; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP
+ csi_report->CSI_report_bitlen.rsrp_bitlen = 7; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP
csi_report->CSI_report_bitlen.diff_rsrp_bitlen =4; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP
- } else {
+ } else {
csi_report->CSI_report_bitlen.cri_ssbri_bitlen =0;
- csi_report->CSI_report_bitlen.rsrp_bitlen = 0;
- csi_report->CSI_report_bitlen.diff_rsrp_bitlen =0;
+ csi_report->CSI_report_bitlen.rsrp_bitlen = 0;
+ csi_report->CSI_report_bitlen.diff_rsrp_bitlen =0;
}
LOG_I (MAC, "UCI: CSI_bit len : ssbri %d, rsrp: %d, diff_rsrp: %d\n",
@@ -270,7 +270,7 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_in
csi_report->csi_meas_bitlen.ri_bitlen=0;
break;
case 2:
- /* From Spec 38.212
+ /* From Spec 38.212
* If the higher layer parameter nrofCQIsPerReport=1, nRI in Table 6.3.1.1.2-3 is the number of allowed rank indicator
* values in the 4 LSBs of the higher layer parameter typeI-SinglePanel-ri-Restriction according to Subclause 5.2.2.2.1 [6,
* TS 38.214]; otherwise nRI in Table 6.3.1.1.2-3 is the number of allowed rank indicator values according to Subclause
@@ -283,7 +283,7 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_in
ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0];
- /* Replace dummy with the nrofCQIsPerReport from the CSIreport
+ /* Replace dummy with the nrofCQIsPerReport from the CSIreport
config when equalent ASN structure present */
if (0==*(csi_reportconfig->dummy)){
nb_allowed_ri = number_of_bits_set((ri_restriction & 0xf0), &max_ri);
@@ -293,7 +293,7 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_in
nb_allowed_ri = number_of_bits_set(ri_restriction, &max_ri);
ri_bitlen = ceil(log2(nb_allowed_ri));
}
- ri_bitlen = ri_bitlen<1?ri_bitlen:1; //from the spec 38.212 and table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel
+ ri_bitlen = ri_bitlen<1?ri_bitlen:1; //from the spec 38.212 and table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel
csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen;
break;
case 4:
@@ -301,7 +301,7 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_in
ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0];
- /* Replace dummy with the nrofCQIsPerReport from the CSIreport
+ /* Replace dummy with the nrofCQIsPerReport from the CSIreport
config when equalent ASN structure present */
if (0==*(csi_reportconfig->dummy)){
nb_allowed_ri = number_of_bits_set((ri_restriction & 0xf0), &max_ri);
@@ -311,16 +311,16 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_in
nb_allowed_ri = number_of_bits_set(ri_restriction,&max_ri);
ri_bitlen = ceil(log2(nb_allowed_ri));
}
- ri_bitlen = ri_bitlen<2?ri_bitlen:2; //from the spec 38.212 and table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel
+ ri_bitlen = ri_bitlen<2?ri_bitlen:2; //from the spec 38.212 and table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel
csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen;
break;
case 6:
case 8:
AssertFatal (NULL!=csi_reportconfig->dummy, "nrofCQIsPerReport is not present");
-
+
ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0];
- /* Replace dummy with the nrofCQIsPerReport from the CSIreport
+ /* Replace dummy with the nrofCQIsPerReport from the CSIreport
config when equalent ASN structure present */
if (0==*(csi_reportconfig->dummy)){
nb_allowed_ri = number_of_bits_set((ri_restriction & 0xf0),&max_ri);
@@ -353,7 +353,7 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_in
case 4:
case 6:
case 8:
- /* From Spec 38.212
+ /* From Spec 38.212
* If the higher layer parameter nrofCQIsPerReport=1, nRI in Table 6.3.1.1.2-3 is the number of allowed rank indicator
* values in the 4 LSBs of the higher layer parameter typeI-SinglePanel-ri-Restriction according to Subclause 5.2.2.2.1 [6,
* TS 38.214]; otherwise nRI in Table 6.3.1.1.2-3 is the number of allowed rank indicator values according to Subclause
@@ -383,7 +383,7 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_in
case 4:
case 6:
case 8:
- /* From Spec 38.212
+ /* From Spec 38.212
* If the higher layer parameter nrofCQIsPerReport=1, nRI in Table 6.3.1.1.2-3 is the number of allowed rank indicator
* values in the 4 LSBs of the higher layer parameter typeI-SinglePanel-ri-Restriction according to Subclause 5.2.2.2.1 [6,
* TS 38.214]; otherwise nRI in Table 6.3.1.1.2-3 is the number of allowed rank indicator values according to Subclause
@@ -392,18 +392,18 @@ void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE_in
* But from Current RRC ASN structures nrofCQIsPerReport is not present. Present a dummy variable is present so using it to
* calculate RI for antennas equal or more than two.
* */
-
+
if (max_ri > 4 && max_ri < 8){
if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel==csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.present){
if (NR_CSI_ReportConfig__reportFreqConfiguration__cqi_FormatIndicator_widebandCQI==csi_reportconfig->reportFreqConfiguration->cqi_FormatIndicator)
csi_report->csi_meas_bitlen.cqi_bitlen = 8;
- else
+ else
csi_report->csi_meas_bitlen.cqi_bitlen = 4;
}
}else{ //This condition will work even for type1-multipanel.
if (NR_CSI_ReportConfig__reportFreqConfiguration__cqi_FormatIndicator_widebandCQI==csi_reportconfig->reportFreqConfiguration->cqi_FormatIndicator)
csi_report->csi_meas_bitlen.cqi_bitlen = 4;
- else
+ else
csi_report->csi_meas_bitlen.cqi_bitlen = 2;
}
break;
@@ -449,7 +449,7 @@ uint16_t nr_get_csi_bitlen(int Mod_idP,
NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP==UE_info->csi_report_template[UE_id][csi_report_id].reportQuantity_type){
CSI_report_bitlen = &(UE_info->csi_report_template[UE_id][csi_report_id].CSI_report_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements
csi_bitlen+= ((CSI_report_bitlen->cri_ssbri_bitlen * CSI_report_bitlen->nb_ssbri_cri) +
- CSI_report_bitlen->rsrp_bitlen +(CSI_report_bitlen->diff_rsrp_bitlen *
+ CSI_report_bitlen->rsrp_bitlen +(CSI_report_bitlen->diff_rsrp_bitlen *
(CSI_report_bitlen->nb_ssbri_cri -1 )));
} else{
csi_meas_bitlen = &(UE_info->csi_report_template[UE_id][csi_report_id].csi_meas_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements
@@ -569,7 +569,7 @@ static void handle_dl_harq(module_id_t mod_id,
add_tail_nr_list(&UE_info->UE_sched_ctrl[UE_id].available_dl_harq, harq_pid);
harq->round = 0;
harq->ndi ^= 1;
- } else if (harq->round == MAX_HARQ_ROUNDS) {
+ } else if (harq->round >= MAX_HARQ_ROUNDS - 1) {
add_tail_nr_list(&UE_info->UE_sched_ctrl[UE_id].available_dl_harq, harq_pid);
harq->round = 0;
harq->ndi ^= 1;
@@ -654,7 +654,7 @@ int checkTargetSSBInTCIStates_pdcchConfig(int ssb_index_t, int Mod_idP, int UE_i
//returns the measured RSRP value (upper limit)
int get_measured_rsrp(uint8_t index) {
//if index is invalid returning minimum rsrp -140
- if((index >= 0 && index <= 15) || index >= 114)
+ if(index <= 15 || index >= 114)
return MIN_RSRP_VALUE;
return L1_SSB_CSI_RSRP_measReport_mapping_38133_10_1_6_1_1[index];
@@ -890,7 +890,7 @@ void extract_pucch_csi_report (NR_CSI_MeasConfig_t *csi_MeasConfig,
reportQuantity_type = UE_info->csi_report_template[UE_id][csi_report_id].reportQuantity_type;
LOG_D(PHY,"SFN/SF:%d%d reportQuantity type = %d\n",frame,slot,reportQuantity_type);
- if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP == reportQuantity_type ||
+ if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP == reportQuantity_type ||
NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP == reportQuantity_type) {
uint8_t csi_ssb_idx = 0;
uint8_t diff_rsrp_idx = 0;
@@ -922,12 +922,12 @@ void extract_pucch_csi_report (NR_CSI_MeasConfig_t *csi_MeasConfig,
reverse_n_bits(payload, cri_ssbri_bitlen);
if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP == reportQuantity_type)
- sched_ctrl->CSI_report[idx].choice.ssb_cri_report.CRI_SSBRI [csi_ssb_idx] =
+ sched_ctrl->CSI_report[idx].choice.ssb_cri_report.CRI_SSBRI [csi_ssb_idx] =
*(UE_info->csi_report_template[UE_id][csi_report_id].SSB_Index_list[cri_ssbri_bitlen>0?((*payload)&~(~1<<(cri_ssbri_bitlen-1))):cri_ssbri_bitlen]);
else
- sched_ctrl->CSI_report[idx].choice.ssb_cri_report.CRI_SSBRI [csi_ssb_idx] =
+ sched_ctrl->CSI_report[idx].choice.ssb_cri_report.CRI_SSBRI [csi_ssb_idx] =
*(UE_info->csi_report_template[UE_id][csi_report_id].CSI_Index_list[cri_ssbri_bitlen>0?((*payload)&~(~1<<(cri_ssbri_bitlen-1))):cri_ssbri_bitlen]);
-
+
*payload >>= cri_ssbri_bitlen;
LOG_D(PHY,"SSB_index = %d\n",sched_ctrl->CSI_report[idx].choice.ssb_cri_report.CRI_SSBRI [csi_ssb_idx]);
}
@@ -946,9 +946,52 @@ void extract_pucch_csi_report (NR_CSI_MeasConfig_t *csi_MeasConfig,
}
}
- if ( !(reportQuantity_type))
+ if ( !(reportQuantity_type))
AssertFatal(reportQuantity_type, "reportQuantity is not configured");
+}
+static NR_UE_harq_t *find_harq(module_id_t mod_id, frame_t frame, sub_frame_t slot, int UE_id)
+{
+ /* In case of realtime problems: we can only identify a HARQ process by
+ * timing. If the HARQ process's feedback_frame/feedback_slot is not the one we
+ * expected, we assume that processing has been aborted and we need to
+ * skip this HARQ process, which is what happens in the loop below.
+ * Similarly, we might be "in advance", in which case we need to skip
+ * this result. */
+ NR_UE_sched_ctrl_t *sched_ctrl = &RC.nrmac[mod_id]->UE_info.UE_sched_ctrl[UE_id];
+ int8_t pid = sched_ctrl->feedback_dl_harq.head;
+ if (pid < 0)
+ return NULL;
+ NR_UE_harq_t *harq = &sched_ctrl->harq_processes[pid];
+ /* old feedbacks we missed: mark for retransmission */
+ while (harq->feedback_frame != frame
+ || (harq->feedback_frame == frame && harq->feedback_slot < slot)) {
+ LOG_W(MAC,
+ "expected HARQ pid %d feedback at %d.%d, but is at %d.%d instead (HARQ feedback is in the past)\n",
+ pid,
+ harq->feedback_frame,
+ harq->feedback_slot,
+ frame,
+ slot);
+ remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
+ handle_dl_harq(mod_id, UE_id, pid, 0);
+ pid = sched_ctrl->feedback_dl_harq.head;
+ if (pid < 0)
+ return NULL;
+ harq = &sched_ctrl->harq_processes[pid];
+ }
+ /* feedbacks that we wait for in the future: don't do anything */
+ if (harq->feedback_slot > slot) {
+ LOG_W(MAC,
+ "expected HARQ pid %d feedback at %d.%d, but is at %d.%d instead (HARQ feedback is in the future)\n",
+ pid,
+ harq->feedback_frame,
+ harq->feedback_slot,
+ frame,
+ slot);
+ return NULL;
+ }
+ return harq;
}
void handle_nr_uci_pucch_0_1(module_id_t mod_id,
@@ -968,6 +1011,7 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
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];
@@ -976,28 +1020,12 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id,
for (int harq_bit = 0; harq_bit < uci_01->harq->num_harq; harq_bit++) {
const uint8_t harq_value = uci_01->harq->harq_list[harq_bit].harq_value;
const uint8_t harq_confidence = uci_01->harq->harq_confidence_level;
- const int feedback_slot = (slot - 1 + num_slots) % num_slots;
- /* In case of realtime problems: we can only identify a HARQ process by
- * timing. If the HARQ process's feedback_slot is not the one we
- * expected, we assume that processing has been aborted and we need to
- * skip this HARQ process, which is what happens in the loop below. If
- * you don't experience real-time problems, you might simply revert the
- * commit that introduced these changes. */
- int8_t pid = sched_ctrl->feedback_dl_harq.head;
- DevAssert(pid >= 0);
- while (sched_ctrl->harq_processes[pid].feedback_slot != feedback_slot) {
- LOG_W(MAC,
- "expected feedback slot %d, but found %d instead\n",
- sched_ctrl->harq_processes[pid].feedback_slot,
- feedback_slot);
- remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
- handle_dl_harq(mod_id, UE_id, pid, 0);
- pid = sched_ctrl->feedback_dl_harq.head;
- DevAssert(pid >= 0);
- }
- remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
- NR_UE_harq_t *harq = &sched_ctrl->harq_processes[pid];
+ NR_UE_harq_t *harq = find_harq(mod_id, frame, slot, UE_id);
+ if (!harq)
+ break;
DevAssert(harq->is_waiting);
+ const int8_t pid = sched_ctrl->feedback_dl_harq.head;
+ remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
handle_dl_harq(mod_id, UE_id, pid, harq_value == 1 && harq_confidence == 0);
}
}
@@ -1021,6 +1049,7 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
sched_ctrl->tpc1 = nr_get_tpc(RC.nrmac[mod_id]->pucch_target_snrx10,
uci_234->ul_cqi,
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];
@@ -1028,28 +1057,12 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id,
// iterate over received harq bits
for (int harq_bit = 0; harq_bit < uci_234->harq.harq_bit_len; harq_bit++) {
const int acknack = ((uci_234->harq.harq_payload[harq_bit >> 3]) >> harq_bit) & 0x01;
- const int feedback_slot = (slot - 1 + num_slots) % num_slots;
- /* In case of realtime problems: we can only identify a HARQ process by
- * timing. If the HARQ process's feedback_slot is not the one we
- * expected, we assume that processing has been aborted and we need to
- * skip this HARQ process, which is what happens in the loop below. If
- * you don't experience real-time problems, you might simply revert the
- * commit that introduced these changes. */
- int8_t pid = sched_ctrl->feedback_dl_harq.head;
- DevAssert(pid >= 0);
- while (sched_ctrl->harq_processes[pid].feedback_slot != feedback_slot) {
- LOG_W(MAC,
- "expected feedback slot %d, but found %d instead\n",
- sched_ctrl->harq_processes[pid].feedback_slot,
- feedback_slot);
- remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
- handle_dl_harq(mod_id, UE_id, pid, 0);
- pid = sched_ctrl->feedback_dl_harq.head;
- DevAssert(pid >= 0);
- }
- remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
- NR_UE_harq_t *harq = &sched_ctrl->harq_processes[pid];
+ NR_UE_harq_t *harq = find_harq(mod_id, frame, slot, UE_id);
+ if (!harq)
+ break;
DevAssert(harq->is_waiting);
+ const int8_t pid = sched_ctrl->feedback_dl_harq.head;
+ remove_front_nr_list(&sched_ctrl->feedback_dl_harq);
handle_dl_harq(mod_id, UE_id, pid, uci_234->harq.harq_crc != 1 && acknack);
}
}
@@ -1218,6 +1231,29 @@ bool nr_acknack_scheduling(int mod_id,
// 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];
+ // 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
+ && csi_pucch->ul_slot == pucch->ul_slot) {
+ AssertFatal(!csi_pucch->simultaneous_harqcsi,
+ "%s(): %d.%d cannot handle simultaneous_harqcsi, but found for UE %d\n",
+ __func__,
+ pucch->frame,
+ pucch->ul_slot,
+ UE_id);
+ nr_fill_nfapi_pucch(mod_id, frame, slot, csi_pucch, UE_id);
+ /* advance the UL slot information in PUCCH by one so we won't schedule in
+ * the same slot again */
+ const int f = pucch->frame;
+ const int s = pucch->ul_slot;
+ memset(pucch, 0, sizeof(*pucch));
+ pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f;
+ pucch->ul_slot = (s + 1) % n_slots_frame;
+ return nr_acknack_scheduling(mod_id, UE_id, frame, slot);
+ }
+
// Find the right timing_indicator value.
int i = 0;
while (i < 8) {
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
index 9784b6b79e..a2e066d8c5 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
@@ -61,13 +61,124 @@ const uint32_t NR_LONG_BSR_TABLE[256] ={
35910462, 38241455, 40723756, 43367187, 46182206, 49179951, 52372284, 55771835, 59392055, 63247269, 67352729, 71724679, 76380419, 81338368, 162676736, 4294967295
};
-void nr_process_mac_pdu(
- module_id_t module_idP,
- rnti_t rnti,
- uint8_t CC_id,
- frame_t frameP,
- uint8_t *pduP,
- uint16_t mac_pdu_len)
+void calculate_preferred_ul_tda(module_id_t module_id, const NR_BWP_Uplink_t *ubwp)
+{
+ gNB_MAC_INST *nrmac = RC.nrmac[module_id];
+ const int bwp_id = ubwp->bwp_Id;
+ if (nrmac->preferred_ul_tda[bwp_id])
+ return;
+
+ /* there is a mixed slot only when in TDD */
+ const NR_ServingCellConfigCommon_t *scc = nrmac->common_channels->ServingCellConfigCommon;
+ const int mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing;
+ const NR_TDD_UL_DL_Pattern_t *tdd =
+ scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
+ /* Uplink symbols are at the end of the slot */
+ const int symb_ulMixed = tdd ? ((1 << tdd->nrofUplinkSymbols) - 1) << (14 - tdd->nrofUplinkSymbols) : 0;
+
+ const struct NR_PUCCH_Config__resourceToAddModList *resList = ubwp->bwp_Dedicated->pucch_Config->choice.setup->resourceToAddModList;
+ // for the moment, just block any symbol that might hold a PUCCH, regardless
+ // of the RB. This is a big simplification, as most RBs will NOT have a PUCCH
+ // in the respective symbols, but it simplifies scheduling
+ uint16_t symb_pucch = 0;
+ for (int i = 0; i < resList->list.count; ++i) {
+ const NR_PUCCH_Resource_t *resource = resList->list.array[i];
+ int nrofSymbols = 0;
+ int startingSymbolIndex = 0;
+ switch (resource->format.present) {
+ case NR_PUCCH_Resource__format_PR_format0:
+ nrofSymbols = resource->format.choice.format0->nrofSymbols;
+ startingSymbolIndex = resource->format.choice.format0->startingSymbolIndex;
+ break;
+ case NR_PUCCH_Resource__format_PR_format1:
+ nrofSymbols = resource->format.choice.format1->nrofSymbols;
+ startingSymbolIndex = resource->format.choice.format1->startingSymbolIndex;
+ break;
+ case NR_PUCCH_Resource__format_PR_format2:
+ nrofSymbols = resource->format.choice.format2->nrofSymbols;
+ startingSymbolIndex = resource->format.choice.format2->startingSymbolIndex;
+ break;
+ case NR_PUCCH_Resource__format_PR_format3:
+ nrofSymbols = resource->format.choice.format3->nrofSymbols;
+ startingSymbolIndex = resource->format.choice.format3->startingSymbolIndex;
+ break;
+ case NR_PUCCH_Resource__format_PR_format4:
+ nrofSymbols = resource->format.choice.format4->nrofSymbols;
+ startingSymbolIndex = resource->format.choice.format4->startingSymbolIndex;
+ break;
+ default:
+ AssertFatal(0, "found NR_PUCCH format index %d\n", resource->format.present);
+ break;
+ }
+ symb_pucch |= ((1 << nrofSymbols) - 1) << startingSymbolIndex;
+ }
+
+ /* check that TDA index 1 fits into UL slot and does not overlap with PUCCH */
+ const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
+ AssertFatal(tdaList->list.count >= 3, "need to have at least three TDAs for UL slots\n");
+ const NR_PUSCH_TimeDomainResourceAllocation_t *tdaP_UL = tdaList->list.array[0];
+ const int k2 = get_K2(ubwp, /* tda = */ 0, mu);
+ int start, len;
+ SLIV2SL(tdaP_UL->startSymbolAndLength, &start, &len);
+ const uint16_t symb_tda = ((1 << len) - 1) << start;
+ // check whether PUCCH and TDA overlap: then, we cannot use it. Note that
+ // here we assume that the PUCCH is scheduled in every slot, and on all RBs
+ // (which is mostly not true, this is a simplification)
+ AssertFatal((symb_pucch & symb_tda) == 0, "TDA index 0 for UL overlaps with PUCCH\n");
+
+ // get largest time domain allocation (TDA) for UL slot and UL in mixed slot
+ int tdaMi = -1;
+ const NR_PUSCH_TimeDomainResourceAllocation_t *tdaP_Mi = tdaList->list.array[1];
+ AssertFatal(k2 == get_K2(ubwp, /* tda = */ 1, mu),
+ "scheduler cannot handle different k2 for UL slot (%d) and UL Mixed slot (%ld)\n",
+ k2,
+ get_K2(ubwp, /* tda = */ 1, mu));
+ SLIV2SL(tdaP_Mi->startSymbolAndLength, &start, &len);
+ const uint16_t symb_tda_mi = ((1 << len) - 1) << start;
+ // check whether PUCCH and TDA overlap: then, we cannot use it. Also, check
+ // whether TDA is entirely within mixed slot, UL. Note that here we assume
+ // that the PUCCH is scheduled in every slot, and on all RBs (which is
+ // mostly not true, this is a simplification)
+ if ((symb_pucch & symb_tda_mi) == 0 && (symb_ulMixed & symb_tda_mi) == symb_tda_mi) {
+ tdaMi = 1;
+ } else {
+ LOG_E(MAC,
+ "TDA index 1 UL overlaps with PUCCH or is not entirely in mixed slot (symb_pucch %x symb_ulMixed %x symb_tda_mi %x), won't schedule UL mixed slot\n",
+ symb_pucch,
+ symb_ulMixed,
+ symb_tda_mi);
+ }
+
+ const uint8_t slots_per_frame[5] = {10, 20, 40, 80, 160};
+ const int n = slots_per_frame[*scc->ssbSubcarrierSpacing];
+ nrmac->preferred_ul_tda[bwp_id] = malloc(n * sizeof(*nrmac->preferred_ul_tda[bwp_id]));
+
+ const int nr_mix_slots = tdd ? tdd->nrofDownlinkSymbols != 0 || tdd->nrofUplinkSymbols != 0 : 0;
+ const int nr_slots_period = tdd ? tdd->nrofDownlinkSlots + tdd->nrofUplinkSlots + nr_mix_slots : n;
+ for (int slot = 0; slot < n; ++slot) {
+ const int sched_slot = (slot + k2) % n;
+ nrmac->preferred_ul_tda[bwp_id][slot] = -1;
+ if (!tdd || sched_slot % nr_slots_period >= tdd->nrofDownlinkSlots + nr_mix_slots)
+ nrmac->preferred_ul_tda[bwp_id][slot] = 0;
+ else if (tdd && nr_mix_slots && sched_slot % nr_slots_period == tdd->nrofDownlinkSlots)
+ nrmac->preferred_ul_tda[bwp_id][slot] = tdaMi;
+ LOG_I(MAC, "DL slot %d UL slot %d preferred_ul_tda %d\n", slot, sched_slot, nrmac->preferred_ul_tda[bwp_id][slot]);
+ }
+
+ if (k2 < tdd->nrofUplinkSlots)
+ LOG_W(MAC,
+ "k2 %d < tdd->nrofUplinkSlots %ld: not all UL slots can be scheduled\n",
+ k2,
+ tdd->nrofUplinkSlots);
+}
+
+void nr_process_mac_pdu(module_id_t module_idP,
+ int UE_id,
+ uint8_t CC_id,
+ frame_t frameP,
+ sub_frame_t slot,
+ uint8_t *pduP,
+ uint16_t mac_pdu_len)
{
// This function is adapting code from the old
@@ -79,11 +190,6 @@ void nr_process_mac_pdu(
NR_UE_info_t *UE_info = &RC.nrmac[module_idP]->UE_info;
- int UE_id = find_nr_UE_id(module_idP, rnti);
- if (UE_id == -1) {
- LOG_E(MAC, "%s() UE_id == -1\n",__func__);
- return;
- }
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
// For both DL/UL-SCH
// Except:
@@ -145,12 +251,15 @@ void nr_process_mac_pdu(
NR_BSR_SHORT *bsr_s = (NR_BSR_SHORT *) ce_ptr;
sched_ctrl->estimated_ul_buffer = 0;
sched_ctrl->estimated_ul_buffer = NR_SHORT_BSR_TABLE[bsr_s->Buffer_size];
- LOG_D(MAC, "SHORT BSR, LCG ID %d, BS Index %d, BS value < %d, est buf %d\n",
+ LOG_D(MAC,
+ "SHORT BSR at %4d.%2d, LCG ID %d, BS Index %d, BS value < %d, est buf %d\n",
+ frameP,
+ slot,
bsr_s->LcgID,
bsr_s->Buffer_size,
NR_SHORT_BSR_TABLE[bsr_s->Buffer_size],
sched_ctrl->estimated_ul_buffer);
- break;
+ break;
case UL_SCH_LCID_L_BSR:
case UL_SCH_LCID_L_TRUNCATED_BSR:
@@ -170,16 +279,18 @@ void nr_process_mac_pdu(
n_Lcg = bsr_l->LcgID7 + bsr_l->LcgID6 + bsr_l->LcgID5 + bsr_l->LcgID4 +
bsr_l->LcgID3 + bsr_l->LcgID2 + bsr_l->LcgID1 + bsr_l->LcgID0;
- LOG_D(MAC, "LONG BSR, LCG ID(7-0) %d/%d/%d/%d/%d/%d/%d/%d\n",
- bsr_l->LcgID7, bsr_l->LcgID6, bsr_l->LcgID5, bsr_l->LcgID4,
- bsr_l->LcgID3, bsr_l->LcgID2, bsr_l->LcgID1, bsr_l->LcgID0);
-
for (int n = 0; n < n_Lcg; n++){
- LOG_D(MAC, "LONG BSR, %d/%d (n/n_Lcg), BS Index %d, BS value < %d",
- n, n_Lcg, pdu_ptr[mac_subheader_len + 1 + n],
- NR_LONG_BSR_TABLE[pdu_ptr[mac_subheader_len + 1 + n]]);
sched_ctrl->estimated_ul_buffer +=
NR_LONG_BSR_TABLE[pdu_ptr[mac_subheader_len + 1 + n]];
+ LOG_D(MAC,
+ "LONG BSR at %4d.%2d, %d/%d (n/n_Lcg), BS Index %d, BS value < %d, total %d\n",
+ frameP,
+ slot,
+ n,
+ n_Lcg,
+ pdu_ptr[mac_subheader_len + 1 + n],
+ NR_LONG_BSR_TABLE[pdu_ptr[mac_subheader_len + 1 + n]],
+ sched_ctrl->estimated_ul_buffer);
}
break;
@@ -196,6 +307,20 @@ void nr_process_mac_pdu(
//fixed length
mac_ce_len = 2;
/* Extract SINGLE ENTRY PHR elements for PHR calculation */
+ ce_ptr = &pdu_ptr[mac_subheader_len];
+ NR_SINGLE_ENTRY_PHR_MAC_CE *phr = (NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr;
+ /* Save the phr info */
+ const int PH = phr->PH;
+ const int PCMAX = phr->PCMAX;
+ /* 38.133 Table10.1.17.1-1 */
+ if (PH < 55)
+ sched_ctrl->ph = PH - 32;
+ else
+ sched_ctrl->ph = PH - 32 + (PH - 54);
+ /* 38.133 Table10.1.18.1-1 */
+ sched_ctrl->pcmax = PCMAX - 29;
+ LOG_D(MAC, "SINGLE ENTRY PHR R1 %d PH %d (%d dB) R2 %d PCMAX %d (%d dBm)\n",
+ phr->R1, PH, sched_ctrl->ph, phr->R2, PCMAX, sched_ctrl->pcmax);
break;
case UL_SCH_LCID_MULTI_ENTRY_PHR_1_OCT:
@@ -237,57 +362,91 @@ void nr_process_mac_pdu(
case UL_SCH_LCID_SRB3:
// todo
break;
- case UL_SCH_LCID_CCCH_MSG3:
- // todo
- break;
+
case UL_SCH_LCID_CCCH:
- // todo
- mac_subheader_len = 2;
+ case UL_SCH_LCID_CCCH1:
+ // fixed length
+ mac_subheader_len = 1;
+
+ if ( rx_lcid == UL_SCH_LCID_CCCH1 ) {
+ // RRCResumeRequest1 message includes the full I-RNTI and has a size of 8 bytes
+ mac_sdu_len = 8;
+
+ // Check if it is a valid CCCH1 message, we get all 00's messages very often
+ int i = 0;
+ for(i=0; i<(mac_subheader_len+mac_sdu_len); i++) {
+ if(pdu_ptr[i] != 0) {
+ break;
+ }
+ }
+ if (i == (mac_subheader_len+mac_sdu_len)) {
+ LOG_D(NR_MAC, "%s() Invalid CCCH1 message!, pdu_len: %d\n", __func__, pdu_len);
+ done = 1;
break;
+ }
+ } else {
+ // fixed length of 6 bytes
+ mac_sdu_len = 6;
+ }
+
+ nr_mac_rrc_data_ind(module_idP,
+ CC_id,
+ frameP,
+ 0,
+ 0,
+ UE_info->rnti[UE_id],
+ CCCH,
+ pdu_ptr+mac_subheader_len,
+ mac_sdu_len,
+ 0);
+ break;
case UL_SCH_LCID_DTCH:
- // check if LCID is valid at current time.
- if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){
- //mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8;
- mac_subheader_len = 3;
- mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *) pdu_ptr)->L1 & 0x7f) << 8)
- | ((uint16_t)((NR_MAC_SUBHEADER_LONG *) pdu_ptr)->L2 & 0xff);
+ // check if LCID is valid at current time.
+ if (((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F) {
+ // mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2)<<8;
+ mac_subheader_len = 3;
+ mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L1 & 0x7f) << 8)
+ | ((uint16_t)((NR_MAC_SUBHEADER_LONG *)pdu_ptr)->L2 & 0xff);
- } else {
- mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L;
- mac_subheader_len = 2;
- }
+ } else {
+ mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L;
+ mac_subheader_len = 2;
+ }
- LOG_D(MAC, "[UE %d] Frame %d : ULSCH -> UL-DTCH %d (gNB %d, %d bytes)\n", module_idP, frameP, rx_lcid, module_idP, mac_sdu_len);
- int UE_id = find_nr_UE_id(module_idP, rnti);
- RC.nrmac[module_idP]->UE_info.mac_stats[UE_id].lc_bytes_rx[rx_lcid] += mac_sdu_len;
- #if defined(ENABLE_MAC_PAYLOAD_DEBUG)
- log_dump(MAC, pdu_ptr + mac_subheader_len, 32, LOG_DUMP_CHAR, "\n");
+ LOG_D(MAC,
+ "[UE %d] Frame %d : ULSCH -> UL-DTCH %d (gNB %d, %d bytes)\n",
+ module_idP,
+ frameP,
+ rx_lcid,
+ module_idP,
+ mac_sdu_len);
+ UE_info->mac_stats[UE_id].lc_bytes_rx[rx_lcid] += mac_sdu_len;
+#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
+ log_dump(MAC, pdu_ptr + mac_subheader_len, 32, LOG_DUMP_CHAR, "\n");
+#endif
- #endif
+ mac_rlc_data_ind(module_idP,
+ UE_info->rnti[UE_id],
+ module_idP,
+ frameP,
+ ENB_FLAG_YES,
+ MBMS_FLAG_NO,
+ rx_lcid,
+ (char *)(pdu_ptr + mac_subheader_len),
+ mac_sdu_len,
+ 1,
+ NULL);
- mac_rlc_data_ind(module_idP,
- rnti,
- module_idP,
- frameP,
- ENB_FLAG_YES,
- MBMS_FLAG_NO,
- rx_lcid,
- (char *) (pdu_ptr + mac_subheader_len),
- mac_sdu_len,
- 1,
- NULL);
-
- /* Updated estimated buffer when receiving data */
- if (sched_ctrl->estimated_ul_buffer >= mac_sdu_len)
- sched_ctrl->estimated_ul_buffer -= mac_sdu_len;
- else
- sched_ctrl->estimated_ul_buffer = 0;
-
- break;
+ /* Updated estimated buffer when receiving data */
+ if (sched_ctrl->estimated_ul_buffer >= mac_sdu_len)
+ sched_ctrl->estimated_ul_buffer -= mac_sdu_len;
+ else
+ sched_ctrl->estimated_ul_buffer = 0;
+ break;
default:
- LOG_D(MAC, "Received unknown MAC header (LCID = 0x%02x)\n", rx_lcid);
+ LOG_E(MAC, "Received unknown MAC header (LCID = 0x%02x)\n", rx_lcid);
return;
break;
}
@@ -305,6 +464,24 @@ void nr_process_mac_pdu(
}
}
+void abort_nr_ul_harq(module_id_t mod_id, int UE_id, int8_t harq_pid)
+{
+ 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];
+ NR_UE_ul_harq_t *harq = &sched_ctrl->ul_harq_processes[harq_pid];
+
+ harq->ndi ^= 1;
+ harq->round = 0;
+ UE_info->mac_stats[UE_id].ulsch_errors++;
+ add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_pid);
+
+ /* the transmission failed: the UE won't send the data we expected initially,
+ * so retrieve to correctly schedule after next BSR */
+ sched_ctrl->sched_ul_bytes -= harq->sched_pusch.tb_size;
+ if (sched_ctrl->sched_ul_bytes < 0)
+ sched_ctrl->sched_ul_bytes = 0;
+}
+
void handle_nr_ul_harq(module_id_t mod_id,
frame_t frame,
sub_frame_t slot,
@@ -329,8 +506,13 @@ void handle_nr_ul_harq(module_id_t mod_id,
return;
remove_front_nr_list(&sched_ctrl->feedback_ul_harq);
- sched_ctrl->ul_harq_processes[harq_pid].round++;
- add_tail_nr_list(&sched_ctrl->retrans_ul_harq, harq_pid);
+ sched_ctrl->ul_harq_processes[harq_pid].is_waiting = false;
+ if(sched_ctrl->ul_harq_processes[harq_pid].round >= MAX_HARQ_ROUNDS - 1) {
+ abort_nr_ul_harq(mod_id, UE_id, harq_pid);
+ } else {
+ sched_ctrl->ul_harq_processes[harq_pid].round++;
+ add_tail_nr_list(&sched_ctrl->retrans_ul_harq, harq_pid);
+ }
harq_pid = sched_ctrl->feedback_ul_harq.head;
}
remove_front_nr_list(&sched_ctrl->feedback_ul_harq);
@@ -346,15 +528,12 @@ void handle_nr_ul_harq(module_id_t mod_id,
harq_pid,
crc_pdu->rnti);
add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_pid);
- } else if (harq->round == MAX_HARQ_ROUNDS) {
- harq->ndi ^= 1;
- harq->round = 0;
+ } else if (harq->round >= MAX_HARQ_ROUNDS - 1) {
+ abort_nr_ul_harq(mod_id, UE_id, harq_pid);
LOG_D(MAC,
"RNTI %04x: Ulharq id %d crc failed in all rounds\n",
crc_pdu->rnti,
harq_pid);
- UE_info->mac_stats[UE_id].ulsch_errors++;
- add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_pid);
} else {
harq->round++;
LOG_D(MAC,
@@ -407,11 +586,12 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
sduP);
// if not missed detection (10dB threshold for now)
- if (UE_scheduling_control->ul_rssi < (100+rssi)) {
+ if (UE_scheduling_control->raw_rssi < 100 + rssi) {
UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10,ul_cqi,30);
if (timing_advance != 0xffff)
UE_scheduling_control->ta_update = timing_advance;
- UE_scheduling_control->ul_rssi = rssi;
+ UE_scheduling_control->raw_rssi = rssi;
+ UE_scheduling_control->pusch_snrx10 = ul_cqi * 5 - 640;
LOG_D(NR_MAC, "[UE %d] PUSCH TPC %d and TA %d\n",UE_id,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update);
}
else{
@@ -438,21 +618,21 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
if (UE_scheduling_control->sched_ul_bytes < 0)
UE_scheduling_control->sched_ul_bytes = 0;
- nr_process_mac_pdu(gnb_mod_idP, current_rnti, CC_idP, frameP, sduP, sdu_lenP);
+ nr_process_mac_pdu(gnb_mod_idP, UE_id, CC_idP, frameP, slotP, sduP, sdu_lenP);
}
- else {
- NR_UE_ul_harq_t *cur_harq = &UE_scheduling_control->ul_harq_processes[harq_pid];
- /* reduce sched_ul_bytes when cur_harq->round == 3 */
- if (cur_harq->round == 3){
- const uint32_t tb_size = UE_scheduling_control->ul_harq_processes[harq_pid].sched_pusch.tb_size;
- UE_scheduling_control->sched_ul_bytes -= tb_size;
- if (UE_scheduling_control->sched_ul_bytes < 0)
- UE_scheduling_control->sched_ul_bytes = 0;
+ } else if(sduP) {
+
+ bool no_sig = true;
+ for (int k = 0; k < sdu_lenP; k++) {
+ if(sduP[k]!=0) {
+ no_sig = false;
+ break;
}
}
- } else {
- if (!sduP) // check that CRC passed
- return;
+
+ if(no_sig) {
+ LOG_W(NR_MAC, "No signal\n");
+ }
T(T_GNB_MAC_UL_PDU_WITH_DATA, T_INT(gnb_mod_idP), T_INT(CC_idP),
T_INT(rntiP), T_INT(frameP), T_INT(slotP), T_INT(-1) /* harq_pid */,
@@ -466,45 +646,93 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
if (ra->state != WAIT_Msg3)
continue;
- // random access pusch with TC-RNTI
- if (ra->rnti != current_rnti) {
- LOG_W(NR_MAC,
- "expected TC-RNTI %04x to match current RNTI %04x\n",
+ if(no_sig) {
+ LOG_W(NR_MAC, "Random Access %i failed at state %i\n", i, ra->state);
+ nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti);
+ nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
+ } else {
+
+ // random access pusch with TC-RNTI
+ if (ra->rnti != current_rnti) {
+ LOG_W(NR_MAC,
+ "expected TC_RNTI %04x to match current RNTI %04x\n",
+ ra->rnti,
+ current_rnti);
+
+ if( (frameP==ra->Msg3_frame) && (slotP==ra->Msg3_slot) ) {
+ LOG_W(NR_MAC, "Random Access %i failed at state %i\n", i, ra->state);
+ nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti);
+ nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
+ }
+
+ continue;
+ }
+
+ const int UE_id = add_new_nr_ue(gnb_mod_idP, ra->rnti, ra->secondaryCellGroup);
+ UE_info->UE_beam_index[UE_id] = ra->beam_id;
+
+ // re-initialize ta update variables after RA procedure completion
+ UE_info->UE_sched_ctrl[UE_id].ta_frame = frameP;
+
+ LOG_I(NR_MAC,
+ "reset RA state information for RA-RNTI %04x/index %d\n",
ra->rnti,
- current_rnti);
+ i);
+
+ LOG_I(NR_MAC,
+ "[gNB %d][RAPROC] PUSCH with TC_RNTI %x received correctly, "
+ "adding UE MAC Context UE_id %d/RNTI %04x\n",
+ gnb_mod_idP,
+ current_rnti,
+ UE_id,
+ ra->rnti);
+
+ if(ra->cfra) {
+
+ LOG_I(NR_MAC, "(ue %i, rnti 0x%04x) CFRA procedure succeeded!\n", UE_id, ra->rnti);
+ nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti);
+ nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
+ UE_info->active[UE_id] = true;
+
+ } else {
+
+ LOG_I(NR_MAC,"[RAPROC] RA-Msg3 received (sdu_lenP %d)\n",sdu_lenP);
+ LOG_D(NR_MAC,"[RAPROC] Received Msg3:\n");
+ for (int k = 0; k < sdu_lenP; k++) {
+ LOG_D(NR_MAC,"(%i): 0x%x\n",k,sduP[k]);
+ }
+
+ // UE Contention Resolution Identity
+ // Store the first 48 bits belonging to the uplink CCCH SDU within Msg3 to fill in Msg4
+ // First byte corresponds to R/LCID MAC sub-header
+ memcpy(ra->cont_res_id, &sduP[1], sizeof(uint8_t) * 6);
+
+ nr_process_mac_pdu(gnb_mod_idP, UE_id, CC_idP, frameP, slotP, sduP, sdu_lenP);
+
+ ra->state = Msg4;
+ ra->Msg4_frame = ( frameP +2 ) % 1024;
+ ra->Msg4_slot = 1;
+ LOG_I(NR_MAC, "Scheduling RA-Msg4 for TC_RNTI %04x (state %d, frame %d, slot %d)\n", ra->rnti, ra->state, ra->Msg4_frame, ra->Msg4_slot);
+
+ }
+ return;
+
+ }
+ }
+ } else {
+ for (int i = 0; i < NR_NB_RA_PROC_MAX; ++i) {
+ NR_RA_t *ra = &gNB_mac->common_channels[CC_idP].ra[i];
+ if (ra->state != WAIT_Msg3)
continue;
- }
- const int UE_id = add_new_nr_ue(gnb_mod_idP, ra->rnti, ra->secondaryCellGroup);
- UE_info->UE_beam_index[UE_id] = ra->beam_id;
- LOG_I(NR_MAC,
- "[gNB %d][RAPROC] PUSCH with TC_RNTI %x received correctly, "
- "adding UE MAC Context UE_id %d/RNTI %04x\n",
- gnb_mod_idP,
- current_rnti,
- UE_id,
- ra->rnti);
- LOG_D(NR_MAC,"[RAPROC] Received Msg3:\n");
- for (int k = 0; k < sdu_lenP; k++) {
- LOG_D(NR_MAC,"(%i): 0x%x\n",k,sduP[k]);
- }
-
- // re-initialize ta update variables afrer RA procedure completion
- UE_info->UE_sched_ctrl[UE_id].ta_frame = frameP;
-
- free(ra->preambles.preamble_list);
- ra->state = RA_IDLE;
- LOG_I(NR_MAC,
- "reset RA state information for RA-RNTI %04x/index %d\n",
- ra->rnti,
- i);
-
- return;
+ LOG_W(NR_MAC, "Random Access %i failed at state %i\n", i, ra->state);
+ nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti);
+ nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra);
}
}
}
-long get_K2(NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu) {
+long get_K2(const NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu) {
DevAssert(ubwp);
const NR_PUSCH_TimeDomainResourceAllocation_t *tda_list = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment];
if (tda_list->k2)
@@ -524,21 +752,142 @@ int next_list_entry_looped(NR_list_t *list, int UE_id)
return list->next[UE_id] < 0 ? list->head : list->next[UE_id];
}
+bool allocate_ul_retransmission(module_id_t module_id,
+ frame_t frame,
+ sub_frame_t slot,
+ uint8_t *rballoc_mask,
+ int *n_rb_sched,
+ int UE_id,
+ int harq_pid)
+{
+ const int CC_id = 0;
+ const NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[CC_id].ServingCellConfigCommon;
+ NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
+ NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
+ NR_sched_pusch_t *retInfo = &sched_ctrl->ul_harq_processes[harq_pid].sched_pusch;
+ int rbStart =
+ NRRIV2PRBOFFSET(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+ const uint16_t bwpSize =
+ NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+
+ const uint8_t num_dmrs_cdm_grps_no_data = 1;
+ const int tda = RC.nrmac[module_id]->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot];
+ if (tda == retInfo->time_domain_allocation) {
+ /* Check the resource is enough for retransmission */
+ while (rbStart < bwpSize && !rballoc_mask[rbStart])
+ rbStart++;
+ if (rbStart + retInfo->rbSize >= bwpSize) {
+ LOG_D(MAC, "cannot allocate retransmission of UE %d/RNTI %04x: no resources\n", UE_id, UE_info->rnti[UE_id]);
+ return false;
+ }
+ /* check whether we need to switch the TDA allocation since tha last
+ * (re-)transmission */
+ NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static;
+ const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats;
+ const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0;
+ if (ps->time_domain_allocation != tda
+ || ps->dci_format != dci_format
+ || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data)
+ nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, dci_format, tda, num_dmrs_cdm_grps_no_data, ps);
+ LOG_D(MAC, "%s(): retransmission keeping TDA %d and TBS %d\n", __func__, tda, retInfo->tb_size);
+ } else {
+ /* the retransmission will use a different time domain allocation, check
+ * that we have enough resources */
+ while (rbStart < bwpSize && !rballoc_mask[rbStart])
+ rbStart++;
+ int rbSize = 0;
+ while (rbStart + rbSize < bwpSize && rballoc_mask[rbStart + rbSize])
+ rbSize++;
+ NR_pusch_semi_static_t temp_ps;
+ const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats;
+ const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0;
+ nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, dci_format, tda, num_dmrs_cdm_grps_no_data, &temp_ps);
+ uint32_t new_tbs;
+ uint16_t new_rbSize;
+ bool success = nr_find_nb_rb(retInfo->Qm,
+ retInfo->R,
+ temp_ps.nrOfSymbols,
+ temp_ps.N_PRB_DMRS * temp_ps.num_dmrs_symb,
+ retInfo->tb_size,
+ rbSize,
+ &new_tbs,
+ &new_rbSize);
+ if (!success || new_tbs != retInfo->tb_size) {
+ LOG_D(MAC, "%s(): new TBsize %d of new TDA does not match old TBS %d\n", __func__, new_tbs, retInfo->tb_size);
+ return false; /* the maximum TBsize we might have is smaller than what we need */
+ }
+ LOG_D(MAC, "%s(): retransmission with TDA %d->%d and TBS %d -> %d\n", __func__, retInfo->time_domain_allocation, tda, retInfo->tb_size, new_tbs);
+ /* we can allocate it. Overwrite the time_domain_allocation, the number
+ * of RBs, and the new TB size. The rest is done below */
+ retInfo->tb_size = new_tbs;
+ retInfo->rbSize = new_rbSize;
+ retInfo->time_domain_allocation = tda;
+ sched_ctrl->pusch_semi_static = temp_ps;
+ }
+
+ /* Find free CCE */
+ bool freeCCE = find_free_CCE(module_id, slot, UE_id);
+ if (!freeCCE) {
+ LOG_D(MAC, "%4d.%2d no free CCE for retransmission UL DCI UE %04x\n", frame, slot, UE_info->rnti[UE_id]);
+ return false;
+ }
+
+ /* frame/slot in sched_pusch has been set previously. In the following, we
+ * overwrite the information in the retransmission information before storing
+ * as the new scheduling instruction */
+ retInfo->frame = sched_ctrl->sched_pusch.frame;
+ retInfo->slot = sched_ctrl->sched_pusch.slot;
+ /* Get previous PSUCH field info */
+ sched_ctrl->sched_pusch = *retInfo;
+ NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
+ LOG_D(MAC,
+ "%4d.%2d Allocate UL retransmission UE %d/RNTI %04x sched %4d.%2d (%d RBs)\n",
+ frame,
+ slot,
+ UE_id,
+ UE_info->rnti[UE_id],
+ sched_pusch->frame,
+ sched_pusch->slot,
+ sched_pusch->rbSize);
+
+ sched_pusch->rbStart = rbStart;
+ /* no need to recompute the TBS, it will be the same */
+
+ /* Mark the corresponding RBs as used */
+ n_rb_sched -= sched_pusch->rbSize;
+ for (int rb = 0; rb < sched_ctrl->sched_pusch.rbSize; rb++)
+ rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] = 0;
+ return true;
+}
+
+void update_ul_ue_R_Qm(NR_sched_pusch_t *sched_pusch, const NR_pusch_semi_static_t *ps)
+{
+ const int mcs = sched_pusch->mcs;
+ sched_pusch->R = nr_get_code_rate_ul(mcs, ps->mcs_table);
+ sched_pusch->Qm = nr_get_Qm_ul(mcs, ps->mcs_table);
+ if (ps->pusch_Config->tp_pi2BPSK
+ && ((ps->mcs_table == 3 && mcs < 2) || (ps->mcs_table == 4 && mcs < 6))) {
+ sched_pusch->R >>= 1;
+ sched_pusch->Qm <<= 1;
+ }
+}
+
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,
- int num_slots_per_tdd,
NR_list_t *UE_list,
+ int max_num_ue,
int n_rb_sched,
- uint8_t *rballoc_mask,
- int max_num_ue) {
+ uint8_t *rballoc_mask) {
const int CC_id = 0;
- const int tda = 1;
- NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[CC_id].ServingCellConfigCommon;
- NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
+ const uint8_t num_dmrs_cdm_grps_no_data = 1;
+ gNB_MAC_INST *nrmac = RC.nrmac[module_id];
+ NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon;
+ NR_UE_info_t *UE_info = &nrmac->UE_info;
const int min_rb = 5;
float coeff_ue[MAX_MOBILES_PER_GNB];
// UEs that could be scheduled
@@ -554,86 +903,34 @@ void pf_ul(module_id_t module_id,
/* 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];
- int rbStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+ int rbStart =
+ NRRIV2PRBOFFSET(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+ NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
+ NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static;
/* Calculate throughput */
const float a = 0.0005f; // corresponds to 200ms window
const uint32_t b = UE_info->mac_stats[UE_id].ulsch_current_bytes;
ul_thr_ue[UE_id] = (1 - a) * ul_thr_ue[UE_id] + a * b;
- /* Save PUSCH field */
- /* we want to avoid a lengthy deduction of DMRS and other parameters in
- * every TTI if we can save it, so check whether dci_format, TDA, or
- * num_dmrs_cdm_grps_no_data has changed and only then recompute */
- sched_ctrl->sched_pusch.time_domain_allocation = tda;
- sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, NR_SearchSpace__searchSpaceType_PR_ue_Specific);
- sched_ctrl->coreset = get_coreset(sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */);
- const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats;
- const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0;
- const uint8_t num_dmrs_cdm_grps_no_data = 1;
- NR_sched_pusch_save_t *ps = &sched_ctrl->pusch_save;
- if (ps->time_domain_allocation != tda
- || ps->dci_format != dci_format
- || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data)
- nr_save_pusch_fields(scc, sched_ctrl->active_ubwp, dci_format, tda, num_dmrs_cdm_grps_no_data, ps);
-
/* Check if retransmission is necessary */
- sched_ctrl->sched_pusch.ul_harq_pid = sched_ctrl->retrans_ul_harq.head;
- if (sched_ctrl->sched_pusch.ul_harq_pid >= 0) {
- /* RETRANSMISSION: Allocate retransmission*/
- /* Find free CCE */
- bool freeCCE = find_free_CCE(module_id, slot, UE_id);
- if (!freeCCE) {
- LOG_D(MAC, "%4d.%2d no free CCE for retransmission UL DCI UE %04x\n", frame, slot, UE_info->rnti[UE_id]);
+ sched_pusch->ul_harq_pid = sched_ctrl->retrans_ul_harq.head;
+ if (sched_pusch->ul_harq_pid >= 0) {
+ /* Allocate retransmission*/
+ bool r = allocate_ul_retransmission(
+ module_id, frame, slot, rballoc_mask, &n_rb_sched, UE_id, sched_pusch->ul_harq_pid);
+ if (!r) {
+ LOG_D(MAC, "%4d.%2d UL retransmission UE RNTI %04x can NOT be allocated\n", frame, slot, UE_info->rnti[UE_id]);
continue;
}
/* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
max_num_ue--;
if (max_num_ue < 0)
return;
-
- /* Save shced_frame and sched_slot before overwrite by previous PUSCH filed */
- NR_UE_ul_harq_t *cur_harq = &sched_ctrl->ul_harq_processes[sched_ctrl->sched_pusch.ul_harq_pid];
- cur_harq->sched_pusch.frame = sched_ctrl->sched_pusch.frame;
- cur_harq->sched_pusch.slot = sched_ctrl->sched_pusch.slot;
- /* Get previous PSUCH filed info */
- sched_ctrl->sched_pusch = cur_harq->sched_pusch;
- NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
- LOG_D(MAC, "%4d.%2d Allocate UL retransmission UE %d/RNTI %04x sched %4d.%2d (%d RBs)\n",
- frame, slot, UE_id, UE_info->rnti[UE_id],
- sched_pusch->frame, sched_pusch->slot,
- sched_pusch->rbSize);
-
- while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++;
- if (rbStart + sched_pusch->rbSize >= bwpSize) {
- LOG_W(MAC, "cannot allocate UL data for UE %d/RNTI %04x: no resources\n",
- UE_id, UE_info->rnti[UE_id]);
- return;
- }
- sched_pusch->rbStart = rbStart;
- /* no need to recompute the TBS, it will be the same */
-
- /* Mark the corresponding RBs as used */
- n_rb_sched -= sched_pusch->rbSize;
- for (int rb = 0; rb < sched_ctrl->sched_pusch.rbSize; rb++)
- rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] = 0;
-
continue;
}
- /* Calculate TBS from MCS */
- NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
- const int mcs = 9;
- sched_pusch->mcs = mcs;
- sched_pusch->R = nr_get_code_rate_ul(mcs, ps->mcs_table);
- sched_pusch->Qm = nr_get_Qm_ul(mcs, ps->mcs_table);
- if (ps->pusch_Config->tp_pi2BPSK
- && ((ps->mcs_table == 3 && mcs < 2) || (ps->mcs_table == 4 && mcs < 6))) {
- sched_pusch->R >>= 1;
- sched_pusch->Qm <<= 1;
- }
-
/* 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) {
@@ -652,10 +949,25 @@ void pf_ul(module_id_t module_id,
while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++;
if (rbStart + min_rb >= bwpSize) {
- LOG_W(MAC, "cannot allocate UL data for UE %d/RNTI %04x: no resources\n",
+ LOG_D(MAC, "cannot allocate continuous data for UE %d/RNTI %04x: no resources\n",
UE_id, UE_info->rnti[UE_id]);
- return;
+ continue;
}
+
+ /* Save PUSCH field */
+ /* we want to avoid a lengthy deduction of DMRS and other parameters in
+ * every TTI if we can save it, so check whether dci_format, TDA, or
+ * num_dmrs_cdm_grps_no_data has changed and only then recompute */
+ const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats;
+ const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0;
+ const int tda = nrmac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot];
+ if (ps->time_domain_allocation != tda
+ || ps->dci_format != dci_format
+ || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data)
+ nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, dci_format, tda, num_dmrs_cdm_grps_no_data, ps);
+ NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
+ sched_pusch->mcs = 9;
+ update_ul_ue_R_Qm(sched_pusch, ps);
sched_pusch->rbStart = rbStart;
sched_pusch->rbSize = min_rb;
sched_pusch->tb_size = nr_compute_tbs(sched_pusch->Qm,
@@ -680,15 +992,8 @@ void pf_ul(module_id_t module_id,
add_tail_nr_list(&UE_sched, UE_id);
/* Calculate coefficient*/
- const uint32_t tbs = nr_compute_tbs(sched_pusch->Qm,
- sched_pusch->R,
- 1, // rbSize
- ps->nrOfSymbols,
- ps->N_PRB_DMRS * ps->num_dmrs_symb,
- 0, // nb_rb_oh
- 0,
- 1 /* NrOfLayers */)
- >> 3;
+ sched_pusch->mcs = 9;
+ const uint32_t tbs = ul_pf_tbs[ps->mcs_table][sched_pusch->mcs];
coeff_ue[UE_id] = (float) tbs / ul_thr_ue[UE_id];
LOG_D(MAC,"b %d, ul_thr_ue[%d] %f, tbs %d, coeff_ue[%d] %f\n",
b, UE_id, ul_thr_ue[UE_id], tbs, UE_id, coeff_ue[UE_id]);
@@ -727,35 +1032,45 @@ void pf_ul(module_id_t module_id,
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
int rbStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
- const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+ /* for some reason, the UEs do not like when they are scheduled on the last
+ * RB. Hence, as a (hopefully temporary) fix, schedule one RB less. */
+ const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE) - 1;
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
-
+ NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static;
while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++;
sched_pusch->rbStart = rbStart;
- if (rbStart + min_rb >= bwpSize) {
- LOG_W(MAC, "cannot allocate UL data for UE %d/RNTI %04x: no resources\n",
- UE_id, UE_info->rnti[UE_id]);
- return;
- }
+ uint16_t max_rbSize = 1;
+ while (rbStart + max_rbSize < bwpSize && rballoc_mask[rbStart + max_rbSize])
+ max_rbSize++;
- /* Calculate the current scheduling bytes */
+ /* Save PUSCH field */
+ /* we want to avoid a lengthy deduction of DMRS and other parameters in
+ * every TTI if we can save it, so check whether dci_format, TDA, or
+ * num_dmrs_cdm_grps_no_data has changed and only then recompute */
+ const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats;
+ const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0;
+ const int tda = nrmac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot];
+ if (ps->time_domain_allocation != tda
+ || ps->dci_format != dci_format
+ || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data)
+ nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, dci_format, tda, num_dmrs_cdm_grps_no_data, ps);
+ update_ul_ue_R_Qm(sched_pusch, ps);
+
+ /* Calculate the current scheduling bytes and the necessary RBs */
const int B = cmax(sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes, 0);
- uint16_t rbSize = min_rb - 1;
- do {
- rbSize++;
- sched_pusch->rbSize = rbSize;
- sched_pusch->tb_size = nr_compute_tbs(sched_pusch->Qm,
- sched_pusch->R,
- sched_pusch->rbSize,
- sched_ctrl->pusch_save.nrOfSymbols,
- sched_ctrl->pusch_save.N_PRB_DMRS * sched_ctrl->pusch_save.num_dmrs_symb,
- 0, // nb_rb_oh
- 0,
- 1 /* NrOfLayers */)
- >> 3;
- } while (rbStart + rbSize < bwpSize && rballoc_mask[rbStart+rbSize] &&
- sched_pusch->tb_size < B);
+ uint16_t rbSize = 0;
+ uint32_t TBS = 0;
+ nr_find_nb_rb(sched_pusch->Qm,
+ sched_pusch->R,
+ ps->nrOfSymbols,
+ ps->N_PRB_DMRS * ps->num_dmrs_symb,
+ B,
+ max_rbSize,
+ &TBS,
+ &rbSize);
+ sched_pusch->rbSize = rbSize;
+ sched_pusch->tb_size = TBS;
LOG_D(MAC,"rbSize %d, TBS %d, est buf %d, sched_ul %d, B %d\n",
rbSize, sched_pusch->tb_size, sched_ctrl->estimated_ul_buffer, sched_ctrl->sched_ul_bytes, B);
@@ -766,11 +1081,8 @@ void pf_ul(module_id_t module_id,
}
}
-bool nr_simple_ulsch_preprocessor(module_id_t module_id,
- frame_t frame,
- sub_frame_t slot,
- int num_slots_per_tdd,
- uint64_t ulsch_in_slot_bitmap) {
+bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t slot)
+{
gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
NR_COMMON_channels_t *cc = nr_mac->common_channels;
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
@@ -782,45 +1094,47 @@ bool nr_simple_ulsch_preprocessor(module_id_t module_id,
const int CC_id = 0;
- /* NOT support different K2 in here, Get the K2 for first UE */
+ /* Get the K2 for first UE to compute offset. The other UEs are guaranteed to
+ * have the same K2 (we don't support multiple/different K2s via different
+ * TDAs yet). If the TDA is negative, it means that there is no UL slot to
+ * schedule now (slot + k2 is not UL slot) */
int UE_id = UE_info->list.head;
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
- const int tda = 1;
- const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList =
- sched_ctrl->active_ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
- AssertFatal(tda < tdaList->list.count,
- "time domain assignment %d >= %d\n",
- tda,
- tdaList->list.count);
-
+ const int tda = nr_mac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot];
+ if (tda < 0)
+ return false;
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(ulsch_in_slot_bitmap, sched_slot))
+ if (!is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[slot / 64], sched_slot))
return false;
sched_ctrl->sched_pusch.slot = sched_slot;
sched_ctrl->sched_pusch.frame = sched_frame;
-
- /* Confirm all the UE have same K2 as the first UE */
for (UE_id = UE_info->list.next[UE_id]; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) {
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
- AssertFatal(K2 == get_K2(sched_ctrl->active_ubwp, tda, mu),
- "Different K2, %d(UE%d) != %ld(UE%d)\n", K2, 0, get_K2(sched_ctrl->active_ubwp, tda, mu), UE_id);
sched_ctrl->sched_pusch.slot = sched_slot;
sched_ctrl->sched_pusch.frame = sched_frame;
}
- /* Change vrb_map_UL to rballoc_mask */
+ /* Change vrb_map_UL to rballoc_mask: check which symbols per RB (in
+ * vrb_map_UL) overlap with the "default" tda and exclude those RBs.
+ * Calculate largest contiguous RBs */
uint16_t *vrb_map_UL =
&RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[sched_slot * MAX_BWP_SIZE];
const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+ const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList =
+ sched_ctrl->active_ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList;
+ const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength;
+ int startSymbolIndex, nrOfSymbols;
+ SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
+ const uint16_t symb = ((1 << nrOfSymbols) - 1) << startSymbolIndex;
int st = 0, e = 0, len = 0;
for (int i = 0; i < bwpSize; i++) {
- while (vrb_map_UL[i] == 1)
+ while ((vrb_map_UL[i] & symb) != 0 && i < bwpSize)
i++;
st = i;
- while (vrb_map_UL[i] == 0)
+ while ((vrb_map_UL[i] & symb) == 0 && i < bwpSize)
i++;
if (i - st > len) {
len = i - st;
@@ -839,28 +1153,53 @@ bool nr_simple_ulsch_preprocessor(module_id_t module_id,
pf_ul(module_id,
frame,
slot,
- num_slots_per_tdd,
&UE_info->list,
+ 2,
len,
- rballoc_mask,
- 2);
+ rballoc_mask);
return true;
}
-void nr_schedule_ulsch(module_id_t module_id,
- frame_t frame,
- sub_frame_t slot,
- int num_slots_per_tdd,
- int ul_slots,
- uint64_t ulsch_in_slot_bitmap) {
+nr_pp_impl_ul nr_init_fr1_ulsch_preprocessor(module_id_t module_id, int CC_id)
+{
+ /* in the PF algorithm, we have to use the TBsize to compute the coefficient.
+ * This would include the number of DMRS symbols, which in turn depends on
+ * the time domain allocation. In case we are in a mixed slot, we do not want
+ * to recalculate all these values, and therefore we provide a look-up table
+ * which should approximately(!) give us the TBsize. In particular, the
+ * number of symbols, the number of DMRS symbols, and the exact Qm and R, are
+ * not correct*/
+ for (int mcsTableIdx = 0; mcsTableIdx < 3; ++mcsTableIdx) {
+ for (int mcs = 0; mcs < 29; ++mcs) {
+ if (mcs > 27 && mcsTableIdx == 1)
+ continue;
+ const uint8_t Qm = nr_get_Qm_dl(mcs, mcsTableIdx);
+ const uint16_t R = nr_get_code_rate_dl(mcs, mcsTableIdx);
+ /* note: we do not update R/Qm based on low MCS or pi2BPSK */
+ ul_pf_tbs[mcsTableIdx][mcs] = nr_compute_tbs(Qm,
+ R,
+ 1, /* rbSize */
+ 10, /* hypothetical number of slots */
+ 0, /* N_PRB_DMRS * N_DMRS_SLOT */
+ 0 /* N_PRB_oh, 0 for initialBWP */,
+ 0 /* tb_scaling */,
+ 1 /* nrOfLayers */)
+ >> 3;
+ }
+ }
+ return nr_fr1_ulsch_preprocessor;
+}
+
+void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot)
+{
+ gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
/* Uplink data ONLY can be scheduled when the current slot is downlink slot,
* because we have to schedule the DCI0 first before schedule uplink data */
- if (is_xlsch_in_slot(ulsch_in_slot_bitmap, slot)) {
+ if (!is_xlsch_in_slot(nr_mac->dlsch_slot_bitmap[slot / 64], slot)) {
LOG_D(MAC, "Current slot %d is NOT DL slot, cannot schedule DCI0 for UL data\n", slot);
return;
}
- bool do_sched = RC.nrmac[module_id]->pre_processor_ul(
- module_id, frame, slot, num_slots_per_tdd, ulsch_in_slot_bitmap);
+ bool do_sched = RC.nrmac[module_id]->pre_processor_ul(module_id, frame, slot);
if (!do_sched)
return;
@@ -915,8 +1254,8 @@ void nr_schedule_ulsch(module_id_t module_id,
/* pre-computed PUSCH values that only change if time domain allocation,
* DCI format, or DMRS parameters change. Updated in the preprocessor
- * through nr_save_pusch_fields() */
- NR_sched_pusch_save_t *ps = &sched_ctrl->pusch_save;
+ * through nr_set_pusch_semi_static() */
+ NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static;
/* Statistics */
UE_info->mac_stats[UE_id].ulsch_rounds[cur_harq->round]++;
@@ -925,6 +1264,9 @@ void nr_schedule_ulsch(module_id_t module_id,
/* Save information on MCS, TBS etc for the current initial transmission
* so we have access to it when retransmitting */
cur_harq->sched_pusch = *sched_pusch;
+ /* save which time allocation has been used, to be used on
+ * retransmissions */
+ cur_harq->sched_pusch.time_domain_allocation = ps->time_domain_allocation;
sched_ctrl->sched_ul_bytes += sched_pusch->tb_size;
} else {
LOG_D(MAC,
@@ -941,7 +1283,7 @@ void nr_schedule_ulsch(module_id_t module_id,
UE_info->mac_stats[UE_id].ulsch_current_bytes = sched_pusch->tb_size;
LOG_D(MAC,
- "%4d.%2d RNTI %04x UL sched %4d.%2d start %d RBS %d MCS %d TBS %d HARQ PID %d round %d NDI %d\n",
+ "%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",
frame,
slot,
rnti,
@@ -949,11 +1291,17 @@ void nr_schedule_ulsch(module_id_t module_id,
sched_pusch->slot,
sched_pusch->rbStart,
sched_pusch->rbSize,
+ ps->startSymbolIndex,
+ ps->nrOfSymbols,
sched_pusch->mcs,
sched_pusch->tb_size,
harq_id,
cur_harq->round,
- cur_harq->ndi);
+ cur_harq->ndi,
+ sched_ctrl->estimated_ul_buffer,
+ sched_ctrl->sched_ul_bytes,
+ sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes);
+
/* PUSCH in a later slot, but corresponding DCI now! */
nfapi_nr_ul_tti_request_t *future_ul_tti_req = &RC.nrmac[module_id]->UL_tti_req_ahead[0][sched_pusch->slot];
diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
index f552b6c606..4256097174 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
@@ -67,10 +67,16 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
frame_t frame_rxP, sub_frame_t slot_rxP);
+/* \brief main DL scheduler function. Calls a preprocessor to decide on
+ * resource allocation, then "post-processes" resource allocation (nFAPI
+ * messages, statistics, HARQ handling, CEs, ... */
void nr_schedule_ue_spec(module_id_t module_id,
frame_t frame,
sub_frame_t slot);
+/* \brief default FR1 DL preprocessor init routine, returns preprocessor to call */
+nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(module_id_t module_id, int CC_id);
+
void schedule_control_sib1(module_id_t module_id,
int CC_id,
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
@@ -82,30 +88,15 @@ void schedule_control_sib1(module_id_t module_id,
void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP);
-/* \brief default preprocessor */
-void nr_simple_dlsch_preprocessor(module_id_t module_id,
- frame_t frame,
- sub_frame_t slot);
+void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP);
-void schedule_nr_mib(module_id_t module_idP,
- frame_t frameP,
- sub_frame_t subframeP,
- uint8_t slots_per_frame,
- int nb_periods_per_frame);
+/* \brief main UL scheduler function. Calls a preprocessor to decide on
+ * resource allocation, then "post-processes" resource allocation (nFAPI
+ * messages, statistics, HARQ handling, ... */
+void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot);
-/// uplink scheduler
-void nr_schedule_ulsch(module_id_t module_id,
- frame_t frame,
- sub_frame_t slot,
- int num_slots_per_tdd,
- int ul_slots,
- uint64_t ulsch_in_slot_bitmap);
-
-bool nr_simple_ulsch_preprocessor(module_id_t module_id,
- frame_t frame,
- sub_frame_t slot,
- int num_slots_per_tdd,
- uint64_t ulsch_in_slot_bitmap);
+/* \brief default FR1 UL preprocessor init routine, returns preprocessor to call */
+nr_pp_impl_ul nr_init_fr1_ulsch_preprocessor(module_id_t module_id, int CC_id);
/////// Random Access MAC-PHY interface functions and primitives ///////
@@ -122,7 +113,7 @@ void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP);
void nr_initiate_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP,
uint16_t preamble_index, uint8_t freq_index, uint8_t symbol, int16_t timing_offset);
-void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP);
+void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, NR_RA_t *ra);
int nr_allocate_CCEs(int module_idP, int CC_idP, frame_t frameP, sub_frame_t slotP, int test_only);
@@ -159,11 +150,7 @@ void nr_preprocessor_phytest(module_id_t module_id,
sub_frame_t slot);
/* \brief UL preprocessor for phytest: schedules UE_id 0 with fixed MCS on a
* fixed set of resources */
-bool nr_ul_preprocessor_phytest(module_id_t module_id,
- frame_t frame,
- sub_frame_t slot,
- int num_slots_per_tdd,
- uint64_t ulsch_in_slot_bitmap);
+bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_t slot);
void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
frame_t frameP,
@@ -262,23 +249,26 @@ void prepare_dci(const NR_CellGroupConfig_t *secondaryCellGroup,
int bwp_id);
/* find coreset within the search space */
-NR_ControlResourceSet_t *get_coreset(NR_BWP_Downlink_t *bwp,
- NR_SearchSpace_t *ss,
- int ss_type);
+NR_ControlResourceSet_t *get_coreset(const NR_BWP_Downlink_t *bwp, const NR_SearchSpace_t *ss, int ss_type);
/* find a search space within a BWP */
-NR_SearchSpace_t *get_searchspace(
- NR_BWP_Downlink_t *bwp,
- NR_SearchSpace__searchSpaceType_PR target_ss);
+NR_SearchSpace_t *get_searchspace(const NR_BWP_Downlink_t *bwp, NR_SearchSpace__searchSpaceType_PR target_ss);
-long get_K2(NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu);
+long get_K2(const NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu);
-void nr_save_pusch_fields(const NR_ServingCellConfigCommon_t *scc,
- const NR_BWP_Uplink_t *ubwp,
- long dci_format,
- int tda,
- uint8_t num_dmrs_cdm_grps_no_data,
- NR_sched_pusch_save_t *ps);
+void nr_set_pdsch_semi_static(const NR_ServingCellConfigCommon_t *scc,
+ const NR_CellGroupConfig_t *secondaryCellGroup,
+ const NR_BWP_Downlink_t *bwp,
+ int tda,
+ uint8_t num_dmrs_cdm_grps_no_data,
+ NR_pdsch_semi_static_t *ps);
+
+void nr_set_pusch_semi_static(const NR_ServingCellConfigCommon_t *scc,
+ const NR_BWP_Uplink_t *ubwp,
+ long dci_format,
+ int tda,
+ uint8_t num_dmrs_cdm_grps_no_data,
+ NR_pusch_semi_static_t *ps);
uint8_t nr_get_tpc(int target, uint8_t cqi, int incr);
@@ -320,6 +310,8 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP, NR_CellGroupConfig_t *secon
void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti);
+void nr_mac_remove_ra_rnti(module_id_t mod_id, rnti_t rnti);
+
int allocate_nr_CCEs(gNB_MAC_INST *nr_mac,
NR_BWP_Downlink_t *bwp,
NR_ControlResourceSet_t *coreset,
@@ -355,15 +347,17 @@ void config_nr_mib(int Mod_idP,
int cellBarred,
int intraFreqReselection);
+int nr_write_ce_dlsch_pdu(module_id_t module_idP,
+ const NR_UE_sched_ctrl_t *ue_sched_ctl,
+ unsigned char *mac_pdu,
+ unsigned char drx_cmd,
+ unsigned char *ue_cont_res_id);
+
void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra);
-void nr_process_mac_pdu(
- module_id_t module_idP,
- rnti_t rnti,
- uint8_t CC_id,
- frame_t frameP,
- uint8_t *pduP,
- uint16_t mac_pdu_len);
+void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra);
+
+void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t slot, NR_RA_t *ra);
int binomial(int n, int k);
@@ -406,5 +400,18 @@ int16_t ssb_index_from_prach(module_id_t module_idP,
void find_SSB_and_RO_available(module_id_t module_idP);
+void calculate_preferred_dl_tda(module_id_t module_id, const NR_BWP_Downlink_t *bwp);
+void calculate_preferred_ul_tda(module_id_t module_id, const NR_BWP_Uplink_t *ubwp);
+
bool find_free_CCE(module_id_t module_id, sub_frame_t slot, int UE_id);
+
+bool nr_find_nb_rb(uint16_t Qm,
+ uint16_t R,
+ uint16_t nb_symb_sch,
+ uint16_t nb_dmrs_prb,
+ uint32_t bytes,
+ uint16_t nb_rb_max,
+ uint32_t *tbs,
+ uint16_t *nb_rb);
+
#endif /*__LAYER2_NR_MAC_PROTO_H__*/
diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c
index 33e575d2b9..60b0cac215 100644
--- a/openair2/LAYER2/NR_MAC_gNB/main.c
+++ b/openair2/LAYER2/NR_MAC_gNB/main.c
@@ -85,8 +85,8 @@ void mac_top_init_gNB(void)
RC.nrmac[i]->pre_processor_dl = nr_preprocessor_phytest;
RC.nrmac[i]->pre_processor_ul = nr_ul_preprocessor_phytest;
} else {
- RC.nrmac[i]->pre_processor_dl = nr_simple_dlsch_preprocessor;
- RC.nrmac[i]->pre_processor_ul = nr_simple_ulsch_preprocessor;
+ RC.nrmac[i]->pre_processor_dl = nr_init_fr1_dlsch_preprocessor(i, 0);
+ RC.nrmac[i]->pre_processor_ul = nr_init_fr1_ulsch_preprocessor(i, 0);
}
}//END for (i = 0; i < RC.nb_nr_macrlc_inst; i++)
diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
index d9869e7a7b..c8ea892ca5 100644
--- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
+++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
@@ -305,11 +305,11 @@ typedef struct NR_sched_pucch {
uint8_t resource_indicator;
} NR_sched_pucch_t;
-/* this struct is a helper: as long as the TDA and DCI format remain the same
- * over the same uBWP and search space, there is no need to recalculate all
- * S/L, MCS table, or DMRS-related parameters over and over again. Hence, we
- * store them in this struct for easy reference. */
-typedef struct NR_sched_pusch_save {
+/* PUSCH semi-static configuration: as long as the TDA and DCI format remain
+ * the same over the same uBWP and search space, there is no need to
+ * recalculate all S/L, MCS table, or DMRS-related parameters over and over
+ * again. Hence, we store them in this struct for easy reference. */
+typedef struct NR_pusch_semi_static_t {
int dci_format;
int time_domain_allocation;
uint8_t num_dmrs_cdm_grps_no_data;
@@ -327,7 +327,7 @@ typedef struct NR_sched_pusch_save {
uint16_t ul_dmrs_symb_pos;
uint8_t num_dmrs_symb;
uint8_t N_PRB_DMRS;
-} NR_sched_pusch_save_t;
+} NR_pusch_semi_static_t;
typedef struct NR_sched_pusch {
int frame;
@@ -337,9 +337,6 @@ typedef struct NR_sched_pusch {
uint16_t rbSize;
uint16_t rbStart;
- // time-domain allocation for scheduled RBs
- int time_domain_allocation;
-
/// MCS
uint8_t mcs;
@@ -350,17 +347,68 @@ typedef struct NR_sched_pusch {
/// UL HARQ PID to use for this UE, or -1 for "any new"
int8_t ul_harq_pid;
+
+ /// the Time Domain Allocation used for this transmission. Note that this is
+ /// only important for retransmissions; otherwise, the TDA in
+ /// NR_pusch_semi_static_t has precedence
+ int time_domain_allocation;
} NR_sched_pusch_t;
+/* PDSCH semi-static configuratio: as long as the TDA/DMRS/mcsTable remains the
+ * same, there is no need to recalculate all S/L or DMRS-related parameters
+ * over and over again. Hence, we store them in this struct for easy
+ * reference. */
+typedef struct NR_pdsch_semi_static {
+ int time_domain_allocation;
+ uint8_t numDmrsCdmGrpsNoData;
+
+ int startSymbolIndex;
+ int nrOfSymbols;
+
+ uint8_t mcsTableIdx;
+
+ uint8_t N_PRB_DMRS;
+ uint8_t N_DMRS_SLOT;
+ uint16_t dl_dmrs_symb_pos;
+ nfapi_nr_dmrs_type_e dmrsConfigType;
+} NR_pdsch_semi_static_t;
+
+typedef struct NR_sched_pdsch {
+ /// RB allocation within active BWP
+ uint16_t rbSize;
+ uint16_t rbStart;
+
+ /// MCS-related infos
+ uint8_t mcs;
+
+ /// TBS-related info
+ uint16_t R;
+ uint8_t Qm;
+ uint32_t tb_size;
+
+ /// DL HARQ PID to use for this UE, or -1 for "any new"
+ int8_t dl_harq_pid;
+
+ /// the Time Domain Allocation used for this transmission. Note that this is
+ /// only important for retransmissions; otherwise, the TDA in
+ /// NR_pdsch_semi_static_t has precedence
+ int time_domain_allocation;
+} NR_sched_pdsch_t;
+
typedef struct NR_UE_harq {
bool is_waiting;
uint8_t ndi;
uint8_t round;
+ uint16_t feedback_frame;
uint16_t feedback_slot;
- /* Transport block to be sent using this HARQ process */
+ /* Transport block to be sent using this HARQ process, its size is in
+ * sched_pdsch */
uint32_t tb[16384];
uint32_t tb_size;
+
+ /// sched_pdsch keeps information on MCS etc used for the initial transmission
+ NR_sched_pdsch_t sched_pdsch;
} NR_UE_harq_t;
//! fixme : need to enhace for the multiple TB CQI report
@@ -441,13 +489,6 @@ typedef struct nr_csi_report {
From spec 38.214 section 5.2.1.2 For periodic and semi-persistent CSI Resource Settings, the number of CSI-RS Resource Sets configured is limited to S=1
*/
#define MAX_CSI_RESOURCE_SET_IN_CSI_RESOURCE_CONFIG 16
-typedef struct NR_UE_old_sched {
- uint16_t rbSize;
- int time_domain_allocation;
- uint8_t mcsTableIdx;
- uint8_t mcs;
- uint8_t numDmrsCdmGrpsNoData;
-} NR_UE_ret_info_t;
typedef enum {
INACTIVE = 0,
@@ -468,15 +509,18 @@ typedef struct NR_UE_ul_harq {
/*! \brief scheduling control information set through an API */
#define MAX_CSI_REPORTS 48
typedef struct {
- /// total amount of data awaiting for this UE
- uint32_t num_total_bytes;
- /// per-LC status data
- mac_rlc_status_resp_t rlc_status[MAX_NUM_LCID];
-
/// the currently active BWP in DL
NR_BWP_Downlink_t *active_bwp;
/// the currently active BWP in UL
NR_BWP_Uplink_t *active_ubwp;
+ /// CCE index and aggregation, should be coherent with cce_list
+ NR_SearchSpace_t *search_space;
+ NR_ControlResourceSet_t *coreset;
+
+ /// CCE index and Aggr. Level are shared for PUSCH/PDSCH allocation decisions
+ /// corresponding to the sched_pusch/sched_pdsch structures below
+ 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
@@ -484,44 +528,40 @@ typedef struct {
/// nr_acknack_scheduling()!
NR_sched_pucch_t sched_pucch[3];
- NR_sched_pusch_save_t pusch_save;
+ /// PUSCH semi-static configuration: is not cleared across TTIs
+ NR_pusch_semi_static_t pusch_semi_static;
+ /// Sched PDSCH: scheduling decisions, copied into HARQ and cleared every TTI
NR_sched_pusch_t sched_pusch;
- /// CCE index and aggregation, should be coherent with cce_list
- NR_SearchSpace_t *search_space;
- NR_ControlResourceSet_t *coreset;
- int cce_index;
- uint8_t aggregation_level;
-
- /// RB allocation within active BWP
- uint16_t rbSize;
- uint16_t rbStart;
-
/// uplink bytes that are currently scheduled
int sched_ul_bytes;
/// estimation of the UL buffer size
int estimated_ul_buffer;
- // time-domain allocation for scheduled RBs
- int time_domain_allocation;
+ /// PHR info: power headroom level (dB)
+ int ph;
+ /// PHR info: nominal UE transmit power levels (dBm)
+ int pcmax;
- /// MCS-related infos
- uint8_t mcsTableIdx;
- uint8_t mcs;
- uint8_t numDmrsCdmGrpsNoData;
+ /// PDSCH semi-static configuration: is not cleared across TTIs
+ 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;
- /// Retransmission-related information
- NR_UE_ret_info_t retInfo[NR_MAX_NB_HARQ_PROCESSES];
- /// DL HARQ PID to use for this UE, or -1 for "any new"
- int8_t dl_harq_pid;
+ /// total amount of data awaiting for this UE
+ uint32_t num_total_bytes;
+ /// per-LC status data
+ mac_rlc_status_resp_t rlc_status[MAX_NUM_LCID];
uint16_t ta_frame;
int16_t ta_update;
bool ta_apply;
uint8_t tpc0;
uint8_t tpc1;
- uint16_t ul_rssi;
- uint8_t current_harq_pid;
+ int raw_rssi;
+ int pusch_snrx10;
+ int pucch_snrx10;
+
struct CSI_Report CSI_report[MAX_CSI_REPORTS];
/// information about every HARQ process
NR_UE_harq_t harq_processes[NR_MAX_NB_HARQ_PROCESSES];
@@ -539,7 +579,6 @@ typedef struct {
NR_list_t feedback_ul_harq;
/// UL HARQ processes that await retransmission
NR_list_t retrans_ul_harq;
- int dummy;
NR_UE_mac_ce_ctrl_t UE_mac_ce_ctrl;// MAC CE related information
} NR_UE_sched_ctrl_t;
@@ -591,9 +630,7 @@ typedef void (*nr_pp_impl_dl)(module_id_t mod_id,
sub_frame_t slot);
typedef bool (*nr_pp_impl_ul)(module_id_t mod_id,
frame_t frame,
- sub_frame_t slot,
- int num_slots_per_tdd,
- uint64_t ulsch_in_slot_bitmap);
+ sub_frame_t slot);
/*! \brief top level eNB MAC structure */
typedef struct gNB_MAC_INST_s {
@@ -672,6 +709,19 @@ typedef struct gNB_MAC_INST_s {
/// 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];
+ /// Lookup for preferred time domain allocation for BWP, in DL, slots
+ /// dynamically allocated
+ int *preferred_dl_tda[MAX_NUM_BWP];
+ /// bitmap of ULSCH slots, can hold up to 160 slots
+ uint64_t ulsch_slot_bitmap[3];
+ /// Lookup for preferred time domain allocation for UL BWP, dynamically
+ /// allocated. The index refers to the DL slot, and the indicated TDA's k2
+ /// points to the right UL slot
+ int *preferred_ul_tda[MAX_NUM_BWP];
+
/// DL preprocessor for differentiated scheduling
nr_pp_impl_dl pre_processor_dl;
/// UL preprocessor for differentiated scheduling
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
index ee2711c6ef..e516217ff1 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
@@ -61,6 +61,7 @@
# include "gtpv1u_eNB_task.h"
# include "gtpv1u.h"
+#include
#include "ENB_APP/enb_config.h"
@@ -83,9 +84,57 @@ hash_table_t *pdcp_coll_p = NULL;
static int mbms_socket = -1;
#endif
+uint32_t Pdcp_stats_tx_window_ms[MAX_eNB][MAX_MOBILES_PER_ENB];
+uint32_t Pdcp_stats_tx_bytes[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_bytes_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_bytes_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_sn[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_throughput_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_aiat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_aiat_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_aiat_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_tx_iat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_window_ms[MAX_eNB][MAX_MOBILES_PER_ENB];
+uint32_t Pdcp_stats_rx[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_bytes[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_bytes_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_bytes_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_sn[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_goodput_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_aiat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_aiat_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_aiat_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_iat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+uint32_t Pdcp_stats_rx_outoforder[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+int pdcp_pc5_sockfd;
+struct sockaddr_in prose_ctrl_addr;
+struct sockaddr_in prose_pdcp_addr;
+struct sockaddr_in pdcp_sin;
/* pdcp module parameters and related functions*/
static pdcp_params_t pdcp_params= {0,NULL};
+rnti_t pdcp_UE_UE_module_id_to_rnti[MAX_MOBILES_PER_ENB];
+rnti_t pdcp_eNB_UE_instance_to_rnti[MAX_MOBILES_PER_ENB]; // for noS1 mode
+unsigned int pdcp_eNB_UE_instance_to_rnti_index;
+
+signed int pdcp_2_nas_irq;
+pdcp_stats_t UE_pdcp_stats[MAX_MOBILES_PER_ENB];
+pdcp_stats_t eNB_pdcp_stats[NUMBER_OF_eNB_MAX];
+
+static pdcp_mbms_t pdcp_mbms_array_ue[MAX_MOBILES_PER_ENB][LTE_maxServiceCount][LTE_maxSessionPerPMCH]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h
+static pdcp_mbms_t pdcp_mbms_array_eNB[NUMBER_OF_eNB_MAX][LTE_maxServiceCount][LTE_maxSessionPerPMCH]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h
+static sdu_size_t pdcp_input_sdu_remaining_size_to_read;
+static sdu_size_t pdcp_output_header_bytes_to_write;
+static sdu_size_t pdcp_output_sdu_bytes_to_write;
+notifiedFIFO_t pdcp_sdu_list;
+
+pdcp_enb_t pdcp_enb[MAX_NUM_CCs];
+
uint64_t get_pdcp_optmask(void) {
return pdcp_params.optmask;
@@ -937,7 +986,7 @@ pdcp_data_ind(
GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).offset = GTPU_HEADER_OVERHEAD_MAX;
GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rnti = ctxt_pP->rnti;
GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rab_id = rb_id + 4;
- itti_send_msg_to_task(TASK_GTPV1_U, INSTANCE_DEFAULT, message_p);
+ itti_send_msg_to_task(TASK_VARIABLE, INSTANCE_DEFAULT, message_p);
packet_forwarded = TRUE;
}
} else {
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
index c8ab4499ee..0c3dd2f04f 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
@@ -91,34 +91,34 @@ extern int pdcp_instance_cnt;
int init_pdcp_thread(void);
void cleanup_pdcp_thread(void);
-uint32_t Pdcp_stats_tx_window_ms[MAX_eNB][MAX_MOBILES_PER_ENB];
-uint32_t Pdcp_stats_tx_bytes[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx_bytes_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx_bytes_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx_sn[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx_throughput_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx_aiat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx_aiat_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx_aiat_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_tx_iat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_tx_window_ms[MAX_eNB][MAX_MOBILES_PER_ENB];
+extern uint32_t Pdcp_stats_tx_bytes[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_tx_bytes_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_tx_bytes_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_tx[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_tx_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_tx_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_tx_sn[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_tx_throughput_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_tx_aiat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_tx_aiat_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_tx_aiat_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_tx_iat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_window_ms[MAX_eNB][MAX_MOBILES_PER_ENB];
-uint32_t Pdcp_stats_rx[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_bytes[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_bytes_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_bytes_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_sn[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_goodput_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_aiat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_aiat_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_aiat_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_iat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
-uint32_t Pdcp_stats_rx_outoforder[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_rx_window_ms[MAX_eNB][MAX_MOBILES_PER_ENB];
+extern uint32_t Pdcp_stats_rx[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_rx_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_rx_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_rx_bytes[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_rx_bytes_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_rx_bytes_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_rx_sn[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_rx_goodput_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_rx_aiat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_rx_aiat_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_rx_aiat_tmp_w[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_rx_iat[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
+extern uint32_t Pdcp_stats_rx_outoforder[MAX_eNB][MAX_MOBILES_PER_ENB][NB_RB_MAX];
void pdcp_update_perioidical_stats(const protocol_ctxt_t *const ctxt_pP);
@@ -138,7 +138,7 @@ typedef struct pdcp_enb_s {
} pdcp_enb_t;
-pdcp_enb_t pdcp_enb[MAX_NUM_CCs];
+extern pdcp_enb_t pdcp_enb[MAX_NUM_CCs];
typedef struct pdcp_stats_s {
time_stats_t pdcp_run;
@@ -242,17 +242,18 @@ typedef struct pdcp_mbms_s {
* \note None
* @ingroup _pdcp
*/
+
boolean_t pdcp_data_req(
protocol_ctxt_t *ctxt_pP,
const srb_flag_t srb_flagP,
const rb_id_t rb_id,
const mui_t muiP,
- const confirm_t confirmP, \
+ const confirm_t confirmP,
const sdu_size_t sdu_buffer_size,
unsigned char *const sdu_buffer,
const pdcp_transmission_mode_t mode,
- const uint32_t *const sourceL2Id,
- const uint32_t *const destinationL2Id
+ const uint32_t * sourceL2Id,
+ const uint32_t * destinationL2Id
);
/*! \fn boolean_t pdcp_data_ind(const protocol_ctxt_t* const, srb_flag_t, MBMS_flag_t, rb_id_t, sdu_size_t, mem_block_t*, boolean_t)
@@ -455,10 +456,10 @@ struct pdcp_netlink_element_s {
//TTN for D2D (PC5S)
#define PDCP_SOCKET_PORT_NO 9999 //temporary value
#define PC5_SIGNALLING_PAYLOAD_SIZE 100 //should be updated with a correct value
-int pdcp_pc5_sockfd;
-struct sockaddr_in prose_ctrl_addr;
-struct sockaddr_in prose_pdcp_addr;
-struct sockaddr_in pdcp_sin;
+extern int pdcp_pc5_sockfd;
+extern struct sockaddr_in prose_ctrl_addr;
+extern struct sockaddr_in prose_pdcp_addr;
+extern struct sockaddr_in pdcp_sin;
void pdcp_pc5_socket_init(void);
typedef struct {
@@ -500,28 +501,18 @@ typedef struct {
#define REORDERING_WINDOW_SN_7BIT 64
#define REORDERING_WINDOW_SN_12BIT 2048
-signed int pdcp_2_nas_irq;
-pdcp_stats_t UE_pdcp_stats[MAX_MOBILES_PER_ENB];
-pdcp_stats_t eNB_pdcp_stats[NUMBER_OF_eNB_MAX];
+extern signed int pdcp_2_nas_irq;
+extern pdcp_stats_t UE_pdcp_stats[MAX_MOBILES_PER_ENB];
+extern pdcp_stats_t eNB_pdcp_stats[NUMBER_OF_eNB_MAX];
// for UE code conly
-rnti_t pdcp_UE_UE_module_id_to_rnti[MAX_MOBILES_PER_ENB];
-rnti_t pdcp_eNB_UE_instance_to_rnti[MAX_MOBILES_PER_ENB]; // for noS1 mode
-unsigned int pdcp_eNB_UE_instance_to_rnti_index;
+extern rnti_t pdcp_UE_UE_module_id_to_rnti[MAX_MOBILES_PER_ENB];
+extern rnti_t pdcp_eNB_UE_instance_to_rnti[MAX_MOBILES_PER_ENB]; // for noS1 mode
+extern unsigned int pdcp_eNB_UE_instance_to_rnti_index;
-pdcp_mbms_t pdcp_mbms_array_ue[MAX_MOBILES_PER_ENB][LTE_maxServiceCount][LTE_maxSessionPerPMCH]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h
-pdcp_mbms_t pdcp_mbms_array_eNB[NUMBER_OF_eNB_MAX][LTE_maxServiceCount][LTE_maxSessionPerPMCH]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h
-sdu_size_t pdcp_output_sdu_bytes_to_write;
-sdu_size_t pdcp_output_header_bytes_to_write;
-notifiedFIFO_t pdcp_sdu_list;
-int pdcp_sent_a_sdu;
-pdcp_data_req_header_t pdcp_input_header;
-unsigned char pdcp_input_sdu_buffer[MAX_IP_PACKET_SIZE];
-sdu_size_t pdcp_input_index_header;
-sdu_size_t pdcp_input_sdu_size_read;
-sdu_size_t pdcp_input_sdu_remaining_size_to_read;
+extern notifiedFIFO_t pdcp_sdu_list;
#define PDCP_COLL_KEY_VALUE(mODULE_iD, rNTI, iS_eNB, rB_iD, iS_sRB) \
((hash_key_t)mODULE_iD | \
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
index 687d7b1bfe..8ff3c06cd4 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
@@ -78,9 +78,6 @@ extern int nas_sock_fd[MAX_MOBILES_PER_ENB];
extern int nas_sock_mbms_fd;
-extern int mbms_rab_id;
-
-
extern struct msghdr nas_msg_tx;
extern struct msghdr nas_msg_rx;
@@ -113,8 +110,6 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) {
* PDCP packet to pick the right socket below */
int rb_id = pdcpHead->rb_id;
- int sizeToWrite= sizeof (pdcp_data_ind_header_t) +
- pdcpHead->data_size;
void * pdcpData=(void*)(pdcpHead+1);
if (rb_id == 10) { //hardcoded for PC5-Signaling
if( LOG_DEBUGFLAG(DEBUG_PDCP) ) {
@@ -128,24 +123,25 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) {
} else if (UE_NAS_USE_TUN) {
//ret = write(nas_sock_fd[pdcpHead->inst], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite );
if(rb_id == mbms_rab_id){
- ret = write(nas_sock_mbms_fd, pdcpData,sizeToWrite );
+ ret = write(nas_sock_mbms_fd, pdcpData, pdcpHead->data_size );
LOG_I(PDCP,"[PDCP_FIFOS] ret %d TRIED TO PUSH MBMS DATA TO rb_id %d handle %d sizeToWrite %d\n",
- ret,rb_id,nas_sock_fd[pdcpHead->inst],sizeToWrite);
+ ret,rb_id,nas_sock_fd[pdcpHead->inst],pdcpHead->data_size);
}
else
{
if( LOG_DEBUGFLAG(DEBUG_PDCP) )
- log_dump(PDCP, pdcpData, sizeToWrite, LOG_DUMP_CHAR,"PDCP output to be sent to TUN interface: \n");
- ret = write(nas_sock_fd[pdcpHead->inst], pdcpData,sizeToWrite );
+ log_dump(PDCP, pdcpData, pdcpHead->data_size, LOG_DUMP_CHAR,"PDCP output to be sent to TUN interface: \n");
+ ret = write(nas_sock_fd[pdcpHead->inst], pdcpData,pdcpHead->data_size );
LOG_T(PDCP,"[UE PDCP_FIFOS] ret %d TRIED TO PUSH DATA TO rb_id %d handle %d sizeToWrite %d\n",
- ret,rb_id,nas_sock_fd[pdcpHead->inst],sizeToWrite);
+ ret,rb_id,nas_sock_fd[pdcpHead->inst],pdcpHead->data_size);
}
} else if (ENB_NAS_USE_TUN) {
if( LOG_DEBUGFLAG(DEBUG_PDCP) )
- log_dump(PDCP, pdcpData, sizeToWrite, LOG_DUMP_CHAR,"PDCP output to be sent to TUN interface: \n");
- ret = write(nas_sock_fd[0], pdcpData, sizeToWrite);
- LOG_T(PDCP,"[NB PDCP_FIFOS] ret %d TRIED TO PUSH DATA TO rb_id %d handle %d sizeToWrite %d\n",ret,rb_id,nas_sock_fd[0],sizeToWrite);
+ log_dump(PDCP, pdcpData, pdcpHead->data_size, LOG_DUMP_CHAR,"PDCP output to be sent to TUN interface: \n");
+ ret = write(nas_sock_fd[0], pdcpData, pdcpHead->data_size);
+ LOG_T(PDCP,"[NB PDCP_FIFOS] ret %d TRIED TO PUSH DATA TO rb_id %d handle %d sizeToWrite %d\n",ret,rb_id,nas_sock_fd[0],pdcpHead->data_size);
} else if (PDCP_USE_NETLINK) {
+ int sizeToWrite= sizeof (pdcp_data_ind_header_t) + pdcpHead->data_size;
memcpy(NLMSG_DATA(nas_nlh_tx), (uint8_t *) pdcpHead, sizeToWrite);
nas_nlh_tx->nlmsg_len = sizeToWrite;
ret = sendmsg(nas_sock_fd[0],&nas_msg_tx,0);
@@ -154,7 +150,7 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) {
AssertFatal(ret >= 0,"[PDCP_FIFOS] pdcp_fifo_flush_sdus (errno: %d %s), nas_sock_fd[0]: %d\n", errno, strerror(errno), nas_sock_fd[0]);
if( LOG_DEBUGFLAG(DEBUG_PDCP) )
- log_dump(PDCP, pdcpData, min(sizeToWrite,30) , LOG_DUMP_CHAR,
+ log_dump(PDCP, pdcpData, min(pdcpHead->data_size,30) , LOG_DUMP_CHAR,
"Printing first bytes of PDCP SDU before removing it from the list: \n");
delNotifiedFIFO_elt (sdu_p);
pdcp_nb_sdu_sent ++;
@@ -377,7 +373,6 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx
protocol_ctxt_t ctxt;
hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE;
hashtable_rc_t h_rc;
- module_id_t ue_id = 0;
pdcp_t *pdcp_p = NULL;
static unsigned char pdcp_read_state_g =0;
rb_id_t rab_id = 0;
@@ -471,30 +466,7 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx
} else { // rb_id =0, thus interpreated as broadcast and transported as multiple unicast
// is a broadcast packet, we have to send this packet on all default RABS of all connected UEs
//#warning CODE TO BE REVIEWED, ONLY WORK FOR SIMPLE TOPOLOGY CASES
- for (ue_id = 0; ue_id < NB_UE_INST; ue_id++) {
- if (oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt_cpy.module_id][ue_id] != NOT_A_RNTI) {
- ctxt.rnti = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt_cpy.module_id][ue_id];
- LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %ld][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n",
- ctxt.frame,
- pdcp_read_header_g.inst,
- pdcp_read_header_g.rb_id,
- pdcp_read_header_g.data_size,
- ctxt.module_id,
- ctxt.rnti,
- DEFAULT_RAB_ID);
- pdcp_data_req (
- &ctxt,
- SRB_FLAG_NO,
- DEFAULT_RAB_ID,
- RLC_MUI_UNDEFINED,
- RLC_SDU_CONFIRM_NO,
- pdcp_read_header_g.data_size,
- (unsigned char *)NLMSG_DATA(nas_nlh_rx),
- PDCP_TRANSMISSION_MODE_DATA
- ,NULL, NULL
- );
- }
- }
+ // never finished code, dropped
}
} else { // ctxt.enb_flag => UE
if (NFAPI_MODE == NFAPI_UE_STUB_PNF) {
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c
index bf6579955b..cb5f1af28d 100644
--- a/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c
@@ -319,13 +319,15 @@ error:
}
int proto_agent_get_ack_result(mod_id_t mod_id, const void *params, Protocol__FlexsplitMessage **msg) {
+/* code useless in this status: return 0 anyways
rlc_op_status_t result = 0;
- //printf("PROTO_AGENT: handling the data_req_ack message\n");
+ printf("PROTO_AGENT: handling the data_req_ack message\n");
Protocol__FlexsplitMessage *input = (Protocol__FlexsplitMessage *)params;
Protocol__FspRlcDataReqAck *data_ack = input->data_req_ack;
result = data_ack->result;
- //printf("PROTO_AGENT: ACK RESULT IS %u\n", result);
+ printf("PROTO_AGENT: ACK RESULT IS %u\n", result);
ack_result = result;
+*/
return 0;
}
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_common.h b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.h
index c805b81543..8f553e05e1 100644
--- a/openair2/LAYER2/PROTO_AGENT/proto_agent_common.h
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.h
@@ -62,7 +62,6 @@ typedef int (*proto_agent_message_destruction_callback)(
);
-uint32_t ack_result;
/**********************************
* progRAN protocol messages helper
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.c b/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.c
index 9a63427ed5..925c11c8f8 100644
--- a/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.c
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.c
@@ -30,7 +30,7 @@
#include "common/utils/LOG/log.h"
proto_agent_channel_t *proto_channel[NUMBER_OF_eNB_MAX][ENB_AGENT_MAX];
-proto_agent_channel_instance_t channel_instance;
+static proto_agent_channel_instance_t channel_instance;
int proto_agent_channel_id = 0;
int proto_agent_register_channel(mod_id_t mod_id, proto_agent_channel_t *channel, proto_agent_id_t agent_id) {
diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.c
index fda84879be..cf77f9ec37 100644
--- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.c
+++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.c
@@ -80,6 +80,8 @@ static int g_send_id_read_index[2];
static struct mac_data_ind g_tx_delayed_indications[MAX_TIME_DELAYED_PDU_DUE_TO_HARQ];
static struct mac_data_ind g_rx_delayed_indications[MAX_TIME_DELAYED_PDU_DUE_TO_HARQ];
+static rlc_um_entity_t um_tx;
+static rlc_um_entity_t um_rx;
static int8_t *g_sdus[] = {"En dépit de son volontarisme affiché, le premier ministre est de plus en plus décrié pour son incompétence. La tension politique et dans l'opinion publique est encore montée d'un cran au Japon, sur fond d'inquiétantes nouvelles, avec du plutonium détecté dans le sol autour de la centrale de Fukushima. Le premier ministre Naoto Kan a solennellement déclaré que son gouvernement était «en état d'alerte maximum». Tout en reconnaissant que la situation restait «imprévisible». Ce volontarisme affiché par le premier ministre - que Nicolas Sarkozy rencontrera demain lors d'une visite au Japon - ne l'a pas empêché d'être la cible de violentes critiques de la part de parlementaires sur sa gestion de la crise. Attaqué sur le manque de transparence, il a assuré qu'il rendait publiques toutes les informations en sa possession. Un député de l'opposition, Yosuke Isozaki, a aussi reproché à Naoto Kan de ne pas avoir ordonné l'évacuation des populations dans la zone comprise entre 20 et 30 km autour de la centrale. «Peut-il y avoir quelque chose de plus irresponsable que cela ?», a-t-il lancé. Pour l'heure, la zone d'évacuation est limitée à un rayon de 20 km, seul le confinement étant recommandé pour les 10 km suivants. Sur ce sujet, les autorités japonaises ont été fragilisées mardi par les déclarations de Greenpeace, affirmant que ses experts avaient détecté une radioactivité dangereuse à 40 km de la centrale. L'organisation écologiste a appelé à une extension de la zone d'évacuation, exhortant Tokyo à «cesser de privilégier la politique aux dépens de la science». L'Agence japonaise de sûreté nucléaire a balayé ces critiques.",
diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.h b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.h
index 6da464aa28..bfde1b31f3 100644
--- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.h
+++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.h
@@ -21,8 +21,6 @@
# ifndef __RLC_UM_TEST_H__
# define __RLC_UM_TEST_H__
-rlc_um_entity_t um_tx;
-rlc_um_entity_t um_rx;
void rlc_um_v9_3_0_test_windows_5(void);
void rlc_um_v9_3_0_test_windows_10(void);
diff --git a/openair2/LAYER2/RLC/rlc.c b/openair2/LAYER2/RLC/rlc.c
index 98c8c3e252..b9dcf0414b 100644
--- a/openair2/LAYER2/RLC/rlc.c
+++ b/openair2/LAYER2/RLC/rlc.c
@@ -36,6 +36,7 @@
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "targets/COMMON/openairinterface5g_limits.h"
#include "assertions.h"
+#include
#include "common/ran_context.h"
extern RAN_CONTEXT_t RC;
@@ -51,7 +52,27 @@ extern boolean_t pdcp_data_ind(
#define DEBUG_RLC_PDCP_INTERFACE 1
//#define TRACE_RLC_PAYLOAD 1
#define DEBUG_RLC_DATA_REQ 1
+void (*rlc_rrc_data_conf)(
+ const protocol_ctxt_t *const ctxtP,
+ const rb_id_t rb_idP,
+ const mui_t muiP,
+ const rlc_tx_status_t statusP) __attribute__ ((aligned(32)));
+void (*rlc_rrc_data_ind)(
+ const protocol_ctxt_t *const ctxtP,
+ const rb_id_t rb_idP,
+ const sdu_size_t sdu_sizeP,
+ const uint8_t *const sduP) __attribute__ ((aligned(32)));
+
+logical_chan_id_t rlc_mbms_rbid2lcid_ue [MAX_MOBILES_PER_ENB][NB_RB_MBMS_MAX]; /*!< \brief Pairing logical channel identifier with radio bearer identifer. */
+logical_chan_id_t rlc_mbms_rbid2lcid_eNB[MAX_eNB][NB_RB_MBMS_MAX]; /*!< \brief Pairing logical channel identifier with radio bearer identifer. */
+rlc_mbms_id_t rlc_mbms_lcid2service_session_id_ue[MAX_MOBILES_PER_ENB][RLC_MAX_MBMS_LC]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h
+rlc_mbms_id_t rlc_mbms_lcid2service_session_id_eNB[MAX_eNB][RLC_MAX_MBMS_LC]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h
+hash_table_t *rlc_coll_p __attribute__ ((aligned(32)));
+
+
+logical_chan_id_t rlc_mbms_rbid2lcid_ue [MAX_MOBILES_PER_ENB][NB_RB_MBMS_MAX]; /*!< \brief Pairing logical channel identifier with radio bearer identifer. */
+logical_chan_id_t rlc_mbms_rbid2lcid_eNB[MAX_eNB][NB_RB_MBMS_MAX]; /*!< \brief Pairing logical channel identifier with radio bearer identifer. */
//-----------------------------------------------------------------------------
void rlc_util_print_hex_octets(comp_name_t componentP, unsigned char *dataP, const signed long sizeP)
//-----------------------------------------------------------------------------
diff --git a/openair2/LAYER2/RLC/rlc.h b/openair2/LAYER2/RLC/rlc.h
index 7e4920a579..ef5f824ba0 100644
--- a/openair2/LAYER2/RLC/rlc.h
+++ b/openair2/LAYER2/RLC/rlc.h
@@ -133,13 +133,13 @@ typedef struct {
#define RLC_MAX_MBMS_LC (LTE_maxSessionPerPMCH * LTE_maxServiceCount)
#define RLC_MAX_LC ((max_val_LTE_DRB_Identity+1)* MAX_MOBILES_PER_ENB)
-void (*rlc_rrc_data_ind)(
+extern void (*rlc_rrc_data_ind)(
const protocol_ctxt_t *const ctxtP,
const rb_id_t rb_idP,
const sdu_size_t sdu_sizeP,
const uint8_t *const sduP) __attribute__ ((aligned(32)));
-void (*rlc_rrc_data_conf)(
+extern void (*rlc_rrc_data_conf)(
const protocol_ctxt_t *const ctxtP,
const rb_id_t rb_idP,
const mui_t muiP,
@@ -184,8 +184,8 @@ typedef struct rlc_mbms_id_s {
//rlc_mbms_t rlc_mbms_array_ue[MAX_MOBILES_PER_ENB][maxServiceCount][maxSessionPerPMCH]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h
//rlc_mbms_t rlc_mbms_array_eNB[NUMBER_OF_eNB_MAX][maxServiceCount][maxSessionPerPMCH]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h
-rlc_mbms_id_t rlc_mbms_lcid2service_session_id_ue[MAX_MOBILES_PER_ENB][RLC_MAX_MBMS_LC]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h
-rlc_mbms_id_t rlc_mbms_lcid2service_session_id_eNB[MAX_eNB][RLC_MAX_MBMS_LC]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h
+extern rlc_mbms_id_t rlc_mbms_lcid2service_session_id_ue[MAX_MOBILES_PER_ENB][RLC_MAX_MBMS_LC]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h
+extern rlc_mbms_id_t rlc_mbms_lcid2service_session_id_eNB[MAX_eNB][RLC_MAX_MBMS_LC]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h
#define rlc_mbms_enb_get_lcid_by_rb_id(Enb_mOD,rB_iD) rlc_mbms_rbid2lcid_eNB[Enb_mOD][rB_iD]
;
@@ -201,8 +201,8 @@ rlc_mbms_id_t rlc_mbms_lcid2service_session_id_eNB[MAX_eNB][RLC_MAX_MBMS_
rlc_mbms_rbid2lcid_ue[uE_mOD][rB_iD] = lOG_cH_iD; \
} while (0);
-logical_chan_id_t rlc_mbms_rbid2lcid_ue [MAX_MOBILES_PER_ENB][NB_RB_MBMS_MAX]; /*!< \brief Pairing logical channel identifier with radio bearer identifer. */
-logical_chan_id_t rlc_mbms_rbid2lcid_eNB[MAX_eNB][NB_RB_MBMS_MAX]; /*!< \brief Pairing logical channel identifier with radio bearer identifer. */
+extern logical_chan_id_t rlc_mbms_rbid2lcid_ue [MAX_MOBILES_PER_ENB][NB_RB_MBMS_MAX]; /*!< \brief Pairing logical channel identifier with radio bearer identifer. */
+extern logical_chan_id_t rlc_mbms_rbid2lcid_eNB[MAX_eNB][NB_RB_MBMS_MAX]; /*!< \brief Pairing logical channel identifier with radio bearer identifer. */
#define RLC_COLL_KEY_VALUE(eNB_iD, rNTI, iS_eNB, rB_iD, iS_sRB) \
@@ -250,7 +250,7 @@ logical_chan_id_t rlc_mbms_rbid2lcid_eNB[MAX_eNB][NB_RB_MBMS_MAX];
(((hash_key_t)(sESSION_ID)) << 37) | \
(((hash_key_t)(0x0000000000000001)) << 63))
-hash_table_t *rlc_coll_p __attribute__ ((aligned(32)));
+extern hash_table_t *rlc_coll_p __attribute__ ((aligned(32)));
/*! \fn tbs_size_t mac_rlc_serialize_tb (char* bufferP, list_t transport_blocksP)
* \brief Serialize a list of transport blocks coming from RLC in order to be processed by MAC.
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
index ec48b0adae..39b770508e 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
@@ -34,6 +34,7 @@
/* from OAI */
#include "pdcp.h"
#include "LAYER2/nr_rlc/nr_rlc_oai_api.h"
+#include
#define TODO do { \
printf("%s:%d:%s: todo\n", __FILE__, __LINE__, __FUNCTION__); \
@@ -450,7 +451,7 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity,
LOG_D(PDCP, "%s() (drb %d) sending message to gtp size %d\n", __func__, rb_id, size);
//for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)buf[i]);
//printf("\n");
- itti_send_msg_to_task(TASK_GTPV1_U, INSTANCE_DEFAULT, message_p);
+ itti_send_msg_to_task(TASK_VARIABLE, INSTANCE_DEFAULT, message_p);
}
}
@@ -804,7 +805,9 @@ void nr_DRB_preconfiguration(uint16_t crnti)
rbconfig->securityConfig->keyToUse = calloc(1,sizeof(*rbconfig->securityConfig->keyToUse));
*rbconfig->securityConfig->keyToUse = NR_SecurityConfig__keyToUse_master;
- xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)rbconfig);
+ if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
+ xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)rbconfig);
+ }
NR_RLC_BearerConfig_t *RLC_BearerConfig = calloc(1,sizeof(*RLC_BearerConfig));
nr_rlc_bearer_init(RLC_BearerConfig);
diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
index 2eb2bae968..88333272cb 100644
--- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
+++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
@@ -320,7 +320,6 @@ rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind(
return ret;
}
-int oai_emulation;
rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP,
const srb_flag_t srb_flagP,
diff --git a/openair2/LAYER2/rlc_v2/rlc_oai_api.c b/openair2/LAYER2/rlc_v2/rlc_oai_api.c
index 919d577a18..18285f6563 100644
--- a/openair2/LAYER2/rlc_v2/rlc_oai_api.c
+++ b/openair2/LAYER2/rlc_v2/rlc_oai_api.c
@@ -265,7 +265,6 @@ rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind(
return ret;
}
-int oai_emulation;
rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP,
const srb_flag_t srb_flagP,
diff --git a/openair2/NETWORK_DRIVER/UE_IP/netlink.c b/openair2/NETWORK_DRIVER/UE_IP/netlink.c
index 658ae19aba..b3829c51d1 100644
--- a/openair2/NETWORK_DRIVER/UE_IP/netlink.c
+++ b/openair2/NETWORK_DRIVER/UE_IP/netlink.c
@@ -39,6 +39,7 @@
#include "local.h"
#include "proto_extern.h"
+MODULE_LICENSE("OAI");
#define OAI_IP_DRIVER_NETLINK_ID 31
#define NL_DEST_PID 1
diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
index 5b5f3e6b3c..e42d19167d 100644
--- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
+++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
@@ -41,8 +41,8 @@
#define MAX_IF_MODULES 100
//#define UL_HARQ_PRINT
-NR_IF_Module_t *if_inst[MAX_IF_MODULES];
-NR_Sched_Rsp_t Sched_INFO[MAX_IF_MODULES][MAX_NUM_CCs];
+static NR_IF_Module_t *nr_if_inst[MAX_IF_MODULES];
+static NR_Sched_Rsp_t NR_Sched_INFO[MAX_IF_MODULES][MAX_NUM_CCs];
extern int oai_nfapi_harq_indication(nfapi_harq_indication_t *harq_ind);
extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind);
extern int oai_nfapi_cqi_indication(nfapi_cqi_indication_t *cqi_ind);
@@ -55,7 +55,7 @@ extern uint16_t sl_ahead;
void handle_nr_rach(NR_UL_IND_t *UL_info) {
if (UL_info->rach_ind.number_of_pdus>0) {
- LOG_I(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SLOT:%d/%d\n",UL_info->frame,UL_info->slot, UL_info->rach_ind.sfn,UL_info->rach_ind.slot);
+ LOG_D(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SLOT:%d/%d\n",UL_info->frame,UL_info->slot, UL_info->rach_ind.sfn,UL_info->rach_ind.slot);
int npdus = UL_info->rach_ind.number_of_pdus;
for(int i = 0; i < npdus; i++) {
UL_info->rach_ind.number_of_pdus--;
@@ -178,8 +178,8 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
#endif
module_id_t module_id = UL_info->module_id;
int CC_id = UL_info->CC_id;
- NR_Sched_Rsp_t *sched_info = &Sched_INFO[module_id][CC_id];
- NR_IF_Module_t *ifi = if_inst[module_id];
+ NR_Sched_Rsp_t *sched_info = &NR_Sched_INFO[module_id][CC_id];
+ NR_IF_Module_t *ifi = nr_if_inst[module_id];
gNB_MAC_INST *mac = RC.nrmac[module_id];
LOG_D(PHY,"SFN/SF:%d%d module_id:%d CC_id:%d UL_info[rach_pdus:%d rx_ind:%d crcs:%d]\n",
UL_info->frame,UL_info->slot,
@@ -253,17 +253,17 @@ NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {
AssertFatal(Mod_id %d\n",Mod_id,MAX_IF_MODULES);
LOG_I(PHY,"Installing callbacks for IF_Module - UL_indication\n");
- if (if_inst[Mod_id]==NULL) {
- if_inst[Mod_id] = (NR_IF_Module_t*)malloc(sizeof(NR_IF_Module_t));
- memset((void*)if_inst[Mod_id],0,sizeof(NR_IF_Module_t));
+ if (nr_if_inst[Mod_id]==NULL) {
+ nr_if_inst[Mod_id] = (NR_IF_Module_t*)malloc(sizeof(NR_IF_Module_t));
+ memset((void*)nr_if_inst[Mod_id],0,sizeof(NR_IF_Module_t));
- LOG_I(MAC,"Allocating shared L1/L2 interface structure for instance %d @ %p\n",Mod_id,if_inst[Mod_id]);
+ LOG_I(MAC,"Allocating shared L1/L2 interface structure for instance %d @ %p\n",Mod_id,nr_if_inst[Mod_id]);
- if_inst[Mod_id]->CC_mask=0;
- if_inst[Mod_id]->NR_UL_indication = NR_UL_indication;
- AssertFatal(pthread_mutex_init(&if_inst[Mod_id]->if_mutex,NULL)==0,
- "allocation of if_inst[%d]->if_mutex fails\n",Mod_id);
+ nr_if_inst[Mod_id]->CC_mask=0;
+ nr_if_inst[Mod_id]->NR_UL_indication = NR_UL_indication;
+ AssertFatal(pthread_mutex_init(&nr_if_inst[Mod_id]->if_mutex,NULL)==0,
+ "allocation of nr_if_inst[%d]->if_mutex fails\n",Mod_id);
}
- return if_inst[Mod_id];
+ return nr_if_inst[Mod_id];
}
diff --git a/openair2/PHY_INTERFACE/IF_Module.c b/openair2/PHY_INTERFACE/IF_Module.c
index d98c603d78..38a742bf74 100644
--- a/openair2/PHY_INTERFACE/IF_Module.c
+++ b/openair2/PHY_INTERFACE/IF_Module.c
@@ -7,8 +7,8 @@
#include "nfapi/oai_integration/vendor_ext.h"
#define MAX_IF_MODULES 100
-IF_Module_t *if_inst[MAX_IF_MODULES];
-Sched_Rsp_t Sched_INFO[MAX_IF_MODULES][MAX_NUM_CCs];
+static IF_Module_t *if_inst[MAX_IF_MODULES];
+static Sched_Rsp_t Sched_INFO[MAX_IF_MODULES][MAX_NUM_CCs];
extern int oai_nfapi_harq_indication(nfapi_harq_indication_t *harq_ind);
extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind);
diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c
index 21740016b1..c212075934 100644
--- a/openair2/PHY_INTERFACE/phy_stub_UE.c
+++ b/openair2/PHY_INTERFACE/phy_stub_UE.c
@@ -54,6 +54,7 @@ extern nfapi_tx_request_pdu_t* tx_request_pdu[1023][10][10];
extern uint16_t sf_ahead;
+static eth_params_t stub_eth_params;
void Msg1_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id);
void Msg3_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id);
diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.h b/openair2/PHY_INTERFACE/phy_stub_UE.h
index 547fc2dfc4..bdf8872371 100644
--- a/openair2/PHY_INTERFACE/phy_stub_UE.h
+++ b/openair2/PHY_INTERFACE/phy_stub_UE.h
@@ -26,16 +26,7 @@ extern nfapi_tx_request_pdu_t* tx_request_pdu_list;
extern nfapi_dl_config_request_t* dl_config_req;
extern nfapi_ul_config_request_t* ul_config_req;
extern nfapi_hi_dci0_request_t* hi_dci0_req;
-
-int tx_req_num_elems;
-
-//below 2 difinitions move to lte-ue.c to add initialization when difinition.
-//int next_ra_frame;
-//module_id_t next_Mod_id;
-eth_params_t stub_eth_params;
-
-
-
+extern int tx_req_num_elems;
// This function should return all the sched_response config messages which concern a specific UE. Inside this
// function we should somehow make the translation of config message's rnti to Mod_ID.
diff --git a/openair2/RRC/LTE/plmn_data.h b/openair2/RRC/LTE/plmn_data.h
index 97dc94343b..701bcaf764 100644
--- a/openair2/RRC/LTE/plmn_data.h
+++ b/openair2/RRC/LTE/plmn_data.h
@@ -2231,7 +2231,8 @@ static const plmn_data_t plmn_data[] = {
/*
310 900 Mid-Rivers Communications Mid-Rivers Wireless Operational
*/
- {310, 910, "Verizon Wireless", "Verizon USA"}
+ {310, 910, "Verizon Wireless", "Verizon USA"},
+ {0,0,"",""}
/*
310 920 Get Mobile Inactive
310 930 Copper Valley Wireless Inactive
diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c
index c57cec6ba5..e3d28d8a0f 100644
--- a/openair2/RRC/LTE/rrc_UE.c
+++ b/openair2/RRC/LTE/rrc_UE.c
@@ -330,7 +330,7 @@ void init_SL_preconfig(UE_RRC_INST *UE, const uint8_t eNB_index ) {
preconfigpool->data_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12 = 0;
// 40 ms SL Period
preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.present = LTE_SubframeBitmapSL_r12_PR_bs40_r12;
- preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf = CALLOC(1,5);
+ preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf = CALLOC(5,1);
preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.size = 5;
preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.bits_unused = 0;
// last 36 subframes for PSCCH
@@ -338,7 +338,7 @@ void init_SL_preconfig(UE_RRC_INST *UE, const uint8_t eNB_index ) {
preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[1] = 0xFF;
preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[2] = 0xFF;
preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[3] = 0xFF;
- preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[5] = 0xFF;
+ preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[4] = 0xFF;
preconfigpool->dataHoppingConfig_r12.hoppingParameter_r12 = 0;
preconfigpool->dataHoppingConfig_r12.numSubbands_r12 = LTE_SL_HoppingConfigComm_r12__numSubbands_r12_ns1;
preconfigpool->dataHoppingConfig_r12.rb_Offset_r12 = 0;
diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c
index 9f0e40806a..9a565be560 100644
--- a/openair2/RRC/LTE/rrc_eNB.c
+++ b/openair2/RRC/LTE/rrc_eNB.c
@@ -87,6 +87,7 @@
#include "pdcp.h"
#include "gtpv1u_eNB_task.h"
+#include
#include "intertask_interface.h"
@@ -4968,7 +4969,7 @@ void rrc_eNB_handover_ue_context_release(
ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0;
}
- itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->module_id, msg_delete_tunnels_p);
+ itti_send_msg_to_task(TASK_VARIABLE, ctxt_pP->module_id, msg_delete_tunnels_p);
struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL;
rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(RC.rrc[ctxt_pP->module_id], 0, eNB_ue_s1ap_id);
@@ -6557,10 +6558,9 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete(
(int)DRB_configList->list.array[i]->drb_Identity,
(int)*DRB_configList->list.array[i]->logicalChannelIdentity);
/* For pre-ci tests */
- LOG_I(RRC, "[eNB %d] Frame %d : Logical Channel UL-DCCH, Received LTE_RRCConnectionReconfigurationComplete from UE %u, reconfiguring DRB %d/LCID %d\n",
+ LOG_I(RRC, "[eNB %d] Frame %d : Logical Channel UL-DCCH, Received LTE_RRCConnectionReconfigurationComplete, reconfiguring DRB %d/LCID %d\n",
ctxt_pP->module_id,
ctxt_pP->frame,
- oai_emulation.info.eNB_ue_local_uid_to_ue_module_id[ctxt_pP->module_id][ue_context_pP->local_uid],
(int)DRB_configList->list.array[i]->drb_Identity,
(int)*DRB_configList->list.array[i]->logicalChannelIdentity);
@@ -6585,7 +6585,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete(
"[eNB %d] Config the oai%d to send/receive pkt on DRB %ld to/from the protocol stack\n",
ctxt_pP->module_id, ctxt_pP->module_id,
(long int)((ue_context_pP->local_uid * LTE_maxDRB) + DRB_configList->list.array[i]->drb_Identity));
- ue_module_id = oai_emulation.info.eNB_ue_local_uid_to_ue_module_id[ctxt_pP->module_id][ue_context_pP->local_uid];
+ ue_module_id = 0; // Was oai_emulation.info.eNB_ue_local_uid_to_ue_module_id[ctxt_pP->module_id][ue_context_pP->local_uid];
rb_conf_ipv4(0, //add
ue_module_id, //cx
ctxt_pP->module_id, //inst
diff --git a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c
index e974a28f68..64f84ddc4d 100644
--- a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c
+++ b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c
@@ -40,6 +40,7 @@
# include "common/ran_context.h"
+#include
extern RAN_CONTEXT_t RC;
@@ -92,7 +93,6 @@ rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
}
}
-
//------------------------------------------------------------------------------
boolean_t
gtpv_data_req(
@@ -113,64 +113,151 @@ gtpv_data_req(
return FALSE;
}
LOG_D(GTPU,"gtpv_data_req ue rnti %x sdu_sizeP %d rb id %ld", ctxt_pP->rnti, sdu_sizeP, rb_idP);
- {
- MessageDef *message_p;
- // Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling).
- uint8_t *message_buffer;
-
- if(task_id == TASK_DATA_FORWARDING){
-
- LOG_I(GTPU,"gtpv_data_req task_id = TASK_DATA_FORWARDING\n");
-
- message_buffer = itti_malloc (TASK_GTPV1_U, TASK_DATA_FORWARDING, sdu_sizeP);
-
- memcpy (message_buffer, buffer_pP, sdu_sizeP);
-
- message_p = itti_alloc_new_message (TASK_GTPV1_U, 0, GTPV1U_ENB_DATA_FORWARDING_IND);
- GTPV1U_ENB_DATA_FORWARDING_IND (message_p).frame = ctxt_pP->frame;
- GTPV1U_ENB_DATA_FORWARDING_IND (message_p).enb_flag = ctxt_pP->enb_flag;
- GTPV1U_ENB_DATA_FORWARDING_IND (message_p).rb_id = rb_idP;
- GTPV1U_ENB_DATA_FORWARDING_IND (message_p).muip = muiP;
- GTPV1U_ENB_DATA_FORWARDING_IND (message_p).confirmp = confirmP;
- GTPV1U_ENB_DATA_FORWARDING_IND (message_p).sdu_size = sdu_sizeP;
- GTPV1U_ENB_DATA_FORWARDING_IND (message_p).sdu_p = message_buffer;
- GTPV1U_ENB_DATA_FORWARDING_IND (message_p).mode = modeP;
- GTPV1U_ENB_DATA_FORWARDING_IND (message_p).module_id = ctxt_pP->module_id;
- GTPV1U_ENB_DATA_FORWARDING_IND (message_p).rnti = ctxt_pP->rnti;
- GTPV1U_ENB_DATA_FORWARDING_IND (message_p).eNB_index = ctxt_pP->eNB_index;
-
- itti_send_msg_to_task (TASK_DATA_FORWARDING, ctxt_pP->instance, message_p);
- return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway.
- }else if(task_id == TASK_END_MARKER){
-
- LOG_I(GTPU,"gtpv_data_req task_id = TASK_END_MARKER\n");
-
- message_buffer = itti_malloc (TASK_GTPV1_U, TASK_END_MARKER, sdu_sizeP);
-
- memcpy (message_buffer, buffer_pP, sdu_sizeP);
-
- message_p = itti_alloc_new_message (TASK_GTPV1_U, 0, GTPV1U_ENB_END_MARKER_IND);
- GTPV1U_ENB_END_MARKER_IND (message_p).frame = ctxt_pP->frame;
- GTPV1U_ENB_END_MARKER_IND (message_p).enb_flag = ctxt_pP->enb_flag;
- GTPV1U_ENB_END_MARKER_IND (message_p).rb_id = rb_idP;
- GTPV1U_ENB_END_MARKER_IND (message_p).muip = muiP;
- GTPV1U_ENB_END_MARKER_IND (message_p).confirmp = confirmP;
- GTPV1U_ENB_END_MARKER_IND (message_p).sdu_size = sdu_sizeP;
- GTPV1U_ENB_END_MARKER_IND (message_p).sdu_p = message_buffer;
- GTPV1U_ENB_END_MARKER_IND (message_p).mode = modeP;
- GTPV1U_ENB_END_MARKER_IND (message_p).module_id = ctxt_pP->module_id;
- GTPV1U_ENB_END_MARKER_IND (message_p).rnti = ctxt_pP->rnti;
- GTPV1U_ENB_END_MARKER_IND (message_p).eNB_index = ctxt_pP->eNB_index;
-
- itti_send_msg_to_task (TASK_END_MARKER, ctxt_pP->instance, message_p);
- return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway.
- }
+ MessageDef *message_p;
+ // Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling).
+ uint8_t *message_buffer;
+
+ if(task_id == TASK_DATA_FORWARDING){
+
+ LOG_I(GTPU,"gtpv_data_req task_id = TASK_DATA_FORWARDING\n");
+
+ message_buffer = itti_malloc (TASK_GTPV1_U, TASK_DATA_FORWARDING, sdu_sizeP);
+
+ memcpy (message_buffer, buffer_pP, sdu_sizeP);
+
+ message_p = itti_alloc_new_message (TASK_GTPV1_U, 0, GTPV1U_ENB_DATA_FORWARDING_IND);
+ GTPV1U_ENB_DATA_FORWARDING_IND (message_p).frame = ctxt_pP->frame;
+ GTPV1U_ENB_DATA_FORWARDING_IND (message_p).enb_flag = ctxt_pP->enb_flag;
+ GTPV1U_ENB_DATA_FORWARDING_IND (message_p).rb_id = rb_idP;
+ GTPV1U_ENB_DATA_FORWARDING_IND (message_p).muip = muiP;
+ GTPV1U_ENB_DATA_FORWARDING_IND (message_p).confirmp = confirmP;
+ GTPV1U_ENB_DATA_FORWARDING_IND (message_p).sdu_size = sdu_sizeP;
+ GTPV1U_ENB_DATA_FORWARDING_IND (message_p).sdu_p = message_buffer;
+ GTPV1U_ENB_DATA_FORWARDING_IND (message_p).mode = modeP;
+ GTPV1U_ENB_DATA_FORWARDING_IND (message_p).module_id = ctxt_pP->module_id;
+ GTPV1U_ENB_DATA_FORWARDING_IND (message_p).rnti = ctxt_pP->rnti;
+ GTPV1U_ENB_DATA_FORWARDING_IND (message_p).eNB_index = ctxt_pP->eNB_index;
+
+ itti_send_msg_to_task (TASK_DATA_FORWARDING, ctxt_pP->instance, message_p);
+ return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway.
+ } else if (task_id == TASK_END_MARKER){
+
+ LOG_I(GTPU,"gtpv_data_req task_id = TASK_END_MARKER\n");
+
+ message_buffer = itti_malloc (TASK_GTPV1_U, TASK_END_MARKER, sdu_sizeP);
+
+ memcpy (message_buffer, buffer_pP, sdu_sizeP);
+
+ message_p = itti_alloc_new_message (TASK_GTPV1_U, 0, GTPV1U_ENB_END_MARKER_IND);
+ GTPV1U_ENB_END_MARKER_IND (message_p).frame = ctxt_pP->frame;
+ GTPV1U_ENB_END_MARKER_IND (message_p).enb_flag = ctxt_pP->enb_flag;
+ GTPV1U_ENB_END_MARKER_IND (message_p).rb_id = rb_idP;
+ GTPV1U_ENB_END_MARKER_IND (message_p).muip = muiP;
+ GTPV1U_ENB_END_MARKER_IND (message_p).confirmp = confirmP;
+ GTPV1U_ENB_END_MARKER_IND (message_p).sdu_size = sdu_sizeP;
+ GTPV1U_ENB_END_MARKER_IND (message_p).sdu_p = message_buffer;
+ GTPV1U_ENB_END_MARKER_IND (message_p).mode = modeP;
+ GTPV1U_ENB_END_MARKER_IND (message_p).module_id = ctxt_pP->module_id;
+ GTPV1U_ENB_END_MARKER_IND (message_p).rnti = ctxt_pP->rnti;
+ GTPV1U_ENB_END_MARKER_IND (message_p).eNB_index = ctxt_pP->eNB_index;
+
+ itti_send_msg_to_task (TASK_END_MARKER, ctxt_pP->instance, message_p);
+ return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway.
}
- return TRUE;
-
+ LOG_E(RRC, "Impossible state\n");
+ return FALSE;
}
-//#endif
+boolean_t gtpv_data_req_new (
+ protocol_ctxt_t *ctxt,
+ const srb_flag_t srb_flagP,
+ const rb_id_t rb_idP,
+ const mui_t muiP,
+ const confirm_t confirmP,
+ const sdu_size_t sdu_buffer_sizeP,
+ unsigned char *const sdu_buffer_pP,
+ const pdcp_transmission_mode_t modeP,
+ const uint32_t *sourceL2Id,
+ const uint32_t *destinationL2Id) {
+ int task;
+
+ if (sdu_buffer_sizeP==0)
+ task=TASK_END_MARKER;
+ else
+ task=TASK_DATA_FORWARDING;
+
+ struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt->module_id], ctxt->rnti);
+ if(ue_context_p == NULL || ue_context_p->ue_context.handover_info == NULL ||
+ ue_context_p->ue_context.Status != RRC_HO_EXECUTION) {
+ LOG_E(RRC,"incoming GTP-U for X2 in non HO context\n");
+ return false;
+ }
+
+ /* in the source enb, UE in RRC_HO_EXECUTION mode */
+ // We have 2*2=4 cases (data or end marker) * (from slave, from EPC)
+ if (ue_context_p->ue_context.handover_info->state == HO_COMPLETE) {
+ LOG_I(GTPU, "source receive END MARKER\n");
+ /* set handover state */
+ //ue_context_p->ue_context.handover_info->state = HO_END_MARKER;
+ MessageDef *msg;
+ // Configure end marker
+ msg = itti_alloc_new_message(TASK_GTPV1_U, 0, GTPV1U_ENB_END_MARKER_REQ);
+ GTPV1U_ENB_END_MARKER_REQ(msg).buffer = itti_malloc(TASK_GTPV1_U, TASK_GTPV1_U, GTPU_HEADER_OVERHEAD_MAX + sdu_buffer_sizeP);
+ memcpy(>PV1U_ENB_END_MARKER_REQ(msg).buffer[GTPU_HEADER_OVERHEAD_MAX], sdu_buffer_pP, sdu_buffer_sizeP);
+ GTPV1U_ENB_END_MARKER_REQ(msg).length = sdu_buffer_sizeP;
+ GTPV1U_ENB_END_MARKER_REQ(msg).rnti = ctxt->rnti;
+ GTPV1U_ENB_END_MARKER_REQ(msg).rab_id = rb_idP;
+ GTPV1U_ENB_END_MARKER_REQ(msg).offset = GTPU_HEADER_OVERHEAD_MAX;
+ LOG_I(GTPU, "Send End Marker to GTPV1-U at frame %d and subframe %d \n", ctxt->frame,ctxt->subframe);
+ itti_send_msg_to_task(TASK_GTPV1_U, ENB_MODULE_ID_TO_INSTANCE(ctxt->module_id), msg);
+ return NW_GTPV1U_OK;
+ }
+
+ /* target enb */
+ // We have 2*2=4 cases (data or end marker) * (from source, from EPC)
+ if (ue_context_p->ue_context.Status == RRC_RECONFIGURED) {
+ // It should come from remote eNB
+ // case end marker by EPC is not possible ?
+ if (task==TASK_END_MARKER) {
+ LOG_I(GTPU, "target end receive END MARKER\n");
+ // We close the HO, nothing to send to remote ?
+ ue_context_p->ue_context.handover_info->state = HO_END_MARKER;
+ gtpv1u_enb_delete_tunnel_req_t delete_tunnel_req;
+ memset(&delete_tunnel_req, 0, sizeof(delete_tunnel_req));
+ delete_tunnel_req.rnti = ctxt->rnti;
+ gtpv1u_delete_x2u_tunnel(ctxt->module_id, &delete_tunnel_req, GTPV1U_TARGET_ENB);
+ return true;
+ } else {
+ /* data packet */
+ LOG_I(GTPU, "Received a message data forwarding length %d\n", sdu_buffer_sizeP);
+ // Is it from remote ENB
+ // We have to push it to the UE ?
+ if(ue_context_p->ue_context.handover_info->state != HO_COMPLETE) {
+ int result = pdcp_data_req(
+ ctxt,
+ srb_flagP,
+ rb_idP,
+ muiP, // mui
+ confirmP, // confirm
+ sdu_buffer_sizeP,
+ sdu_buffer_pP,
+ modeP,
+ sourceL2Id,
+ destinationL2Id
+ );
+ ue_context_p->ue_context.handover_info->forwarding_state = FORWARDING_NO_EMPTY;
+ return result;
+ } else { /* It is from from epc message */
+ /* in the source enb, UE in RRC_HO_EXECUTION mode */
+ // ?????
+ return true;
+ }
+ }
+ }
+ LOG_E(RRC,"This function should return before the end\n");
+ return false;
+}
+
void rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(
module_id_t enb_mod_idP,
@@ -181,21 +268,16 @@ void rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(
LOG_W(RRC, "[eNB] In %s: invalid UE\n", __func__);
return;
}
+ gtpv1u_enb_delete_tunnel_req_t tmp={0};
- MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_GTPU_ENB, NULL, 0,
- "0 GTPV1U_ENB_DELETE_TUNNEL_REQ rnti %x ",
- ue_context_pP->ue_context.eNB_ue_s1ap_id);
-
- MessageDef *msg = itti_alloc_new_message(TASK_RRC_ENB, 0, GTPV1U_ENB_DELETE_TUNNEL_REQ);
- memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg)));
- GTPV1U_ENB_DELETE_TUNNEL_REQ(msg).rnti = ue_context_pP->ue_context.rnti;
- GTPV1U_ENB_DELETE_TUNNEL_REQ(msg).from_gnb = 0;
- GTPV1U_ENB_DELETE_TUNNEL_REQ(msg).num_erab = ue_context_pP->ue_context.nb_of_e_rabs;
+ tmp.rnti = ue_context_pP->ue_context.rnti;
+ tmp.from_gnb = 0;
+ tmp.num_erab = ue_context_pP->ue_context.nb_of_e_rabs;
for (int e_rab = 0; e_rab < ue_context_pP->ue_context.nb_of_e_rabs; e_rab++) {
const rb_id_t gtp_ebi = ue_context_pP->ue_context.enb_gtp_ebi[e_rab];
- GTPV1U_ENB_DELETE_TUNNEL_REQ(msg).eps_bearer_id[e_rab] = gtp_ebi;
+ tmp.eps_bearer_id[e_rab] = gtp_ebi;
}
- itti_send_msg_to_task(TASK_GTPV1_U, ENB_MODULE_ID_TO_INSTANCE(enb_mod_idP), msg);
+ gtpv1u_delete_s1u_tunnel(enb_mod_idP,&tmp);
}
diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c
index 0e6d5b580f..f64a109f75 100644
--- a/openair2/RRC/LTE/rrc_eNB_S1AP.c
+++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c
@@ -48,11 +48,12 @@
#include "pdcp_primitives.h"
#include "UTIL/OSA/osa_defs.h"
-#include "msc.h"
+#include
#include "LTE_UERadioAccessCapabilityInformation.h"
#include "gtpv1u_eNB_task.h"
+#include
#include "RRC/LTE/rrc_eNB_GTPV1U.h"
#include "TLVDecoder.h"
@@ -1787,7 +1788,7 @@ int rrc_eNB_process_S1AP_E_RAB_RELEASE_COMMAND(MessageDef *msg_p, const char *ms
}
}
- itti_send_msg_to_task(TASK_GTPV1_U, instance, msg_delete_tunnels_p);
+ itti_send_msg_to_task(TASK_VARIABLE, instance, msg_delete_tunnels_p);
//S1AP_E_RAB_RELEASE_RESPONSE
rrc_eNB_send_S1AP_E_RAB_RELEASE_RESPONSE(&ctxt, ue_context_p, xid);
}
diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c
index 58c595a3d0..c9ab3a3a97 100644
--- a/openair2/RRC/NR/L2_nr_interface.c
+++ b/openair2/RRC/NR/L2_nr_interface.c
@@ -42,6 +42,7 @@
#include "NR_MIB.h"
#include "NR_BCCH-BCH-Message.h"
+#include "rrc_gNB_UE_context.h"
extern RAN_CONTEXT_t RC;
@@ -217,29 +218,22 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
const int CC_id,
const frame_t frameP,
const rb_id_t Srb_id,
+ const rnti_t rnti,
const uint8_t Nb_tb,
uint8_t *const buffer_pP ){
- asn_enc_rval_t enc_rval;
- uint8_t Sdu_size = 0;
- uint8_t sfn_msb = (uint8_t)((frameP>>4)&0x3f);
-
#ifdef DEBUG_RRC
LOG_D(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%ld\n",Mod_idP,Srb_id);
#endif
- rrc_gNB_carrier_data_t *carrier;
- NR_BCCH_BCH_Message_t *mib;
- NR_SRB_INFO *srb_info;
- char payload_size, *payload_pP;
-
- carrier = &RC.nrrrc[Mod_idP]->carrier;
- mib = &carrier->mib;
- srb_info = &carrier->Srb0;
-
- /* MIBCH */
+ // MIBCH
if ((Srb_id & RAB_OFFSET) == MIBCH) {
+ asn_enc_rval_t enc_rval;
+ uint8_t sfn_msb = (uint8_t)((frameP>>4)&0x3f);
+ rrc_gNB_carrier_data_t *carrier = &RC.nrrrc[Mod_idP]->carrier;
+ NR_BCCH_BCH_Message_t *mib = &carrier->mib;
+
// Currently we are getting the pdcch_ConfigSIB1 from the configuration file.
// Uncomment this function for a dynamic pdcch_ConfigSIB1.
//channel_bandwidth_t min_channel_bw = bw_10MHz; // Must be obtained based on TS 38.101-1 Table 5.3.5-1
@@ -269,7 +263,7 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
return (3);
}
- /* TODO BCCH SIB1 SIBs */
+ // TODO BCCH SIB1 SIBs
if ((Srb_id & RAB_OFFSET ) == BCCH) {
memcpy(&buffer_pP[0],
RC.nrrrc[Mod_idP]->carrier.SIB1,
@@ -278,29 +272,54 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
return RC.nrrrc[Mod_idP]->carrier.sizeof_SIB1;
}
- /* CCCH */
+ // CCCH
if( (Srb_id & RAB_OFFSET ) == CCCH) {
- //struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[Mod_idP],rnti);
- //if (ue_context_p == NULL) return(0);
- //eNB_RRC_UE_t *ue_p = &ue_context_p->ue_context;
- LOG_D(RRC,"[gNB %d] Frame %d CCCH request (Srb_id %ld)\n", Mod_idP, frameP, Srb_id);
- // srb_info=&ue_p->Srb0;
+ char *payload_pP;
+ uint8_t Sdu_size = 0;
+ struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[Mod_idP], rnti);
- payload_size = srb_info->Tx_buffer.payload_size;
+ LOG_D(NR_RRC,"[gNB %d] Frame %d CCCH request (Srb_id %ld)\n", Mod_idP, frameP, Srb_id);
+
+ char payload_size = ue_context_p->ue_context.Srb0.Tx_buffer.payload_size;
// check if data is there for MAC
if (payload_size > 0) {
- payload_pP = srb_info->Tx_buffer.Payload;
- LOG_D(RRC,"[gNB %d] CCCH (%p) has %d bytes (dest: %p, src %p)\n", Mod_idP, srb_info, payload_size, buffer_pP, payload_pP);
+ payload_pP = ue_context_p->ue_context.Srb0.Tx_buffer.Payload;
+ LOG_D(NR_RRC,"[gNB %d] CCCH has %d bytes (dest: %p, src %p)\n", Mod_idP, payload_size, buffer_pP, payload_pP);
// Fill buffer
memcpy((void *)buffer_pP, (void*)payload_pP, payload_size);
Sdu_size = payload_size;
- srb_info->Tx_buffer.payload_size = 0;
+ ue_context_p->ue_context.Srb0.Tx_buffer.payload_size = 0;
}
return Sdu_size;
}
return(0);
+}
+
+int8_t nr_mac_rrc_data_ind(const module_id_t module_idP,
+ const int CC_id,
+ const frame_t frameP,
+ const sub_frame_t sub_frameP,
+ const int UE_id,
+ const rnti_t rntiP,
+ const rb_id_t srb_idP,
+ const uint8_t *sduP,
+ const sdu_size_t sdu_lenP,
+ const boolean_t brOption) {
+
+ protocol_ctxt_t ctxt;
+ PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, GNB_FLAG_YES, rntiP, frameP, sub_frameP,0);
+
+ if((srb_idP & RAB_OFFSET) == CCCH) {
+ LOG_D(NR_RRC, "[gNB %d] Received SDU for CCCH on SRB %ld\n", module_idP, srb_idP);
+ ctxt.brOption = brOption;
+ if (sdu_lenP > 0) {
+ nr_rrc_gNB_decode_ccch(&ctxt, sduP, sdu_lenP, CC_id);
+ }
+ }
+
+ return 0;
}
\ No newline at end of file
diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c
index 6c28beec34..a26a4ac5b1 100644
--- a/openair2/RRC/NR/MESSAGES/asn1_msg.c
+++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c
@@ -326,7 +326,7 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier,
// cellSelectionInfo
sib1->cellSelectionInfo = CALLOC(1,sizeof(struct NR_SIB1__cellSelectionInfo));
- sib1->cellSelectionInfo->q_RxLevMin = -50;
+ sib1->cellSelectionInfo->q_RxLevMin = -65;
// cellAccessRelatedInfo
struct NR_PLMN_IdentityInfo *nr_plmn_info=CALLOC(1,sizeof(struct NR_PLMN_IdentityInfo));
@@ -418,7 +418,8 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier,
nrMultiBandInfo->freqBandIndicatorNR = configuration->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[i];
ASN_SEQUENCE_ADD(&sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.frequencyBandList.list,nrMultiBandInfo);
}
- sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.offsetToPointA = configuration->scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier;
+ //sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.offsetToPointA = configuration->scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier;
+ sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.offsetToPointA = 86;
for(int i = 0; i< configuration->scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.count; i++) {
ASN_SEQUENCE_ADD(&sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.scs_SpecificCarrierList.list,configuration->scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[i]);
}
diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h
index 5aafbaee4c..ea7b853c03 100644
--- a/openair2/RRC/NR/nr_rrc_proto.h
+++ b/openair2/RRC/NR/nr_rrc_proto.h
@@ -51,6 +51,7 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
const int CC_id,
const frame_t frameP,
const rb_id_t Srb_id,
+ const rnti_t rnti,
const uint8_t Nb_tb,
uint8_t *const buffer_pP );
@@ -158,6 +159,24 @@ int
nr_rrc_mac_remove_ue(module_id_t mod_idP,
rnti_t rntiP);
+int8_t nr_mac_rrc_data_ind(
+ const module_id_t module_idP,
+ const int CC_id,
+ const frame_t frameP,
+ const sub_frame_t sub_frameP,
+ const int UE_id,
+ const rnti_t rntiP,
+ const rb_id_t srb_idP,
+ const uint8_t *sduP,
+ const sdu_size_t sdu_lenP,
+ const boolean_t brOption
+);
+
+int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP,
+ const uint8_t *buffer,
+ int buffer_length,
+ const int CC_id);
+
void
rrc_gNB_generate_dedicatedRRCReconfiguration_release(
const protocol_ctxt_t *const ctxt_pP,
diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c
index 9bea266ffd..dca6587d45 100755
--- a/openair2/RRC/NR/rrc_gNB.c
+++ b/openair2/RRC/NR/rrc_gNB.c
@@ -1388,7 +1388,7 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP,
break;
case NR_UL_CCCH_MessageType__c1_PR_rrcSetupRequest:
- LOG_I(NR_RRC, "Received RRCSetupRequest on UL-CCCH-Message (UE rnti %x)\n", ctxt_pP->rnti);
+ LOG_D(NR_RRC, "Received RRCSetupRequest on UL-CCCH-Message (UE rnti %x)\n", ctxt_pP->rnti);
ue_context_p = rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rnti);
if (ue_context_p != NULL) {
rrc_gNB_free_mem_UE_context(ctxt_pP, ue_context_p);
@@ -1495,15 +1495,16 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP,
CC_id);
break;
}
- }
- if (ue_context_p != NULL) {
ue_context_p->ue_context.establishment_cause = rrcSetupRequest->establishmentCause;
- }
- rrc_gNB_generate_RRCSetup(ctxt_pP,
- rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rnti),
- CC_id);
+ rrc_gNB_generate_RRCSetup(ctxt_pP,
+ rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rnti),
+ CC_id);
+
+ // FIXME: Check the best place to perform this DRB configuration
+ nr_DRB_preconfiguration(ctxt_pP->rnti);
+ }
break;
case NR_UL_CCCH_MessageType__c1_PR_rrcResumeRequest:
diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c
index c1efc9550c..2336c758fc 100644
--- a/openair2/RRC/NR/rrc_gNB_nsa.c
+++ b/openair2/RRC/NR/rrc_gNB_nsa.c
@@ -39,6 +39,7 @@
#include "openair2/RRC/LTE/rrc_eNB_GTPV1U.h"
#include "executables/softmodem-common.h"
#include
+#include
#include "UTIL/OSA/osa_defs.h"
extern boolean_t nr_rrc_pdcp_config_asn1_req(
@@ -425,7 +426,7 @@ void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti) {
ue_context->ue_context.gnb_gtp_ebi[e_rab] = 0;
}
- itti_send_msg_to_task(TASK_GTPV1_U, rrc->module_id, msg_delete_tunnels_p);
+ itti_send_msg_to_task(TASK_VARIABLE, rrc->module_id, msg_delete_tunnels_p);
/* remove context */
rrc_gNB_remove_ue_context(&ctxt, rrc, ue_context);
diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c
index 8e60dafb27..cd5ded9714 100644
--- a/openair2/RRC/NR/rrc_gNB_reconfig.c
+++ b/openair2/RRC/NR/rrc_gNB_reconfig.c
@@ -186,8 +186,8 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
secondaryCellGroup->mac_CellGroupConfig->drx_Config = NULL;
secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig = 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_sf80;
- secondaryCellGroup->mac_CellGroupConfig->bsr_Config->retxBSR_Timer = NR_BSR_Config__retxBSR_Timer_sf320;
+ 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;
secondaryCellGroup->mac_CellGroupConfig->tag_Config=calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->tag_Config));
secondaryCellGroup->mac_CellGroupConfig->tag_Config->tag_ToReleaseList = NULL;
secondaryCellGroup->mac_CellGroupConfig->tag_Config->tag_ToAddModList = calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->tag_Config->tag_ToAddModList));
@@ -228,33 +228,38 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
secondaryCellGroup->spCellConfig->reconfigurationWithSync->t304=NR_ReconfigurationWithSync__t304_ms2000;
secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated = NULL;
secondaryCellGroup->spCellConfig->reconfigurationWithSync->ext1 = NULL;
- /* contention free ra */
- secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated = calloc(1,sizeof(struct NR_ReconfigurationWithSync__rach_ConfigDedicated));
- secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->present= NR_ReconfigurationWithSync__rach_ConfigDedicated_PR_uplink;
- secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink= calloc(1,sizeof(struct NR_RACH_ConfigDedicated));
- secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra= calloc(1,sizeof(struct NR_CFRA));
- secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->ra_Prioritization= NULL;
- secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions= calloc(1,sizeof(struct NR_CFRA__occasions));
- memcpy(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->rach_ConfigGeneric,
- &servingcellconfigcommon->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric, sizeof(NR_RACH_ConfigGeneric_t));
- secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion= calloc(1,sizeof(long));
- *secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion = NR_CFRA__occasions__ssb_perRACH_Occasion_one;
- secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.present = NR_CFRA__resources_PR_ssb;
- secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb = calloc(1,sizeof(struct NR_CFRA__resources__ssb));
- secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ra_ssb_OccasionMaskIndex = 0;
- int n_ssb = 0;
- struct NR_CFRA_SSB_Resource *ssbElem[64];
- for (int i=0;i<64;i++) {
- 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;
- ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[n_ssb]);
- n_ssb++;
+ // For 2-step contention-free random access procedure
+ if(get_softmodem_params()->sa == 0) {
+ secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated = calloc(1,sizeof(struct NR_ReconfigurationWithSync__rach_ConfigDedicated));
+ secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->present= NR_ReconfigurationWithSync__rach_ConfigDedicated_PR_uplink;
+ secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink= calloc(1,sizeof(struct NR_RACH_ConfigDedicated));
+ secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra= calloc(1,sizeof(struct NR_CFRA));
+ secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->ra_Prioritization= NULL;
+ secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions= calloc(1,sizeof(struct NR_CFRA__occasions));
+ memcpy(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->rach_ConfigGeneric,
+ &servingcellconfigcommon->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric, sizeof(NR_RACH_ConfigGeneric_t));
+ secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion= calloc(1,sizeof(long));
+ *secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion = NR_CFRA__occasions__ssb_perRACH_Occasion_one;
+ secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.present = NR_CFRA__resources_PR_ssb;
+ secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb = calloc(1,sizeof(struct NR_CFRA__resources__ssb));
+ secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ra_ssb_OccasionMaskIndex = 0;
+
+ int n_ssb = 0;
+ struct NR_CFRA_SSB_Resource *ssbElem[64];
+ for (int i=0;i<64;i++) {
+ 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;
+ ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem[n_ssb]);
+ n_ssb++;
+ }
}
+
+ secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->ext1 = NULL;
}
- secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->ext1 = NULL;
+
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));
@@ -294,7 +299,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList=calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList));
- n_ssb = 0;
+ int n_ssb = 0;
NR_TCI_State_t *tcic[64];
for (int i=0;i<64;i++) {
if ((bitmap>>(63-i))&0x01){
@@ -537,7 +542,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
ss->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0 = calloc(1,sizeof(*ss->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0));
ASN_SEQUENCE_ADD(&bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list,ss);
-
+
bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1=calloc(1,sizeof(*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1));
*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceSIB1=0;
@@ -1031,7 +1036,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
long *delay[8];
for (int i=0;i<8;i++) {
delay[i] = calloc(1,sizeof(*delay[i]));
- *delay[i] = (i<6) ? (i+2) : 0;
+ *delay[i] = i+2;
ASN_SEQUENCE_ADD(&pucch_Config->dl_DataToUL_ACK->list,delay[i]);
}
pucch_Config->spatialRelationInfoToAddModList = calloc(1,sizeof(*pucch_Config->spatialRelationInfoToAddModList));
diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c
index e21859ded8..c78a1caf37 100644
--- a/openair2/RRC/NR_UE/L2_interface_ue.c
+++ b/openair2/RRC/NR_UE/L2_interface_ue.c
@@ -42,17 +42,71 @@ nr_mac_rrc_data_ind_ue(
const module_id_t module_id,
const int CC_id,
const uint8_t gNB_index,
+ const frame_t frame,
+ const sub_frame_t sub_frame,
+ const rnti_t rnti,
const channel_t channel,
const uint8_t* pduP,
const sdu_size_t pdu_len){
+ sdu_size_t sdu_size = 0;
switch(channel){
case NR_BCCH_BCH:
AssertFatal( nr_rrc_ue_decode_NR_BCCH_BCH_Message(module_id, gNB_index, (uint8_t*)pduP, pdu_len) == 0, "UE decode BCCH-BCH error!\n");
break;
+
case NR_BCCH_DL_SCH:
- AssertFatal( nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(module_id, gNB_index, (uint8_t*)pduP, pdu_len, 0, 0) == 0, "UE decode BCCH-DL-SCH error!\n");
+ if (pdu_len>0) {
+ LOG_T(NR_RRC, "[UE %d] Received SDU for NR-BCCH-DL-SCH on SRB %u from gNB %d\n", module_id, channel & RAB_OFFSET,
+ gNB_index);
+
+ MessageDef *message_p;
+ int msg_sdu_size = BCCH_SDU_SIZE;
+
+ if (pdu_len > msg_sdu_size) {
+ LOG_E(NR_RRC, "SDU larger than NR-BCCH-DL-SCH SDU buffer size (%d, %d)", sdu_size, msg_sdu_size);
+ sdu_size = msg_sdu_size;
+ } else {
+ sdu_size = pdu_len;
+ }
+
+ message_p = itti_alloc_new_message(TASK_MAC_UE, 0, NR_RRC_MAC_BCCH_DATA_IND);
+ memset(NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu, 0, BCCH_SDU_SIZE);
+ memcpy(NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu, pduP, sdu_size);
+ NR_RRC_MAC_BCCH_DATA_IND (message_p).frame = frame; //frameP
+ NR_RRC_MAC_BCCH_DATA_IND (message_p).sub_frame = sub_frame; //sub_frameP
+ NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu_size = sdu_size;
+ NR_RRC_MAC_BCCH_DATA_IND (message_p).gnb_index = gNB_index;
+ itti_send_msg_to_task(TASK_RRC_NRUE, GNB_MODULE_ID_TO_INSTANCE(module_id), message_p);
+ }
break;
+
+ case CCCH:
+ if (pdu_len>0) {
+ LOG_T(NR_RRC,"[UE %d] Received SDU for CCCH on SRB %u from gNB %d\n",module_id,channel & RAB_OFFSET,gNB_index);
+
+ MessageDef *message_p;
+ int msg_sdu_size = CCCH_SDU_SIZE;
+
+ if (pdu_len > msg_sdu_size) {
+ LOG_E(NR_RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", sdu_size, msg_sdu_size);
+ sdu_size = msg_sdu_size;
+ } else {
+ sdu_size = pdu_len;
+ }
+
+ message_p = itti_alloc_new_message (TASK_MAC_UE, 0, NR_RRC_MAC_CCCH_DATA_IND);
+ memset (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE);
+ memcpy (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, pduP, sdu_size);
+ NR_RRC_MAC_CCCH_DATA_IND (message_p).frame = frame; //frameP
+ NR_RRC_MAC_CCCH_DATA_IND (message_p).sub_frame = sub_frame; //sub_frameP
+ NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = sdu_size;
+ NR_RRC_MAC_CCCH_DATA_IND (message_p).gnb_index = gNB_index;
+ NR_RRC_MAC_CCCH_DATA_IND (message_p).rnti = rnti; //rntiP
+ itti_send_msg_to_task (TASK_RRC_NRUE, GNB_MODULE_ID_TO_INSTANCE( module_id ), message_p);
+ }
+ break;
+
default:
break;
}
diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c
index f373d74230..def7ca6404 100644
--- a/openair2/RRC/NR_UE/rrc_UE.c
+++ b/openair2/RRC/NR_UE/rrc_UE.c
@@ -72,6 +72,7 @@
#include "nr_nas_msg_sim.h"
#endif
+NR_UE_RRC_INST_t *NR_UE_rrc_inst;
/* NAS Attach request with IMSI */
static const char nr_nas_attach_req_imsi[] = {
0x07, 0x41,
@@ -1365,10 +1366,10 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB
(void **)&dl_ccch_msg,
(uint8_t *)Srb_info->Rx_buffer.Payload,
100,0,0);
-
- // if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
+
+ if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
xer_fprint(stdout,&asn_DEF_NR_DL_CCCH_Message,(void *)dl_ccch_msg);
- // }
+ }
if ((dec_rval.code != RC_OK) && (dec_rval.consumed==0)) {
LOG_E(RRC,"[UE %d] Frame %d : Failed to decode DL-CCCH-Message (%zu bytes)\n",ctxt_pP->module_id,ctxt_pP->frame,dec_rval.consumed);
@@ -2472,7 +2473,6 @@ void *rrc_nrue_task( void *args_p ) {
case NR_RRC_MAC_BCCH_DATA_IND:
LOG_D(NR_RRC, "[UE %d] Received %s: frameP %d, gNB %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p),
NR_RRC_MAC_BCCH_DATA_IND (msg_p).frame, NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index);
- // PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_NO, NOT_A_RNTI, RRC_MAC_BCCH_DATA_IND (msg_p).frame, 0);
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NOT_A_RNTI, NR_RRC_MAC_BCCH_DATA_IND (msg_p).frame, 0,NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index);
nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message (ctxt.module_id,
NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index,
@@ -2480,6 +2480,7 @@ void *rrc_nrue_task( void *args_p ) {
NR_RRC_MAC_BCCH_DATA_IND (msg_p).sdu_size,
NR_RRC_MAC_BCCH_DATA_IND (msg_p).rsrq,
NR_RRC_MAC_BCCH_DATA_IND (msg_p).rsrp);
+ break;
case NR_RRC_MAC_CCCH_DATA_IND:
LOG_D(NR_RRC, "[UE %d] RNTI %x Received %s: frameP %d, gNB %d\n",
@@ -2568,7 +2569,7 @@ void *rrc_nrue_task( void *args_p ) {
LOG_E(NR_RRC, "[UE %d] Received unexpected message %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p));
break;
}
- LOG_I(NR_RRC, "[UE %d] RRC Status %d\n", ue_mod_id, nr_rrc_get_state(ue_mod_id));
+ LOG_D(NR_RRC, "[UE %d] RRC Status %d\n", ue_mod_id, nr_rrc_get_state(ue_mod_id));
result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
msg_p = NULL;
diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h
index 0acf6db634..534da0112b 100644
--- a/openair2/RRC/NR_UE/rrc_proto.h
+++ b/openair2/RRC/NR_UE/rrc_proto.h
@@ -109,7 +109,15 @@ int8_t nr_rrc_ue_decode_NR_DL_DCCH_Message(const module_id_t module_id, const ui
\param channel indicator for channel of the pdu
\param pduP pointer to pdu
\param pdu_len data length of pdu*/
-int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, const channel_t channel, const uint8_t* pduP, const sdu_size_t pdu_len);
+int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id,
+ const int CC_id,
+ const uint8_t gNB_index,
+ const frame_t frame,
+ const sub_frame_t sub_frame,
+ const rnti_t rnti,
+ const channel_t channel,
+ const uint8_t* pduP,
+ const sdu_size_t pdu_len);
/**\brief
\param module_id module id
diff --git a/openair2/RRC/NR_UE/rrc_vars.h b/openair2/RRC/NR_UE/rrc_vars.h
index 5c74e5b5a8..30c74debdd 100644
--- a/openair2/RRC/NR_UE/rrc_vars.h
+++ b/openair2/RRC/NR_UE/rrc_vars.h
@@ -36,6 +36,6 @@
#include "rrc_defs.h"
-NR_UE_RRC_INST_t *NR_UE_rrc_inst;
+extern NR_UE_RRC_INST_t *NR_UE_rrc_inst;
#endif
diff --git a/openair2/SIMULATION/NR_RRC/itti_sim.c b/openair2/SIMULATION/NR_RRC/itti_sim.c
index 9b35ea6721..d583346a89 100644
--- a/openair2/SIMULATION/NR_RRC/itti_sim.c
+++ b/openair2/SIMULATION/NR_RRC/itti_sim.c
@@ -87,8 +87,6 @@ pthread_mutex_t nfapi_sync_mutex;
int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex
uint8_t nfapi_mode = 0; // Default to monolithic mode
-uint32_t target_dl_mcs = 28;
-uint32_t target_ul_mcs = 20;
uint32_t timing_advance = 0;
uint64_t num_missed_slots=0;
@@ -120,7 +118,6 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
//Temp fix for inexistent NR upper layer
unsigned char NB_gNB_INST = 1;
-static char *itti_dump_file = NULL;
int UE_scan = 1;
int UE_scan_carrier = 0;
@@ -148,7 +145,6 @@ extern void *udp_eNB_task(void *args_p);
int transmission_mode=1;
int emulate_rf = 0;
int numerology = 0;
-int usrp_tx_thread = 0;
double cpuf;
diff --git a/openair2/UTIL/OCG/OCG.h b/openair2/UTIL/OCG/OCG.h
index 34190f7d15..58cc7184e7 100644
--- a/openair2/UTIL/OCG/OCG.h
+++ b/openair2/UTIL/OCG/OCG.h
@@ -667,7 +667,6 @@ typedef struct {
unsigned char omv_enabled; // openair mobility visulizer
unsigned char opp_enabled; // openair performance profiler
unsigned char oeh_enabled; // openair event handler, with CLI this could provide a remote event management
- char *itti_dump_file;
unsigned char vcd_enabled;
char *vcd_file;
unsigned char eMBMS_active_state;
@@ -717,12 +716,6 @@ typedef struct {
*/
unsigned char slot_isr;
int slot_sfd;
- rnti_t eNB_ue_module_id_to_rnti[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX];/*!< \brief used by eNB, this array can be filled:
- by local virtualization: set directly by UE, or by remote UEs: TODO add signalisation on ethernet emulation link from UE to eNB*/
-
- module_id_t eNB_ue_local_uid_to_ue_module_id[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX];/*!< \brief used by eNB, this array can be filled:
- by local virtualization: set directly by UE, or by remote UEs: TODO add signalisation on ethernet emulation link from UE to eNB*/
-
} Info;
/* @}*/
diff --git a/openair3/GTPV1-U/gtpv1u_eNB.c b/openair3/GTPV1-U/gtpv1u_eNB.c
index 847002ab44..e1ea5cb08e 100644
--- a/openair3/GTPV1-U/gtpv1u_eNB.c
+++ b/openair3/GTPV1-U/gtpv1u_eNB.c
@@ -51,6 +51,7 @@
#include "gtpv1u_eNB_defs.h"
#include "gtpv1u_eNB_task.h"
#include "rrc_eNB_GTPV1U.h"
+#include
#undef GTP_DUMP_SOCKET
@@ -308,7 +309,7 @@ NwGtpv1uRcT gtpv1u_eNB_process_stack_req(
msgsrc != GTPV1U_MSG_FROM_SOURCE_ENB? "UDP DATA" :
msgType == NW_GTP_END_MARKER?"END MARKER":"DATA FORWARDING");
- /* target enb */
+ /* target enb */
if(msgType == NW_GTP_END_MARKER) {
LOG_I(GTPU, "target end receive END MARKER\n");
ue_context_p->ue_context.handover_info->state = HO_END_MARKER;
@@ -1497,15 +1498,15 @@ void *gtpv1u_eNB_process_itti_msg(void *notUsed) {
stack_req.apiInfo.sendtoInfo.teid = tenb_x2u_teid;
stack_req.apiInfo.sendtoInfo.ipAddr = gtpv1u_ue_data_p->bearers[data_req_p->rab_id - GTPV1U_BEARER_OFFSET].tenb_ip_addr;// target enb ip
rc = nwGtpv1uGpduMsgNew(
- RC.gtpv1u_data_g->gtpv1u_stack,
- tenb_x2u_teid,
- NW_FALSE,
- RC.gtpv1u_data_g->seq_num++,
- data_req_p->buffer,
- data_req_p->length,
- data_req_p->offset,
- &(stack_req.apiInfo.sendtoInfo.hMsg));
-
+ RC.gtpv1u_data_g->gtpv1u_stack,
+ tenb_x2u_teid,
+ NW_FALSE,
+ RC.gtpv1u_data_g->seq_num++,
+ data_req_p->buffer,
+ data_req_p->length,
+ data_req_p->offset,
+ &(stack_req.apiInfo.sendtoInfo.hMsg));
+
if (rc != NW_GTPV1U_OK) {
LOG_E(GTPU, "nwGtpv1uGpduMsgNew failed: 0x%x\n", rc);
MSC_LOG_EVENT(MSC_GTPU_ENB,"0 Failed send G-PDU ltid %u rtid %u size %u",
@@ -1515,7 +1516,7 @@ void *gtpv1u_eNB_process_itti_msg(void *notUsed) {
pMsg = (NwGtpv1uMsgT *) stack_req.apiInfo.sendtoInfo.hMsg;
pMsg->msgType = NW_GTP_END_MARKER;
rc = nwGtpv1uProcessUlpReq(RC.gtpv1u_data_g->gtpv1u_stack, &stack_req);
-
+
if (rc != NW_GTPV1U_OK) {
LOG_E(GTPU, "nwGtpv1uProcessUlpReq failed: 0x%x\n", rc);
MSC_LOG_EVENT(MSC_GTPU_ENB,"0 Failed send G-PDU ltid %u rtid %u size %u",
@@ -1535,11 +1536,11 @@ void *gtpv1u_eNB_process_itti_msg(void *notUsed) {
rc = nwGtpv1uMsgDelete(RC.gtpv1u_data_g->gtpv1u_stack,
stack_req.apiInfo.sendtoInfo.hMsg);
-
+
if (rc != NW_GTPV1U_OK) {
LOG_E(GTPU, "nwGtpv1uMsgDelete failed: 0x%x\n", rc);
}
-
+
gtpv1u_enb_delete_tunnel_req_t delete_tunnel_req;
memset(&delete_tunnel_req, 0, sizeof(delete_tunnel_req));
delete_tunnel_req.rnti = data_req_p->rnti;
@@ -1547,7 +1548,7 @@ void *gtpv1u_eNB_process_itti_msg(void *notUsed) {
}
}
}
-
+
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GTPV1U_PROCESS_TUNNEL_DATA_REQ, VCD_FUNCTION_OUT);
}
break;
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/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c
index 178f21a44a..be887623bb 100644
--- a/openair3/NAS/UE/nas_ue_task.c
+++ b/openair3/NAS/UE/nas_ue_task.c
@@ -33,6 +33,7 @@
# include "memory.h"
#include "nas_user.h"
+#include
// FIXME make command line option for NAS_UE_AUTOSTART
# define NAS_UE_AUTOSTART 1
diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp
new file mode 100644
index 0000000000..29633ba6ae
--- /dev/null
+++ b/openair3/ocp-gtpu/gtp_itf.cpp
@@ -0,0 +1,783 @@
+#include