diff --git a/.gitignore b/.gitignore
index 8f8ff1f454..ff947966a2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,3 +12,9 @@ targets/bin/
# vscode
.vscode
+
+# Tags for vim/global
+GPATH
+GRTAGS
+GTAGS
+tags
diff --git a/ci-scripts/args_parse.py b/ci-scripts/args_parse.py
index 1249f52172..84b3a84514 100644
--- a/ci-scripts/args_parse.py
+++ b/ci-scripts/args_parse.py
@@ -34,7 +34,7 @@
import sys # arg
import re # reg
import yaml
-
+import constants as CONST
#-----------------------------------------------------------
# Parsing Command Line Arguements
diff --git a/ci-scripts/cls_cots_ue.py b/ci-scripts/cls_cots_ue.py
index 6954aa3927..59c2713b47 100644
--- a/ci-scripts/cls_cots_ue.py
+++ b/ci-scripts/cls_cots_ue.py
@@ -27,61 +27,111 @@
# pexpect
#---------------------------------------------------------------------
+#to use isfile
+import os
+import sys
#to use logging.info()
import logging
#to create a SSH object locally in the methods
import sshconnection
#time.sleep
import time
+#to load cots_ue dictionary
+import yaml
class CotsUe:
- def __init__(self,model,UEIPAddr,UEUserName,UEPassWord):
- self.model = model
- self.UEIPAddr = UEIPAddr
- self.UEUserName = UEUserName
- self.UEPassWord = UEPassWord
- self.runargs = '' #on of off to toggle airplane mode on/off
+ def __init__(self,ADBIPAddr,ADBUserName,ADBPassWord):
+ self.cots_id = '' #cots id from yaml oppo, s10 etc...
+ self.ADBIPAddr = ADBIPAddr
+ self.ADBUserName = ADBUserName
+ self.ADBPassWord = ADBPassWord
+ self.cots_run_mode = '' #on of off to toggle airplane mode on/off
+ self.__cots_cde_dict_file = 'cots_ue_ctl.yaml'
self.__SetAirplaneRetry = 3
+
#-----------------$
#PUBLIC Methods$
#-----------------$
def Check_Airplane(self):
mySSH = sshconnection.SSHConnection()
- mySSH.open(self.UEIPAddr, self.UEUserName, self.UEPassWord)
- status=mySSH.cde_check_value('sudo adb shell settings get global airplane_mode_on ', ['0','1'],5)
+ mySSH.open(self.ADBIPAddr, self.ADBUserName, self.ADBPassWord)
+ status=mySSH.cde_check_value('adb shell settings get global airplane_mode_on ', ['0','1'],5)
mySSH.close()
return status
-
- def Set_Airplane(self,target_state_str):
- mySSH = sshconnection.SSHConnection()
- mySSH.open(self.UEIPAddr, self.UEUserName, self.UEPassWord)
- mySSH.command('sudo adb start-server','$',5)
- logging.info("Toggling COTS UE Airplane mode to : "+target_state_str)
- current_state = self.Check_Airplane()
- if target_state_str.lower()=="on":
- target_state=1
+ #simply check if the device id exists in the dictionary
+ #returns true if it exists, false otherwise
+ def Check_Exists(self,target_id):
+ #load cots commands dictionary
+ if (os.path.isfile(self.__cots_cde_dict_file)):
+ yaml_file=self.__cots_cde_dict_file
+ elif (os.path.isfile('ci-scripts/'+self.__cots_cde_dict_file)):
+ yaml_file='ci-scripts/'+self.__cots_cde_dict_file
else:
- target_state=0
- if current_state != target_state:
- #toggle state
- retry = 0
- while (current_state!=target_state) and (retry < self.__SetAirplaneRetry):
- mySSH.command('sudo adb shell am start -a android.settings.AIRPLANE_MODE_SETTINGS', '\$', 5)
- mySSH.command('sudo adb shell input keyevent 20', '\$', 5)
- mySSH.command('sudo adb shell input tap 968 324', '\$', 5)
- time.sleep(1)
- current_state = self.Check_Airplane()
- retry+=1
+ logging.error("COTS UE dictionary yaml file cannot be found")
+ sys.exit("COTS UE dictionary yaml file cannot be found")
+
+ #load cots commands dictionary
+ with open(yaml_file,'r') as file:
+ cots_ue_ctl = yaml.load(file,Loader=yaml.FullLoader)
+ #check if ue id is in the dictionary
+ if target_id in cots_ue_ctl:
+ return True
+ else:
+ return False
+
+ def Set_Airplane(self, target_id, target_state_str):
+ #loading cots commands dictionary
+
+ if (os.path.isfile(self.__cots_cde_dict_file)):
+ yaml_file=self.__cots_cde_dict_file
+ elif (os.path.isfile('ci-scripts/'+self.__cots_cde_dict_file)):
+ yaml_file='ci-scripts/'+self.__cots_cde_dict_file
+ else:
+ logging.error("COTS UE dictionary yaml file cannot be found")
+ sys.exit("COTS UE dictionary yaml file cannot be found")
+
+ #load cots commands dictionary
+ with open(yaml_file,'r') as file:
+ cots_ue_ctl = yaml.load(file,Loader=yaml.FullLoader)
+ #check if ue id is in the dictionary
+ if target_id in cots_ue_ctl:
+ mySSH = sshconnection.SSHConnection()
+ mySSH.open(self.ADBIPAddr, self.ADBUserName, self.ADBPassWord)
+ logging.info(str(self.ADBIPAddr)+' '+str(self.ADBUserName)+' '+str(self.ADBPassWord))
+ mySSH.command('adb start-server','\$',5)
+ mySSH.command('adb devices','\$',5)
+ logging.info("Toggling COTS UE Airplane mode to : "+target_state_str)
+ #get current state
+ current_state = self.Check_Airplane()
+ if target_state_str.lower()=="on":
+ target_state=1
+ else:
+ target_state=0
if current_state != target_state:
- logging.error("ATTENTION : Could not toggle to : "+target_state_str)
- logging.error("Current state is : "+ str(current_state))
+ #toggle state
+ retry = 0
+ while (current_state!=target_state) and (retry < self.__SetAirplaneRetry):
+ #loop over the command list from dictionary for the selected ue, to switch to required state
+ for i in range (0,len(cots_ue_ctl[target_id])):
+ mySSH.command(cots_ue_ctl[target_id][i], '\$', 5)
+ time.sleep(1)
+ current_state = self.Check_Airplane()
+ retry+=1
+ #could not toggle despite the retry
+ if current_state != target_state:
+ logging.error("ATTENTION : Could not toggle to : "+target_state_str)
+ logging.error("Current state is : "+ str(current_state))
+ else:
+ logging.info("Airplane mode is already "+ target_state_str)
+ mySSH.command('adb kill-server','\$',5)
+ mySSH.close()
+ #ue id is NOT in the dictionary
else:
- print("Airplane mode is already "+ target_state_str)
- mySSH.command('sudo adb kill-server','$',5)
- mySSH.close()
+ logging.error("COTS UE Id from XML could not be found in UE YAML dictionary " + self.__cots_cde_dict_file)
+ sys.exit("COTS UE Id from XML could not be found in UE YAML dictionary " + self.__cots_cde_dict_file)
diff --git a/ci-scripts/cots_ue_ctl.yaml b/ci-scripts/cots_ue_ctl.yaml
new file mode 100644
index 0000000000..c22fca246b
--- /dev/null
+++ b/ci-scripts/cots_ue_ctl.yaml
@@ -0,0 +1,20 @@
+9d690a12: #oppo
+ - adb shell input keyevent KEYCODE_POWER
+ - adb shell input swipe 300 700 300 0
+ - adb shell am start -a android.settings.AIRPLANE_MODE_SETTINGS
+ - adb shell input keyevent 20
+ - adb shell input tap 968 324
+002: #s10
+ - adb shell input keyevent KEYCODE_POWER
+ - adb shell input swipe 200 900 200 300
+ - adb shell am start -a android.settings.AIRPLANE_MODE_SETTINGS
+ - adb shell input tap 968 324
+003: #s20
+ - adb shell input keyevent KEYCODE_POWER
+ - adb shell input swipe 200 900 200 300
+ - adb shell am start -a android.settings.AIRPLANE_MODE_SETTINGS
+ - adb shell input tap 968 324
+004: #xperia
+ - tbd
+ - tbd
+ - tbd
diff --git a/ci-scripts/main.py b/ci-scripts/main.py
index d37f205f4e..86fd9d84df 100644
--- a/ci-scripts/main.py
+++ b/ci-scripts/main.py
@@ -285,21 +285,29 @@ class OaiCiTest():
SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60)
SSH.close()
return
- # enable data service
- SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "svc data enable"', '\$', 60)
- # The following commands are deprecated since we no longer work on Android 7+
- # SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell settings put global airplane_mode_on 1', '\$', 10)
- # SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true', '\$', 60)
- # a dedicated script has to be installed inside the UE
- # airplane mode on means call /data/local/tmp/off
- if device_id == '84B7N16418004022':
- SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60)
+ #RH quick add-on to integrate cots control defined by yaml
+ #if device_id exists in yaml dictionary, we execute the new procedure defined in cots_ue class
+ #otherwise we use the legacy procedure
+ if COTS_UE.Check_Exists(device_id):
+ #switch device to Airplane mode ON (ie Radio OFF)
+ COTS_UE.Set_Airplane(device_id, 'ON')
else:
- SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60)
- #airplane mode off means call /data/local/tmp/on
- logging.debug('\u001B[1mUE (' + device_id + ') Initialize Completed\u001B[0m')
- SSH.close()
+ # enable data service
+ SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "svc data enable"', '\$', 60)
+
+ # The following commands are deprecated since we no longer work on Android 7+
+ # SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell settings put global airplane_mode_on 1', '\$', 10)
+ # SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true', '\$', 60)
+ # a dedicated script has to be installed inside the UE
+ # airplane mode on means call /data/local/tmp/off
+ if device_id == '84B7N16418004022':
+ SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60)
+ else:
+ SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60)
+ #airplane mode off means call /data/local/tmp/on
+ logging.debug('\u001B[1mUE (' + device_id + ') Initialize Completed\u001B[0m')
+ SSH.close()
except:
os.kill(os.getppid(),signal.SIGUSR1)
@@ -790,7 +798,13 @@ class OaiCiTest():
try:
SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
if self.ADBCentralized:
- if device_id == '84B7N16418004022':
+ #RH quick add on to integrate cots control defined by yaml
+ #if device Id exists in yaml dictionary, we execute the new procedure defined in cots_ue class
+ #otherwise we use the legacy procedure
+ if COTS_UE.Check_Exists(device_id):
+ #switch device to Airplane mode OFF (ie Radio ON)
+ COTS_UE.Set_Airplane(device_id, 'OFF')
+ elif device_id == '84B7N16418004022':
SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/on"', '\$', 60)
else:
SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60)
@@ -827,7 +841,13 @@ class OaiCiTest():
if count == 15 or count == 30:
logging.debug('\u001B[1;30;43m Retry UE (' + device_id + ') Flight Mode Off \u001B[0m')
if self.ADBCentralized:
- if device_id == '84B7N16418004022':
+ #RH quick add on to intgrate cots control defined by yaml
+ #if device id exists in yaml dictionary, we execute the new procedure defined in cots_ue class
+ #otherwise we use the legacy procedure
+ if COTS_UE.Check_Exists(device_id):
+ #switch device to Airplane mode ON (ie Radio OFF)
+ COTS_UE.Set_Airplane(device_id, 'ON')
+ elif device_id == '84B7N16418004022':
SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60)
else:
SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60)
@@ -835,7 +855,13 @@ class OaiCiTest():
SSH.command('ssh ' + self.UEDevicesRemoteUser[idx] + '@' + self.UEDevicesRemoteServer[idx] + ' ' + self.UEDevicesOffCmd[idx], '\$', 60)
time.sleep(0.5)
if self.ADBCentralized:
- if device_id == '84B7N16418004022':
+ #RH quick add on to integrate cots control defined by yaml
+ #if device id exists in yaml dictionary, we execute the new procedre defined incots_ue class
+ #otherwise we use the legacy procedure
+ if COTS_UE.Check_Exists(device_id):
+ #switch device to Airplane mode OFF (ie Radio ON)
+ COTS_UE.Set_Airplane(device_id, 'OFF')
+ elif device_id == '84B7N16418004022':
SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/on"', '\$', 60)
else:
SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/on', '\$', 60)
@@ -918,7 +944,13 @@ class OaiCiTest():
try:
SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
if self.ADBCentralized:
- if device_id == '84B7N16418004022':
+ #RH quick add on to integrate cots control defined by yaml
+ #if device id exists in yaml dictionary, we execute the new procedure defined in cots_ue class
+ #otherwise we use the legacy procedure
+ if COTS_UE.Check_Exists(device_id):
+ #switch device to Airplane mode ON (ie Radio OFF)
+ COTS_UE.Set_Airplane(device_id,'ON')
+ elif device_id == '84B7N16418004022':
SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60)
else:
SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60)
@@ -2697,7 +2729,13 @@ class OaiCiTest():
SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword)
# back in airplane mode on (ie radio off)
if self.ADBCentralized:
- if device_id == '84B7N16418004022':
+ #RH quick add on to intgrate cots control defined by yaml
+ #if device Id exists in yaml dictionary, we execute the new procedure defined in cots_ue class
+ #otherwise we use the legacy procedure
+ if COTS_UE.Check_Exists(device_id):
+ #switch device to Airplane mode ON (ie Radio OFF)
+ COTS_UE.Set_Airplane(device_id, 'ON')
+ elif device_id == '84B7N16418004022':
SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell "su - root -c /data/local/tmp/off"', '\$', 60)
else:
SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/off', '\$', 60)
@@ -3133,7 +3171,7 @@ def GetParametersFromXML(action):
else:
RAN.backgroundBuild=False
- if action == 'WaitEndBuild_eNB':
+ elif action == 'WaitEndBuild_eNB':
RAN.Build_eNB_args=test.findtext('Build_eNB_args')
eNB_instance=test.findtext('eNB_instance')
if (eNB_instance is None):
@@ -3144,7 +3182,7 @@ def GetParametersFromXML(action):
if (RAN.eNB_serverId is None):
RAN.eNB_serverId='0'
- if action == 'Initialize_eNB':
+ elif action == 'Initialize_eNB':
RAN.Initialize_eNB_args=test.findtext('Initialize_eNB_args')
eNB_instance=test.findtext('eNB_instance')
if (eNB_instance is None):
@@ -3164,7 +3202,7 @@ def GetParametersFromXML(action):
else :
RAN.air_interface[RAN.eNB_instance] = 'ocp-enb'
- if action == 'Terminate_eNB':
+ elif action == 'Terminate_eNB':
eNB_instance=test.findtext('eNB_instance')
if (eNB_instance is None):
RAN.eNB_instance=0
@@ -3183,21 +3221,21 @@ def GetParametersFromXML(action):
else :
RAN.air_interface[RAN.eNB_instance] = 'ocp-enb'
- if action == 'Attach_UE':
+ elif action == 'Attach_UE':
nbMaxUEtoAttach = test.findtext('nbMaxUEtoAttach')
if (nbMaxUEtoAttach is None):
CiTestObj.nbMaxUEtoAttach = -1
else:
CiTestObj.nbMaxUEtoAttach = int(nbMaxUEtoAttach)
- if action == 'CheckStatusUE':
+ elif action == 'CheckStatusUE':
expectedNBUE = test.findtext('expectedNbOfConnectedUEs')
if (expectedNBUE is None):
CiTestObj.expectedNbOfConnectedUEs = -1
else:
CiTestObj.expectedNbOfConnectedUEs = int(expectedNBUE)
- if action == 'Build_OAI_UE':
+ elif action == 'Build_OAI_UE':
CiTestObj.Build_OAI_UE_args = test.findtext('Build_OAI_UE_args')
CiTestObj.clean_repository = test.findtext('clean_repository')
if (CiTestObj.clean_repository == 'false'):
@@ -3205,7 +3243,7 @@ def GetParametersFromXML(action):
else:
CiTestObj.clean_repository = True
- if action == 'Initialize_OAI_UE':
+ elif action == 'Initialize_OAI_UE':
CiTestObj.Initialize_OAI_UE_args = test.findtext('Initialize_OAI_UE_args')
UE_instance = test.findtext('UE_instance')
if (UE_instance is None):
@@ -3223,7 +3261,7 @@ def GetParametersFromXML(action):
#CiTestObj.air_interface = 'ocp-enb'
logging.error('OCP UE -- NOT SUPPORTED')
- if action == 'Terminate_OAI_UE':
+ elif action == 'Terminate_OAI_UE':
UE_instance=test.findtext('UE_instance')
if (UE_instance is None):
CiTestObj.UE_instance = '0'
@@ -3240,11 +3278,11 @@ def GetParametersFromXML(action):
#CiTestObj.air_interface = 'ocp-enb'
logging.error('OCP UE -- NOT SUPPORTED')
- if action == 'Ping' or action == 'Ping_CatM_module':
+ elif (action == 'Ping') or (action == 'Ping_CatM_module'):
CiTestObj.ping_args = test.findtext('ping_args')
CiTestObj.ping_packetloss_threshold = test.findtext('ping_packetloss_threshold')
- if action == 'Iperf':
+ elif action == 'Iperf':
CiTestObj.iperf_args = test.findtext('iperf_args')
CiTestObj.iperf_packetloss_threshold = test.findtext('iperf_packetloss_threshold')
CiTestObj.iperf_profile = test.findtext('iperf_profile')
@@ -3262,14 +3300,14 @@ def GetParametersFromXML(action):
logging.debug('ERROR: test-case has wrong option ' + CiTestObj.iperf_options)
CiTestObj.iperf_options = 'check'
- if action == 'IdleSleep':
+ elif action == 'IdleSleep':
string_field = test.findtext('idle_sleep_time_in_sec')
if (string_field is None):
CiTestObj.idle_sleep_time = 5
else:
CiTestObj.idle_sleep_time = int(string_field)
- if action == 'Perform_X2_Handover':
+ elif action == 'Perform_X2_Handover':
string_field = test.findtext('x2_ho_options')
if (string_field is None):
CiTestObj.x2_ho_options = 'network'
@@ -3280,7 +3318,7 @@ def GetParametersFromXML(action):
else:
CiTestObj.x2_ho_options = string_field
- if action == 'Build_PhySim':
+ elif action == 'Build_PhySim':
ldpc.buildargs = test.findtext('physim_build_args')
forced_workspace_cleanup = test.findtext('forced_workspace_cleanup')
if (forced_workspace_cleanup is None):
@@ -3291,11 +3329,9 @@ def GetParametersFromXML(action):
else:
ldpc.forced_workspace_cleanup=False
- if action == 'Run_PhySim':
+ else: # ie action == 'Run_PhySim':
ldpc.runargs = test.findtext('physim_run_args')
- if action == 'COTS_UE_Airplane':
- COTS_UE.runargs = test.findtext('cots_ue_airplane_args')
#check if given test is in list
#it is in list if one of the strings in 'list' is at the beginning of 'test'
@@ -3320,15 +3356,21 @@ def receive_signal(signum, frame):
#loading xml action list from yaml
import yaml
-xml_class_list_file=''
-if (os.path.isfile('xml_class_list.yml')):
- xml_class_list_file='xml_class_list.yml'
-if (os.path.isfile('ci-scripts/xml_class_list.yml')):
- xml_class_list_file='ci-scripts/xml_class_list.yml'
-with open(xml_class_list_file,'r') as file:
- # The FullLoader parameter handles the conversion from YAML
- # scalar values to Python the dictionary format
- xml_class_list = yaml.load(file,Loader=yaml.FullLoader)
+xml_class_list_file='xml_class_list.yml'
+if (os.path.isfile(xml_class_list_file)):
+ yaml_file=xml_class_list_file
+elif (os.path.isfile('ci-scripts/'+xml_class_list_file)):
+ yaml_file='ci-scripts/'+xml_class_list_file
+else:
+ logging.error("XML action list yaml file cannot be found")
+ sys.exit("XML action list yaml file cannot be found")
+
+with open(yaml_file,'r') as f:
+ # The FullLoader parameter handles the conversion-$
+ #from YAML scalar values to Python dictionary format$
+ xml_class_list = yaml.load(f,Loader=yaml.FullLoader)
+
+
mode = ''
@@ -3375,8 +3417,9 @@ if py_param_file_present == True:
#-----------------------------------------------------------
# COTS UE instanciation
#-----------------------------------------------------------
-#COTS_UE instanciation can only be done here for the moment, due to code architecture
-COTS_UE=cls_cots_ue.CotsUe('oppo', CiTestObj.UEIPAddress, CiTestObj.UEUserName,CiTestObj.UEPassword)
+#COTS_UE instanciation and ADB server init
+#ue id and ue mode are retrieved from xml
+COTS_UE=cls_cots_ue.CotsUe(CiTestObj.ADBIPAddress, CiTestObj.ADBUserName,CiTestObj.ADBPassword)
#-----------------------------------------------------------
@@ -3613,7 +3656,8 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
GetParametersFromXML(action)
if action == 'Initialize_UE' or action == 'Attach_UE' or action == 'Detach_UE' or action == 'Ping' or action == 'Iperf' or action == 'Reboot_UE' or action == 'DataDisable_UE' or action == 'DataEnable_UE' or action == 'CheckStatusUE':
if (CiTestObj.ADBIPAddress != 'none'):
- terminate_ue_flag = False
+ #in these cases, having no devices is critical, GetAllUEDevices function has to manage it as a critical error, reason why terminate_ue_flag is set to True
+ terminate_ue_flag = True
CiTestObj.GetAllUEDevices(terminate_ue_flag)
if action == 'Build_eNB':
RAN.BuildeNB()
@@ -3688,8 +3732,6 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re
if ldpc.exitStatus==1:sys.exit()
elif action == 'Run_PhySim':
HTML=ldpc.Run_PhySim(HTML,CONST,id)
- elif action == 'COTS_UE_Airplane':
- COTS_UE.Set_Airplane(COTS_UE.runargs)
else:
sys.exit('Invalid class (action) from xml')
CiTestObj.FailReportCnt += 1
diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py
index 96f28e21fe..d5906e9567 100644
--- a/ci-scripts/ran.py
+++ b/ci-scripts/ran.py
@@ -90,6 +90,7 @@ class RANManagement():
self.epcPcapFile = ''
self.htmlObj = None
self.epcObj = None
+ self.runtime_stats= ''
@@ -614,7 +615,7 @@ class RANManagement():
logging.debug('\u001B[1m Analyzing eNB replay logfile \u001B[0m')
logStatus = self.AnalyzeLogFile_eNB(extracted_log_file)
if self.htmlObj is not None:
- self.htmlObj.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
+ self.htmlObj.CreateHtmlTestRow(self.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK)
self.eNBLogFiles[int(self.eNB_instance)] = ''
else:
analyzeFile = False
@@ -643,10 +644,10 @@ class RANManagement():
return
else:
if self.htmlObj is not None:
- self.htmlObj.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
+ self.htmlObj.CreateHtmlTestRow(self.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK)
else:
if self.htmlObj is not None:
- self.htmlObj.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
+ self.htmlObj.CreateHtmlTestRow(self.runtime_stats, 'OK', CONST.ALL_PROCESSES_OK)
self.eNBmbmsEnables[int(self.eNB_instance)] = False
self.eNBstatuses[int(self.eNB_instance)] = -1
@@ -712,16 +713,20 @@ class RANManagement():
if runTime != '':
result = re.search('Time executing user inst', str(line))
if result is not None:
- userTime = 'to be decoded - 1'
+ fields=line.split(':')
+ userTime = 'userTime : ' + fields[1].replace('\n','')
result = re.search('Time executing system inst', str(line))
if result is not None:
- systemTime = 'to be decoded - 2'
+ fields=line.split(':')
+ systemTime = 'systemTime : ' + fields[1].replace('\n','')
result = re.search('Max. Phy. memory usage:', str(line))
if result is not None:
- maxPhyMemUsage = 'to be decoded - 3'
+ fields=line.split(':')
+ maxPhyMemUsage = 'maxPhyMemUsage : ' + fields[1].replace('\n','')
result = re.search('Number of context switch.*process origin', str(line))
if result is not None:
- nbContextSwitches = 'to be decoded - 4'
+ fields=line.split(':')
+ nbContextSwitches = 'nbContextSwitches : ' + fields[1].replace('\n','')
if X2HO_state == CONST.X2_HO_REQ_STATE__IDLE:
result = re.search('target eNB Receives X2 HO Req X2AP_HANDOVER_REQ', str(line))
if result is not None:
@@ -978,11 +983,12 @@ class RANManagement():
global_status = CONST.ENB_PROCESS_REALTIME_ISSUE
if self.htmlObj is not None:
self.htmlObj.htmleNBFailureMsg=htmleNBFailureMsg
- # Runtime statistics
+ # Runtime statistics for console output and HTML
if runTime != '':
logging.debug(runTime)
- logging.debug('Time executing user inst : ' + userTime)
- logging.debug('Time executing system inst : ' + systemTime)
- logging.debug('Max Physical Memory Usage : ' + maxPhyMemUsage)
- logging.debug('Nb Context Switches : ' + nbContextSwitches)
+ logging.debug(userTime)
+ logging.debug(systemTime)
+ logging.debug(maxPhyMemUsage)
+ logging.debug(nbContextSwitches)
+ self.runtime_stats='
'+runTime + '\n'+ userTime + '\n' + systemTime + '\n' + maxPhyMemUsage + '\n' + nbContextSwitches+'
'
return global_status
diff --git a/ci-scripts/xml_class_list.yml b/ci-scripts/xml_class_list.yml
index e80063a120..2c20988851 100755
--- a/ci-scripts/xml_class_list.yml
+++ b/ci-scripts/xml_class_list.yml
@@ -1,4 +1,3 @@
- - COTS_UE_Airplane
- Build_PhySim
- Run_PhySim
- Build_eNB
diff --git a/ci-scripts/xml_files/fr1_toggle_cots_ue.xml b/ci-scripts/xml_files/fr1_epc_closure.xml
similarity index 72%
rename from ci-scripts/xml_files/fr1_toggle_cots_ue.xml
rename to ci-scripts/xml_files/fr1_epc_closure.xml
index b2267efc77..2fd8031936 100644
--- a/ci-scripts/xml_files/fr1_toggle_cots_ue.xml
+++ b/ci-scripts/xml_files/fr1_epc_closure.xml
@@ -21,19 +21,27 @@
-->
- test-airplane-mode
- AirplaneToggle
- tasks
+ epc-closure
+ EPC-Closure
+ log-out
- 010000
+060000 060001 060002
-
- COTS_UE_Airplane
- Toggle COTS Airplane mode ON
- ON
+
+ Terminate_HSS
+ Terminate HSS
+
+ Terminate_MME
+ Terminate MME
+
+
+
+ Terminate_SPGW
+ Terminate SPGW
+
diff --git a/ci-scripts/xml_files/fr1_multi_node_terminate.xml b/ci-scripts/xml_files/fr1_epc_start.xml
similarity index 70%
rename from ci-scripts/xml_files/fr1_multi_node_terminate.xml
rename to ci-scripts/xml_files/fr1_epc_start.xml
index cbaaf8ba99..5cef2b5a6a 100644
--- a/ci-scripts/xml_files/fr1_multi_node_terminate.xml
+++ b/ci-scripts/xml_files/fr1_epc_start.xml
@@ -21,30 +21,28 @@
-->
- test-fr1-tm1
- Test-FR1-TM1
- tasks
- 1
+ epc-start-tab
+ EPC-Start
+ log-in
- 070001
- 070000
+ 000100 000101 000102
-
- Terminate_eNB
- Terminate eNB
- 0
- 0
+
+ Initialize_HSS
+ Initialize HSS
-
- Terminate_eNB
- Terminate gNB
- 1
- 1
+
+ Initialize_MME
+ Initialize MME
+
+
+
+ Initialize_SPGW
+ Initialize SPGW
-
diff --git a/ci-scripts/xml_files/fr1_ran_ue_proc.xml b/ci-scripts/xml_files/fr1_ran_ue_proc.xml
new file mode 100644
index 0000000000..e86a36d2db
--- /dev/null
+++ b/ci-scripts/xml_files/fr1_ran_ue_proc.xml
@@ -0,0 +1,117 @@
+
+
+ TEST-FR1-TM1
+ FR1
+ tasks
+
+ 010000
+ 030000
+ 040000
+ 010001
+ 000001
+ 050000
+ 050001
+ 070001
+ 070000
+ 010002
+ 010003
+
+
+
+
+ Initialize_UE
+ Initialize UE
+
+
+
+ Terminate_UE
+ Terminate UE
+
+
+
+ Attach_UE
+ Attach UE
+
+
+
+ Detach_UE
+ Detach UE
+
+
+
+
+ Initialize_eNB
+ Initialize eNB
+ -O ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf
+ 0
+ 0
+ lte
+
+
+
+
+ Initialize_eNB
+ Initialize gNB
+ -O ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf -E
+ 1
+ 1
+ nr
+
+
+
+ IdleSleep
+ Sleep
+ 20
+
+
+
+ Ping
+ Ping: 20pings in 20sec
+ -c 20
+ 0
+
+
+
+ Ping
+ Ping: 5pings in 1sec
+ -c 5 -i 0.2
+ 0
+
+
+
+ Terminate_eNB
+ Terminate eNB
+ 0
+ 0
+
+
+
+ Terminate_eNB
+ Terminate gNB
+ 1
+ 1
+
+
+
+
diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index e540c3f95d..0977f6c0d9 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -2377,6 +2377,7 @@ add_library(LFDS7
add_library(SIMU_COMMON
${OPENAIR1_DIR}/SIMULATION/TOOLS/random_channel.c
${OPENAIR1_DIR}/SIMULATION/TOOLS/rangen_double.c
+ ${OPENAIR1_DIR}/SIMULATION/TOOLS/phase_noise.c
)
# Simulation library
diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml
index 786002e982..7e43a9d01c 100644
--- a/cmake_targets/autotests/test_case_list.xml
+++ b/cmake_targets/autotests/test_case_list.xml
@@ -1276,7 +1276,10 @@
(Test2: MCS 16 50 PRBs),
(Test3: MCS 28 50 PRBs),
(Test4: MCS 9 217 PRBs),
- (Test5: MCS 9 273 PRBs)
+ (Test5: MCS 9 273 PRBs),
+ (Test6: DMRS Type A, 3 DMRS, 4 PTRS, 5 Interpolated Symbols),
+ (Test7: DMRS Type B, 3 DMRS, 2 PTRS, 7 Interpolated Symbols),
+ (Test8: DMRS Type B, 3 DMRS, 2 PTRS, 3 Interpolated Symbols)
$OPENAIR_DIR/cmake_targets/build_oai
--phy_simulators -c
@@ -1287,8 +1290,11 @@
-n100 -m16 -s10
-n100 -m28 -s20
-n100 -m9 -R217 -r217 -s5
- -n100 -m9 -R273 -r273 -s5
- nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5
+ -n100 -m9 -R273 -r273 -s5
+ -n100 -s5 -T 2 1 2 -U 2 0 2
+ -n100 -s5 -T 2 2 2 -U 2 1 2
+ -n100 -s5 -a4 -b8 -T 2 1 2 -U 2 1 3
+ nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8
PUSCH test OK
segmentation fault|assertion|exiting|fatal
3
diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai
index 36af9eaee4..f301908495 100755
--- a/cmake_targets/build_oai
+++ b/cmake_targets/build_oai
@@ -211,7 +211,7 @@ function main() {
GDB=0
CMAKE_BUILD_TYPE="RelWithDebInfo"
echo_info "Will Compile with gdb symbols"
- CMAKE_CMD="$CMAKE_CMD -DCMAKE_BUILD_TYPE=RelWithDebInfo"
+ CMAKE_CMD="$CMAKE_CMD -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_EXPORT_COMPILE_COMMANDS=1"
shift
;;
"MinSizeRel")
diff --git a/doc/BUILD.md b/doc/BUILD.md
index a15083dc32..ba5db55cab 100644
--- a/doc/BUILD.md
+++ b/doc/BUILD.md
@@ -16,6 +16,7 @@ This page is valid on tags starting from **`2019.w09`**.
# Soft Modem Build Script
+The OAI EPC is developed in a distinct project with it's own [documentation](https://github.com/OPENAIRINTERFACE/openair-epc-fed/wiki) , it is not described here.
OAI softmodem sources, which aim to implement 3GPP compliant UEs, eNodeB and gNodeB can be downloaded from the Eurecom [gitlab repository](./GET_SOURCES.md).
diff --git a/doc/GET_SOURCES.md b/doc/GET_SOURCES.md
index e27e9dbb74..854ff3b504 100644
--- a/doc/GET_SOURCES.md
+++ b/doc/GET_SOURCES.md
@@ -33,12 +33,8 @@ holds the source code for (eNB RAN + UE RAN).
For legal issues (licenses), the core network (EPC) source code is now moved away from
the above openairinterface5g git repository.
-* A very old version of the EPC is located under the same GitLab Eurecom server (splitted into 2 Git repos):
- * [openair-cn](https://gitlab.eurecom.fr/oai/openair-cn.git) with apache license
- * [xtables-addons-oai](https://gitlab.eurecom.fr/oai/xtables-addons-oai.git) with GPL license
- * **These repositories are no more maintained.**
* A more recent version is available under our GitHub domain:
- * [OAI GitHub openair-cn](https://github.com/OPENAIRINTERFACE/openair-cn)
+ * [OAI GitHub openair-cn domain](https://github.com/OPENAIRINTERFACE)
* Check its wiki pages for more details
Configure git with your name/email address (only important if you are developer and want to contribute/push code to Git Repository):
@@ -80,8 +76,6 @@ you do not have account on gitlab.eurecom.fr, please register yourself to gitlab
* `git clone git@gitlab.eurecom.fr:oai/openairinterface5g.git`
* Clone with user name/password prompt:
* `git clone https://YOUR_USERNAME@gitlab.eurecom.fr/oai/openairinterface5g.git`
- * `git clone https://YOUR_USERNAME@gitlab.eurecom.fr/oai/openair-cn.git`
- * `git clone https://YOUR_USERNAME@gitlab.eurecom.fr/oai/xtables-addons-oai.git` (optional, openair-cn build script can do it for you)
# Which branch to checkout?
diff --git a/doc/TESTBenches.md b/doc/TESTBenches.md
new file mode 100644
index 0000000000..7365bc0f4c
--- /dev/null
+++ b/doc/TESTBenches.md
@@ -0,0 +1,45 @@
+## Table of Contents ##
+
+1. [Legacy 1 Bench](#legacy-1-bench)
+2. [Legacy 2 Bench](#legacy-2-bench)
+3. [Next Bench for DEV](#next-bench-for-dev)
+4. [Next Bench for CI](#next-bench-for-ci)
+5. [Indoor Live Network Bench](#indoor-live-network-bench)
+6. [Outdoor Live Network Bench](#outdoor-live-network-bench)
+
+
+## Legacy 1 Bench
+
+**Purpose** : FDD Band 7 and Band 13, LTE-M
+**Note** : Legacy1 and Legacy2 are duplicated so that they can run in parallel, thus avoiding a CI bottleneck
+**Note** : Faraday Cages 1 and 2 are physically the same cage
+
+
+
+## Legacy 2 Bench
+
+**Purpose** : TDD Band 40, TM2 2xTX 2xRX
+**Note** : CN can run in a container, could also run on Massive
+
+
+
+## Next Bench for DEV
+
+**Note** : Benetel CI can also run on this bench at night
+
+
+
+
+## Next Bench for CI
+
+**Note** : The current test running on Caracal could run on this bench with a N300/N300 setup
+
+
+
+## Indoor Live Network Bench
+
+
+
+## Outdoor Live Network Bench
+
+
diff --git a/doc/TESTING_GNB_W_COTS_UE.md b/doc/TESTING_GNB_W_COTS_UE.md
index b1afb0c798..198f6bb115 100644
--- a/doc/TESTING_GNB_W_COTS_UE.md
+++ b/doc/TESTING_GNB_W_COTS_UE.md
@@ -220,17 +220,16 @@ Execute:
- **gNB** (on the gNB host)
+**ATTENTION** : for the gNB execution,
+The **-E** option is required to enable the tri-quarter sampling rate when using a B2xx serie USRP
+The **-E** option is **NOT supported** when using a a N300 USRP
+
Execute:
```
~/openairinterface5g/cmake_targets/ran_build/build$ sudo ./nr-softmodem -O **YOUR_GNB_CONF_FILE** -E | tee **YOUR_LOG_FILE**
```
-**ATTENTION** : for the gNB execution,
-The -E option is required to enable the tri-quarter sampling rate when using a B2xx serie USRP
-The -E opton is not needed when using a a N300 USRP
-
-
## Test Case
diff --git a/doc/testbenches_doc_resources/benches.vsdx b/doc/testbenches_doc_resources/benches.vsdx
new file mode 100755
index 0000000000..6ad3a5b576
Binary files /dev/null and b/doc/testbenches_doc_resources/benches.vsdx differ
diff --git a/doc/testbenches_doc_resources/indoor_live.jpg b/doc/testbenches_doc_resources/indoor_live.jpg
new file mode 100755
index 0000000000..ce8b9cda48
Binary files /dev/null and b/doc/testbenches_doc_resources/indoor_live.jpg differ
diff --git a/doc/testbenches_doc_resources/legacy1.jpg b/doc/testbenches_doc_resources/legacy1.jpg
new file mode 100755
index 0000000000..c3579df3e4
Binary files /dev/null and b/doc/testbenches_doc_resources/legacy1.jpg differ
diff --git a/doc/testbenches_doc_resources/legacy2.jpg b/doc/testbenches_doc_resources/legacy2.jpg
new file mode 100755
index 0000000000..f40d167a2d
Binary files /dev/null and b/doc/testbenches_doc_resources/legacy2.jpg differ
diff --git a/doc/testbenches_doc_resources/next_ci.jpg b/doc/testbenches_doc_resources/next_ci.jpg
new file mode 100755
index 0000000000..2d4111510c
Binary files /dev/null and b/doc/testbenches_doc_resources/next_ci.jpg differ
diff --git a/doc/testbenches_doc_resources/next_dev.jpg b/doc/testbenches_doc_resources/next_dev.jpg
new file mode 100755
index 0000000000..72e9f63bf9
Binary files /dev/null and b/doc/testbenches_doc_resources/next_dev.jpg differ
diff --git a/doc/testbenches_doc_resources/outdoor_live.jpg b/doc/testbenches_doc_resources/outdoor_live.jpg
new file mode 100755
index 0000000000..eba44a3c00
Binary files /dev/null and b/doc/testbenches_doc_resources/outdoor_live.jpg differ
diff --git a/docker/Dockerfile.enb.rhel7.oc4-4 b/docker/Dockerfile.enb.rhel7.oc4-4
new file mode 100644
index 0000000000..12d9a19640
--- /dev/null
+++ b/docker/Dockerfile.enb.rhel7.oc4-4
@@ -0,0 +1,92 @@
+#/*
+# * 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
+# */
+#---------------------------------------------------------------------
+#
+# Dockerfile for the Open-Air-Interface eNB service
+# Valid for RHEL7 in the OpenShift context (v4.4)
+#
+#---------------------------------------------------------------------
+
+
+ARG REGISTRY=localhost
+FROM $REGISTRY/oai-build-base:latest.el7 AS builder
+
+ARG GIT_TAG=v1.1.1
+
+WORKDIR /root
+
+RUN if [ "$EURECOM_PROXY" == true ]; then git config --global http.proxy http://:@proxy.eurecom.fr:8080; fi
+
+RUN git clone --depth=1 --branch=$GIT_TAG https://gitlab.eurecom.fr/oai/openairinterface5g.git
+COPY patches patches/
+RUN patch -p1 -d openairinterface5g < patches/disable_building_nasmesh_and_rbtool.patch \
+ && patch -p1 -d openairinterface5g < patches/disable_sched_fifo_fail_exits.patch
+RUN cd openairinterface5g/cmake_targets \
+ && ln -sf /usr/local/bin/asn1c_oai /usr/local/bin/asn1c \
+ && ln -sf /usr/local/share/asn1c_oai /usr/local/share/asn1c \
+ && ./build_oai -c --eNB -w USRP --verbose-compile
+
+
+FROM registry.redhat.io/ubi7/ubi
+LABEL name="oai-enb" \
+ version="$GIT_TAG" \
+ maintainer="Frank A. Zdarsky " \
+ io.k8s.description="openairinterface5g eNB $GIT_TAG." \
+ io.openshift.tags="oai,enb" \
+ io.openshift.non-scalable="true"
+
+RUN yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm \
+ && REPOLIST="rhel-7-server-optional-rpms" \
+ && PKGLIST="boost libconfig lksctp-tools protobuf-c iproute iputils procps-ng bind-utils xforms nettle libyaml libusb" \
+ # && yum -y upgrade-minimal --setopt=tsflags=nodocs --security --sec-severity=Critical --sec-severity=Important && \
+ && yum -y install --enablerepo ${REPOLIST} --setopt=tsflag=nodocs ${PKGLIST} \
+ && yum -y clean all \
+ && rm -rf /var/cache/yum
+
+ENV APP_ROOT=/opt/oai-enb
+ENV PATH=${APP_ROOT}:${PATH} HOME=${APP_ROOT}
+COPY --from=builder /root/openairinterface5g/cmake_targets/lte_build_oai/build/lte-softmodem ${APP_ROOT}/bin/
+COPY --from=builder /root/openairinterface5g/cmake_targets/lte_build_oai/build/*.so* /lib64
+COPY --from=builder /usr/local/lib64 /lib64
+COPY --from=builder /usr/local/bin/uhd_* /usr/local/bin
+COPY --from=builder /usr/local/share/uhd /usr/local/share/uhd
+RUN cd /lib64 \
+ && ln -sf liboai_eth_transpro.so liboai_transpro.so \
+ && ln -sf liboai_usrpdevif.so liboai_device.so \
+ && ln -sf libuhd.so.3.13 libuhd.so.3 \
+ && ln -sf libuhd.so.3 libuhd.so
+COPY scripts ${APP_ROOT}/bin/
+COPY configs ${APP_ROOT}/etc/
+RUN chmod -R u+x ${APP_ROOT} && \
+ chgrp -R 0 ${APP_ROOT} && \
+ chmod -R g=u ${APP_ROOT} /etc/passwd
+USER 10001
+WORKDIR ${APP_ROOT}
+
+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)
+
+CMD ["/opt/oai-enb/bin/lte-softmodem", "-O", "/opt/oai-enb/etc/enb.conf"]
+ENTRYPOINT ["/opt/oai-enb/bin/entrypoint.sh"]
diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c
index 35a9a15961..057d259baa 100644
--- a/openair1/PHY/INIT/nr_init.c
+++ b/openair1/PHY/INIT/nr_init.c
@@ -251,10 +251,11 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
pusch_vars[ULSCH_id]->ul_ch_estimates_ext = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates_ext = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
+ pusch_vars[ULSCH_id]->ptrs_phase_per_slot = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
pusch_vars[ULSCH_id]->ul_ch_estimates_time = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
pusch_vars[ULSCH_id]->rxdataF_comp = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
- pusch_vars[ULSCH_id]->ul_ch_mag0 = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
- pusch_vars[ULSCH_id]->ul_ch_magb0 = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
+ pusch_vars[ULSCH_id]->ul_ch_mag0 = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
+ pusch_vars[ULSCH_id]->ul_ch_magb0 = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
pusch_vars[ULSCH_id]->ul_ch_mag = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
pusch_vars[ULSCH_id]->ul_ch_magb = (int32_t **)malloc16(Prx*sizeof(int32_t *) );
pusch_vars[ULSCH_id]->rho = (int32_t **)malloc16_clear(Prx*sizeof(int32_t*) );
@@ -268,16 +269,18 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
pusch_vars[ULSCH_id]->ul_ch_estimates_time[i] = (int32_t *)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size );
pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2*fp->symbols_per_slot ); // max intensity in freq is 1 sc every 2 RBs
pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2*fp->symbols_per_slot );
+ pusch_vars[ULSCH_id]->ptrs_phase_per_slot[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*fp->symbols_per_slot); // symbols per slot
pusch_vars[ULSCH_id]->rxdataF_comp[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*N_RB_UL*12*fp->symbols_per_slot );
- pusch_vars[ULSCH_id]->ul_ch_mag0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 );
- pusch_vars[ULSCH_id]->ul_ch_magb0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 );
+ pusch_vars[ULSCH_id]->ul_ch_mag0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 );
+ pusch_vars[ULSCH_id]->ul_ch_magb0[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 );
pusch_vars[ULSCH_id]->ul_ch_mag[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 );
pusch_vars[ULSCH_id]->ul_ch_magb[i] = (int32_t *)malloc16_clear( fp->symbols_per_slot*sizeof(int32_t)*N_RB_UL*12 );
pusch_vars[ULSCH_id]->rho[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(fp->N_RB_UL*12*7*2) );
}
printf("ULSCH_id %d (before llr alloc) : %p\n",ULSCH_id,gNB->dlsch[0][0]->harq_processes[0]);
pusch_vars[ULSCH_id]->llr = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) ); // [hna] 6144 is LTE and (8*((3*8*6144)+12)) is not clear
- printf("ULSCH_id %d (after llr alloc) : %p\n",ULSCH_id,gNB->dlsch[0][0]->harq_processes[0]);
+ printf("ULSCH_id %d (after llr alloc) : %p\n",ULSCH_id,gNB->dlsch[0][0]->harq_processes[0]);
+ pusch_vars[ULSCH_id]->ul_valid_re_per_slot = (int16_t *)malloc16_clear( sizeof(int16_t)*fp->symbols_per_slot);
} //ulsch_id
/*
for (ulsch_id=0; ulsch_idul_ch_estimates_time[i]);
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates[i]);
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates_ext[i]);
+ free_and_zero(pusch_vars[ULSCH_id]->ptrs_phase_per_slot[i]);
free_and_zero(pusch_vars[ULSCH_id]->rxdataF_comp[i]);
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_mag0[i]);
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_magb0[i]);
@@ -353,6 +357,8 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates);
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_ptrs_estimates_ext);
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_estimates_time);
+ free_and_zero(pusch_vars[ULSCH_id]->ptrs_phase_per_slot);
+ free_and_zero(pusch_vars[ULSCH_id]->ul_valid_re_per_slot);
free_and_zero(pusch_vars[ULSCH_id]->rxdataF_comp);
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_mag0);
free_and_zero(pusch_vars[ULSCH_id]->ul_ch_magb0);
diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
index bfc29ab4f5..b6388fb903 100644
--- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
+++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
@@ -25,6 +25,8 @@
#include "nr_ul_estimation.h"
#include "PHY/sse_intrin.h"
#include "PHY/NR_REFSIG/nr_refsig.h"
+#include "PHY/NR_REFSIG/ptrs_nr.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/NR_UE_ESTIMATION/filt16a_32.h"
//#define DEBUG_CH
@@ -507,3 +509,408 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
return(0);
}
+
+
+/*******************************************************************
+ *
+ * NAME : nr_pusch_ptrs_processing
+ *
+ * PARAMETERS : gNB : gNB data structure
+ * rel15_ul : UL parameters
+ * UE_id : UE ID
+ * nr_tti_rx : slot rx TTI
+ * dmrs_symbol_flag: DMRS Symbol Flag
+ * symbol : OFDM Symbol
+ * nb_re_pusch : PUSCH RE's
+ * nb_re_pusch : PUSCH RE's
+ *
+ * RETURN : nothing
+ *
+ * DESCRIPTION :
+ * If ptrs is enabled process the symbol accordingly
+ * 1) Estimate phase noise per PTRS symbol
+ * 2) Interpolate PTRS estimated value in TD after all PTRS symbols
+ * 3) Compensated DMRS based estimated signal with PTRS estimation for slot
+ *********************************************************************/
+void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
+ nfapi_nr_pusch_pdu_t *rel15_ul,
+ uint8_t ulsch_id,
+ uint8_t nr_tti_rx,
+ uint8_t dmrs_symbol_flag,
+ unsigned char symbol,
+ uint32_t nb_re_pusch)
+{
+ NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
+ int16_t *phase_per_symbol;
+
+ uint8_t L_ptrs = 0;
+ uint8_t right_side_ref = 0;
+ uint8_t left_side_ref = 0;
+ uint8_t nb_dmrs_in_slot = 0;
+
+ //#define DEBUG_UL_PTRS 1
+ /* First symbol calculate PTRS symbol index for slot & set the variables */
+ if(symbol == rel15_ul->start_symbol_index)
+ {
+ gNB->pusch_vars[ulsch_id]->ptrs_symbols = 0;
+ L_ptrs = 1<<(rel15_ul->pusch_ptrs.ptrs_time_density);
+ set_ptrs_symb_idx(&gNB->pusch_vars[ulsch_id]->ptrs_symbols,
+ rel15_ul->nr_of_symbols,
+ rel15_ul->start_symbol_index,
+ L_ptrs,
+ rel15_ul->ul_dmrs_symb_pos);
+ }/* First symbol check */
+
+ /* loop over antennas */
+ for (int aarx=0; aarx< frame_parms->nb_antennas_rx; aarx++)
+ {
+ phase_per_symbol = (int16_t*)gNB->pusch_vars[ulsch_id]->ptrs_phase_per_slot[aarx];
+ /* set the previous estimations to zero at first symbol */
+ if(symbol == rel15_ul->start_symbol_index)
+ {
+ memset(phase_per_symbol,0,sizeof(int32_t)*frame_parms->symbols_per_slot);
+ }
+ /* if not PTRS symbol set current ptrs symbol index to zero*/
+ gNB->pusch_vars[ulsch_id]->ptrs_symbol_index = 0;
+ gNB->pusch_vars[ulsch_id]->ptrs_sc_per_ofdm_symbol = 0;
+ /* Check if current symbol contains PTRS */
+ if(is_ptrs_symbol(symbol, gNB->pusch_vars[ulsch_id]->ptrs_symbols))
+ {
+ gNB->pusch_vars[ulsch_id]->ptrs_symbol_index = symbol;
+ /*------------------------------------------------------------------------------------------------------- */
+ /* 1) Estimate phase noise per PTRS symbol */
+ /*------------------------------------------------------------------------------------------------------- */
+ nr_pusch_phase_estimation(frame_parms,
+ rel15_ul,
+ (int16_t *)&gNB->pusch_vars[ulsch_id]->ul_ch_ptrs_estimates_ext[aarx][symbol*nb_re_pusch],
+ nr_tti_rx,
+ symbol,
+ (int16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(symbol * nb_re_pusch)],
+ gNB->nr_gold_pusch_dmrs[rel15_ul->scid],
+ &phase_per_symbol[2* symbol],
+ &gNB->pusch_vars[ulsch_id]->ptrs_sc_per_ofdm_symbol);
+ }
+ /* DMRS Symbol channel estimates extraction */
+ else if(dmrs_symbol_flag)
+ {
+ phase_per_symbol[2* symbol]= (int16_t)((1<<15)-1); // 32767
+ phase_per_symbol[2* symbol +1]= 0;// no angle
+ }
+ /* For last OFDM symbol at each antenna perform interpolation and compensation for the slot*/
+ if(symbol == (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols -1))
+ {
+ nb_dmrs_in_slot = get_dmrs_symbols_in_slot(rel15_ul->ul_dmrs_symb_pos,(rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols));
+ for(uint8_t dmrs_sym = 0; dmrs_sym < nb_dmrs_in_slot; dmrs_sym ++)
+ {
+ if(dmrs_sym == 0)
+ {
+ /* get first DMRS position */
+ left_side_ref = get_next_dmrs_symbol_in_slot(rel15_ul->ul_dmrs_symb_pos, rel15_ul->start_symbol_index, (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols));
+ /* get first DMRS position is not at start symbol position then we need to extrapolate left side */
+ if(left_side_ref > rel15_ul->start_symbol_index)
+ {
+ left_side_ref = rel15_ul->start_symbol_index;
+ }
+ }
+ /* get the next symbol from left_side_ref value */
+ right_side_ref = get_next_dmrs_symbol_in_slot(rel15_ul->ul_dmrs_symb_pos, left_side_ref+1, (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols));
+ /* if no symbol found then interpolate till end of slot*/
+ if(right_side_ref == 0)
+ {
+ right_side_ref = (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols);
+ }
+ /*------------------------------------------------------------------------------------------------------- */
+ /* 2) Interpolate PTRS estimated value in TD */
+ /*------------------------------------------------------------------------------------------------------- */
+ nr_pusch_phase_interpolation(phase_per_symbol,left_side_ref,right_side_ref);
+ /* set left to last dmrs */
+ left_side_ref = right_side_ref;
+ } /*loop over dmrs positions */
+
+#ifdef DEBUG_UL_PTRS
+ LOG_M("ptrsEst.m","est",gNB->pusch_vars[ulsch_id]->ptrs_phase_per_slot[aarx],frame_parms->symbols_per_slot,1,1 );
+ LOG_M("rxdataF_bf_ptrs_comp.m","bf_ptrs_cmp",
+ &gNB->pusch_vars[0]->rxdataF_comp[aarx][rel15_ul->start_symbol_index * NR_NB_SC_PER_RB * rel15_ul->rb_size],
+ rel15_ul->nr_of_symbols * NR_NB_SC_PER_RB * rel15_ul->rb_size,1,1);
+#endif
+
+ /*------------------------------------------------------------------------------------------------------- */
+ /* 3) Compensated DMRS based estimated signal with PTRS estimation */
+ /*--------------------------------------------------------------------------------------------------------*/
+ for(uint8_t i =rel15_ul->start_symbol_index; i< (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols);i++)
+ {
+#ifdef DEBUG_UL_PTRS
+ printf("PTRS: Rotate Symbol %2d with %d + j* %d\n", i, phase_per_symbol[2* i],phase_per_symbol[(2* i) +1]);
+#endif
+ rotate_cpx_vector((int16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(i * rel15_ul->rb_size * NR_NB_SC_PER_RB)],
+ &phase_per_symbol[2* i],
+ (int16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(i * rel15_ul->rb_size * NR_NB_SC_PER_RB)],
+ (rel15_ul->rb_size * NR_NB_SC_PER_RB),
+ 15);
+ }// symbol loop
+ }//interpolation and compensation
+ }// Antenna loop
+}
+
+/*******************************************************************
+ *
+ * NAME : nr_pusch_phase_estimation
+ *
+ * PARAMETERS : frame_parms : UL frame parameters
+ * rel15_ul : UL PDU Structure
+ * Ns :
+ * Symbol : OFDM symbol index
+ * rxF : Channel compensated signal
+ * ptrs_gold_seq: Gold sequence for PTRS regeneration
+ * error_est : Estimated error output vector [Re Im]
+ * RETURN : nothing
+ *
+ * DESCRIPTION :
+ * perform phase estimation from regenerated PTRS SC and channel compensated
+ * signal
+ *********************************************************************/
+void nr_pusch_phase_estimation(NR_DL_FRAME_PARMS *frame_parms,
+ nfapi_nr_pusch_pdu_t *rel15_ul,
+ int16_t *ptrs_ch_p,
+ unsigned char Ns,
+ unsigned char symbol,
+ int16_t *rxF_comp,
+ uint32_t ***ptrs_gold_seq,
+ int16_t *error_est,
+ uint16_t *ptrs_sc)
+{
+ uint8_t is_ptrs_re = 0;
+ uint16_t re_cnt = 0;
+ uint16_t cnt = 0;
+ unsigned short nb_re_pusch = NR_NB_SC_PER_RB * rel15_ul->rb_size;
+ uint8_t K_ptrs = rel15_ul->pusch_ptrs.ptrs_freq_density;
+ uint16_t sc_per_symbol = (rel15_ul->rb_size + K_ptrs - 1)/K_ptrs;
+ int16_t *ptrs_p = (int16_t *)malloc(sizeof(int32_t)*(sc_per_symbol));
+ int16_t *dmrs_comp_p = (int16_t *)malloc(sizeof(int32_t)*(sc_per_symbol));
+ double abs = 0.0;
+ double real = 0.0;
+ double imag = 0.0;
+#ifdef DEBUG_UL_PTRS
+ double alpha = 0;
+#endif
+ /* generate PTRS RE for the symbol */
+ nr_gen_ref_conj_symbols(ptrs_gold_seq[Ns][symbol],sc_per_symbol*2,ptrs_p, NR_MOD_TABLE_QPSK_OFFSET,2);// 2 for QPSK
+
+ /* loop over all sub carriers to get compensated RE on ptrs symbols*/
+ for (int re = 0; re < nb_re_pusch; re++)
+ {
+ is_ptrs_re = is_ptrs_subcarrier(re,
+ rel15_ul->rnti,
+ 0,
+ rel15_ul->dmrs_config_type,
+ K_ptrs,
+ rel15_ul->rb_size,
+ rel15_ul->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset,
+ 0,// start_re is 0 here
+ frame_parms->ofdm_symbol_size);
+ if(is_ptrs_re)
+ {
+ dmrs_comp_p[re_cnt*2] = rxF_comp[re *2];
+ dmrs_comp_p[(re_cnt*2)+1] = rxF_comp[(re *2)+1];
+ re_cnt++;
+ }
+ else
+ {
+ /* Skip PTRS symbols and keep data in a continuous vector */
+ rxF_comp[cnt *2]= rxF_comp[re *2];
+ rxF_comp[(cnt *2)+1]= rxF_comp[(re *2)+1];
+ cnt++;
+ }
+ }/* RE loop */
+ /* update the total ptrs RE in a symbol */
+ *ptrs_sc = re_cnt;
+
+ /*Multiple compensated data with conj of PTRS */
+ mult_cpx_vector(dmrs_comp_p, ptrs_p, ptrs_ch_p,(1 + sc_per_symbol/4)*4,15); // 2^15 shifted
+
+ /* loop over all ptrs sub carriers in a symbol */
+ /* sum the error vector */
+ for(int i = 0;i < sc_per_symbol; i++)
+ {
+ real+= ptrs_ch_p[(2*i)];
+ imag+= ptrs_ch_p[(2*i)+1];
+ }
+#ifdef DEBUG_UL_PTRS
+ alpha = atan(imag/real);
+ printf("PTRS: Symbol %d atan(Im,real):= %f \n",symbol, alpha );
+#endif
+ /* mean */
+ real /= sc_per_symbol;
+ imag /= sc_per_symbol;
+ /* absolute calculation */
+ abs = sqrt(((real * real) + (imag * imag)));
+ /* normalized error estimation */
+ error_est[0]= (real / abs)*(1<<15);
+ /* compensation in given by conjugate of estimated phase (e^-j*2*pi*fd*t)*/
+ error_est[1]= (-1)*(imag / abs)*(1<<15);
+#ifdef DEBUG_UL_PTRS
+ printf("PTRS: Estimated Symbol %d -> %d + j* %d \n",symbol, error_est[0], error_est[1] );
+#endif
+ /* free vectors */
+ free(ptrs_p);
+ free(dmrs_comp_p);
+}
+
+
+/*******************************************************************
+ *
+ * NAME : nr_pusch_phase_interpolation
+ *
+ * PARAMETERS : *error_est : Data Pointer [Re Im Re Im ...]
+ * start_symbol : Start Symbol
+ * end_symbol : End Symbol
+ * RETURN : nothing
+ *
+ * DESCRIPTION :
+ * Perform Interpolation, extrapolation based upon the estimation
+ * location between the data Pointer Array.
+ *
+ *********************************************************************/
+void nr_pusch_phase_interpolation(int16_t *error_est,
+ uint8_t start_symbol,
+ uint8_t end_symbol
+ )
+{
+
+ int next = 0, prev = 0, candidates= 0, distance=0, leftEdge= 0, rightEdge = 0, getDiff =0 ;
+ double weight = 0.0;
+ double scale = 0.125 ; // to avoid saturation due to fixed point multiplication
+#ifdef DEBUG_UL_PTRS
+ printf("PTRS: INT: Left limit %d, Right limit %d, Loop over %d Symbols \n",
+ start_symbol,end_symbol-1, (end_symbol -start_symbol)-1);
+#endif
+ for(int i =start_symbol; i< end_symbol;i++)
+ {
+ /* Only update when an estimation is found */
+ if( error_est[i*2] != 0 )
+ {
+ /* if found a symbol then set next symbol also */
+ next = nr_ptrs_find_next_estimate(error_est, i, end_symbol);
+ /* left extrapolation, if first estimate value is zero */
+ if( error_est[i*2] == 0 )
+ {
+ leftEdge = 1;
+ }
+ /* right extrapolation, if next is 0 before end symbol */
+ if((next == 0) && (end_symbol > i))
+ {
+ rightEdge = 1;
+ /* special case as no right extrapolation possible with DMRS on left */
+ /* In this case take mean of most recent 2 estimated points */
+ if(prev ==0)
+ {
+ prev = start_symbol -1;
+ next = start_symbol -2;
+ getDiff =1;
+ }else
+ {
+ /* for right edge previous is second last from right side */
+ next = prev;
+ /* Set the current as recent estimation reference */
+ prev = i;
+ }
+ }
+ /* update current symbol as prev for next symbol */
+ if (rightEdge==0)
+ /* Set the current as recent estimation reference */
+ prev = i;
+ }
+ /*extrapolation left side*/
+ if(leftEdge)
+ {
+ distance = next - prev;
+ weight = 1.0/distance;
+ candidates = i;
+ for(int j = 1; j <= candidates; j++)
+ {
+ error_est[(i-j)*2] = 8 *(((double)(error_est[prev*2]) * scale * (distance + j) * weight) -
+ ((double)(error_est[next*2]) * scale * j * weight));
+ error_est[((i-j)*2)+1]= 8 *(((double)(error_est[(prev*2)+1]) * scale* (distance + j) * weight) -
+ ((double)(error_est[((next*2)+1)]) * scale * j * weight));
+#ifdef DEBUG_UL_PTRS
+ printf("PTRS: INT: Left Edge i= %d weight= %f %d + j*%d, Prev %d Next %d \n",
+ (i-j),weight, error_est[(i-j)*2],error_est[((i-j)*2)+1], prev,next);
+#endif
+ }
+ leftEdge = 0;
+ }
+ /* extrapolation at right side */
+ else if (rightEdge )
+ {
+ if(getDiff)
+ {
+ error_est[(i+1)*2] = ((1<<15) +(error_est[prev*2]) - error_est[next*2]);
+ error_est[((i+1)*2)+1]= error_est[(prev*2)+1] - error_est[(next*2)+1];
+#ifdef DEBUG_UL_PTRS
+ printf("PTRS: INT: Right Edge Special Case i= %d weight= %f %d + j*%d, Prev %d Next %d \n",
+ (i+1),weight, error_est[(i+1)*2],error_est[((i+1)*2)+1], prev,next);
+#endif
+ i++;
+ }
+ else
+ {
+ distance = prev - next;
+ candidates = (end_symbol -1) - i;
+ weight = 1.0/distance;
+ for(int j = 1; j <= candidates; j++)
+ {
+ error_est[(i+j)*2] = 8 *(((double)(error_est[prev*2]) * scale * (distance + j) * weight) -
+ ((double)(error_est[next*2]) * scale * j * weight));
+ error_est[((i+j)*2)+1]= 8 *(((double)(error_est[(prev*2)+1]) * scale * (distance + j) * weight) -
+ ((double)(error_est[((next*2)+1)]) * scale *j * weight));
+#ifdef DEBUG_UL_PTRS
+ printf("PTRS: INT: Right Edge i= %d weight= %f %d + j*%d, Prev %d Next %d \n",
+ (i+j),weight, error_est[(i+j)*2],error_est[((i+j)*2)+1], prev,next);
+#endif
+ }
+ if(candidates > 1)
+ {
+ i+=candidates;
+ }
+ }
+ }
+ /* Interpolation between 2 estimated points */
+ else if(next != 0 && ( error_est[2*i] == 0 ))
+ {
+ distance = next - prev;
+ weight = 1.0/distance;
+ candidates = next - i ;
+ for(int j = 0; j < candidates; j++)
+ {
+
+ error_est[(i+j)*2] = 8 *(((double)(error_est[prev*2]) * scale * (distance - (j+1)) * weight) +
+ ((double)(error_est[next*2]) * scale * (j+1) * weight));
+ error_est[((i+j)*2)+1]= 8 *(((double)(error_est[(prev*2)+1]) * scale *(distance - (j+1)) * weight) +
+ ((double)(error_est[((next*2)+1)]) * scale *(j+1) * weight));
+#ifdef DEBUG_UL_PTRS
+ printf("PTRS: INT: Interpolation i= %d weight= %f %d + j*%d, Prev %d Next %d\n",
+ (i+j),weight, error_est[(i+j)*2],error_est[((i+j)*2)+1],prev,next);
+#endif
+ }
+ if(candidates > 1)
+ {
+ i+=candidates-1;
+ }
+ }// interpolation
+ }// symbol loop
+}
+
+/* Find the next non zero Real value in a complex vector */
+int nr_ptrs_find_next_estimate(int16_t *error_est,
+ uint8_t counter,
+ uint8_t end_symbol)
+{
+ for (int i = counter +1 ; i< end_symbol; i++)
+ {
+ if( error_est[2*i] != 0)
+ {
+ return i;
+ }
+ }
+ return 0;
+}
diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h
index 17d8c998c9..0f71487e36 100644
--- a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h
+++ b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h
@@ -51,4 +51,30 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB);
int nr_est_timing_advance_pusch(PHY_VARS_gNB* phy_vars_gNB, int UE_id);
+
+void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
+ nfapi_nr_pusch_pdu_t *rel15_ul,
+ uint8_t ulsch_id,
+ uint8_t nr_tti_rx,
+ uint8_t dmrs_symbol_flag,
+ unsigned char symbol,
+ uint32_t nb_re_pusch);
+
+void nr_pusch_phase_estimation(NR_DL_FRAME_PARMS *frame_parms,
+ nfapi_nr_pusch_pdu_t *rel15_ul,
+ int16_t *ptrs_ch_p,
+ unsigned char Ns,
+ unsigned char symbol,
+ int16_t *rxF_comp,
+ uint32_t ***ptrs_gold_seq,
+ int16_t *error_est,
+ uint16_t *ptrs_sc);
+
+void nr_pusch_phase_interpolation(int16_t *error_est,
+ uint8_t start_symbol,
+ uint8_t end_symbol);
+
+int nr_ptrs_find_next_estimate(int16_t *error_est,
+ uint8_t counter,
+ uint8_t end_symbol);
#endif
diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.c b/openair1/PHY/NR_REFSIG/dmrs_nr.c
index 7042c152fd..415e6adfa2 100644
--- a/openair1/PHY/NR_REFSIG/dmrs_nr.c
+++ b/openair1/PHY/NR_REFSIG/dmrs_nr.c
@@ -362,4 +362,25 @@ void generate_dmrs_pbch(uint32_t dmrs_pbch_bitmap[DMRS_PBCH_I_SSB][DMRS_PBCH_N_H
free(dmrs_sequence);
#endif
}
+/* return the position of next dmrs symbol in a slot */
+int get_next_dmrs_symbol_in_slot(uint16_t ul_dmrs_symb_pos, uint8_t counter, uint8_t end_symbol)
+{
+ for(uint8_t symbol = counter; symbol < end_symbol; symbol++)
+ if((ul_dmrs_symb_pos >>symbol)&0x01 )
+ {
+ return symbol;
+ }
+ return 0;
+}
+
+/* return the total number of dmrs symbol in a slot */
+uint8_t get_dmrs_symbols_in_slot(uint16_t l_prime_mask, uint16_t nb_symb)
+{
+ uint8_t tmp = 0;
+ for (int i = 0; i < nb_symb; i++)
+ {
+ tmp += (l_prime_mask >> i) & 0x01;
+ }
+ return tmp;
+}
diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c
index 4eeb8a6e96..3e758c4fa5 100644
--- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c
+++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c
@@ -223,3 +223,27 @@ int nr_pbch_dmrs_rx(int symbol,
return(0);
}
+
+/*!
+ \brief This function generate gold ptrs sequence for each OFDM symbol
+ \param *in gold sequence for ptrs per OFDM symbol
+ \param length is number of RE in a OFDM symbol
+ \param *output pointer to all ptrs RE in a OFDM symbol
+*/
+void nr_gen_ref_conj_symbols(uint32_t *in, uint32_t length, int16_t *output, uint16_t offset, int mod_order)
+{
+ uint8_t idx, b_idx;
+ for (int i=0; i>b_idx)&1)<<(mod_order-j-1);
+ }
+ output[i<<1] = nr_rx_mod_table[(offset+idx)<<1];
+ output[(i<<1)+1] = nr_rx_mod_table[((offset+idx)<<1)+1];
+ }
+}
diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h
index ab9beb780a..ced7f9eb66 100644
--- a/openair1/PHY/NR_REFSIG/nr_refsig.h
+++ b/openair1/PHY/NR_REFSIG/nr_refsig.h
@@ -52,6 +52,9 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB,
uint8_t dmrs_type);
void init_scrambling_luts(void);
+void nr_gen_ref_conj_symbols(uint32_t *in, uint32_t length, int16_t *output, uint16_t offset, int mod_order);
+uint8_t get_next_dmrs_symbol_in_slot(uint16_t ul_dmrs_symb_pos, uint8_t counter, uint8_t end_symbol);
+uint8_t get_dmrs_symbols_in_slot(uint16_t l_prime_mask, uint16_t nb_symb);
void nr_generate_modulation_table(void);
diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
index b8025a828b..8cb7ad45e7 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
@@ -157,7 +157,6 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
NR_gNB_PUSCH *pusch_vars,
unsigned char symbol,
uint8_t is_dmrs_symbol,
- uint8_t is_ptrs_symbol,
nfapi_nr_pusch_pdu_t *pusch_pdu,
NR_DL_FRAME_PARMS *frame_parms);
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
index 622e18f082..3fd7966ce7 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
@@ -226,25 +226,19 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
NR_gNB_PUSCH *pusch_vars,
unsigned char symbol,
uint8_t is_dmrs_symbol,
- uint8_t is_ptrs_symbol,
nfapi_nr_pusch_pdu_t *pusch_pdu,
NR_DL_FRAME_PARMS *frame_parms)
{
unsigned short start_re, re, nb_re_pusch;
unsigned char aarx;
- uint8_t K_ptrs = 0;
uint32_t rxF_ext_index = 0;
uint32_t ul_ch0_ext_index = 0;
uint32_t ul_ch0_index = 0;
- uint32_t ul_ch0_ptrs_ext_index = 0;
- uint32_t ul_ch0_ptrs_index = 0;
uint8_t k_prime;
- uint16_t n=0, num_ptrs_symbols;
+ uint16_t n;
int16_t *rxF,*rxF_ext;
int *ul_ch0,*ul_ch0_ext;
- int *ul_ch0_ptrs,*ul_ch0_ptrs_ext;
- uint16_t n_rnti = pusch_pdu->rnti;
uint8_t delta = 0;
#ifdef DEBUG_RB_EXT
@@ -253,8 +247,8 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
printf("--------------------ch_ext_index = %d-----------------------\n", symbol*NR_NB_SC_PER_RB * pusch_pdu->rb_size);
#endif
-
- uint8_t is_dmrs_re=0,is_ptrs_re=0;
+
+ 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;
nb_re_pusch = NR_NB_SC_PER_RB * pusch_pdu->rb_size;
#ifdef __AVX2__
@@ -263,10 +257,8 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
int nb_re_pusch2 = nb_re_pusch;
#endif
- num_ptrs_symbols = 0;
-
for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
-
+
rxF = (int16_t *)&rxdataF[aarx][symbol * frame_parms->ofdm_symbol_size];
rxF_ext = (int16_t *)&pusch_vars->rxdataF_ext[aarx][symbol * nb_re_pusch2]; // [hna] rxdataF_ext isn't contiguous in order to solve an alignment problem ib llr computation in case of mod_order = 4, 6
@@ -274,20 +266,17 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
ul_ch0_ext = &pusch_vars->ul_ch_estimates_ext[aarx][symbol*nb_re_pusch2];
- ul_ch0_ptrs = &pusch_vars->ul_ch_ptrs_estimates[aarx][pusch_vars->ptrs_symbol_index*frame_parms->ofdm_symbol_size]; // update channel estimates if new dmrs symbol are available
-
- ul_ch0_ptrs_ext = &pusch_vars->ul_ch_ptrs_estimates_ext[aarx][symbol*nb_re_pusch];
-
n = 0;
k_prime = 0;
- if (is_dmrs_symbol == 0 && is_ptrs_symbol == 0) {
+ if (is_dmrs_symbol == 0) {
//
//rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]);
- if (start_re + nb_re_pusch < frame_parms->ofdm_symbol_size) memcpy1((void*)rxF_ext,
- (void*)&rxF[start_re*2],
- nb_re_pusch*sizeof(int32_t));
- else {
+ if (start_re + nb_re_pusch < frame_parms->ofdm_symbol_size) {
+ memcpy1((void*)rxF_ext,
+ (void*)&rxF[start_re*2],
+ nb_re_pusch*sizeof(int32_t));
+ } else {
int neg_length = frame_parms->ofdm_symbol_size-start_re;
int pos_length = nb_re_pusch-neg_length;
@@ -298,58 +287,36 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
}
else {
for (re = 0; re < nb_re_pusch; re++) {
-
- if (is_dmrs_symbol) is_dmrs_re = (re == get_dmrs_freq_idx_ul(n, k_prime, delta, pusch_pdu->dmrs_config_type));
-
- if (is_ptrs_symbol) {
- K_ptrs = (pusch_pdu->pusch_ptrs.ptrs_freq_density)?4:2;
- is_ptrs_re = is_ptrs_subcarrier((start_re + re) % frame_parms->ofdm_symbol_size,
- n_rnti,
- aarx,
- pusch_pdu->dmrs_config_type,
- K_ptrs,
- pusch_pdu->rb_size,
- pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset,
- start_re,
- frame_parms->ofdm_symbol_size);
-
- num_ptrs_symbols+=is_ptrs_re;
-
- }
-
+
+ is_dmrs_re = (re == get_dmrs_freq_idx_ul(n, k_prime, delta, pusch_pdu->dmrs_config_type));
+
#ifdef DEBUG_RB_EXT
- printf("re = %d, kprime %d, n %d, is_ptrs_symbol = %d, symbol = %d\n", re, k_prime,n,is_ptrs_symbol, symbol);
+ printf("re = %d, kprime %d, n %d, is_dmrs_symbol = %d, symbol = %d\n", re, k_prime, n, is_dmrs_symbol, symbol);
#endif
- if ( is_dmrs_re == 0 && is_ptrs_re == 0) {
-
- rxF_ext[rxF_ext_index] = (rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]);
- rxF_ext[rxF_ext_index + 1] = (rxF[(((start_re + re)*2) + 1) % (frame_parms->ofdm_symbol_size*2)]);
- ul_ch0_ext[ul_ch0_ext_index] = ul_ch0[ul_ch0_index];
- ul_ch0_ptrs_ext[ul_ch0_ptrs_ext_index] = ul_ch0_ptrs[ul_ch0_ptrs_index];
-
+ /* save only data and respective channel estimates */
+ if (is_dmrs_re == 0) {
+ rxF_ext[rxF_ext_index] = (rxF[ ((start_re + re)*2) % (frame_parms->ofdm_symbol_size*2)]);
+ rxF_ext[rxF_ext_index + 1] = (rxF[(((start_re + re)*2) + 1) % (frame_parms->ofdm_symbol_size*2)]);
+ ul_ch0_ext[ul_ch0_ext_index] = ul_ch0[ul_ch0_index];
+
#ifdef DEBUG_RB_EXT
- printf("dmrs symb %d: rxF_ext[%d] = (%d,%d), ul_ch0_ext[%d] = (%d,%d)\n",
- is_dmrs_symbol,rxF_ext_index>>1, rxF_ext[rxF_ext_index],rxF_ext[rxF_ext_index+1],
- ul_ch0_ext_index, ((int16_t*)&ul_ch0_ext[ul_ch0_ext_index])[0], ((int16_t*)&ul_ch0_ext[ul_ch0_ext_index])[1]);
+ printf("dmrs symb %d: rxF_ext[%d] = (%d,%d), ul_ch0_ext[%d] = (%d,%d)\n",
+ is_dmrs_symbol,rxF_ext_index>>1, rxF_ext[rxF_ext_index],rxF_ext[rxF_ext_index+1],
+ ul_ch0_ext_index, ((int16_t*)&ul_ch0_ext[ul_ch0_ext_index])[0], ((int16_t*)&ul_ch0_ext[ul_ch0_ext_index])[1]);
#endif
- ul_ch0_ext_index++;
- ul_ch0_ptrs_ext_index++;
- rxF_ext_index +=2;
- } else {
- k_prime++;
- k_prime&=1;
- n+=(k_prime)?0:1;
- }
- ul_ch0_index++;
- ul_ch0_ptrs_index++;
+ ul_ch0_ext_index++;
+ rxF_ext_index +=2;
+ } else {
+ n += k_prime;
+ k_prime ^= 1;
+ }
+ ul_ch0_index++;
}
- } // is_dmrs_symbol ==0 && is_ptrs_symbol == 0
- }
- pusch_vars->ptrs_sc_per_ofdm_symbol = num_ptrs_symbols;
-
+ }
+ }
}
-
+
void nr_ulsch_scale_channel(int **ul_ch_estimates_ext,
NR_DL_FRAME_PARMS *frame_parms,
NR_gNB_ULSCH_t **ulsch_gNB,
@@ -1116,34 +1083,17 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
{
uint8_t aarx, aatx, dmrs_symbol_flag; // dmrs_symbol_flag, a flag to indicate DMRS REs in current symbol
- uint8_t ptrs_symbol_flag; // a flag to indicate PTRS REs in current symbol
uint32_t nb_re_pusch, bwp_start_subcarrier;
- uint8_t L_ptrs = 0; // PTRS parameter
int avgs;
int avg[4];
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
nfapi_nr_pusch_pdu_t *rel15_ul = &gNB->ulsch[ulsch_id][0]->harq_processes[harq_pid]->ulsch_pdu;
dmrs_symbol_flag = 0;
- ptrs_symbol_flag = 0;
-
- gNB->pusch_vars[ulsch_id]->ptrs_sc_per_ofdm_symbol = 0;
if(symbol == rel15_ul->start_symbol_index){
- gNB->pusch_vars[ulsch_id]->rxdataF_ext_offset = 0;
gNB->pusch_vars[ulsch_id]->dmrs_symbol = 0;
gNB->pusch_vars[ulsch_id]->cl_done = 0;
- gNB->pusch_vars[ulsch_id]->ptrs_symbols = 0;
-
- if (rel15_ul->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { // if there is ptrs pdu
- L_ptrs = 1<<(rel15_ul->pusch_ptrs.ptrs_time_density);
-
- set_ptrs_symb_idx(&gNB->pusch_vars[ulsch_id]->ptrs_symbols,
- rel15_ul->nr_of_symbols,
- rel15_ul->start_symbol_index,
- L_ptrs,
- rel15_ul->ul_dmrs_symb_pos);
- }
}
@@ -1172,13 +1122,6 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
nb_re_pusch = rel15_ul->rb_size * NR_NB_SC_PER_RB;
}
- if (rel15_ul->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) { // if there is ptrs pdu
- if(is_ptrs_symbol(symbol, gNB->pusch_vars[ulsch_id]->ptrs_symbols)) {
- gNB->pusch_vars[ulsch_id]->ptrs_symbol_index = symbol;
- ptrs_symbol_flag = 1;
- }
- }
-
//----------------------------------------------------------
//--------------------- Channel estimation ---------------------
//----------------------------------------------------------
@@ -1206,16 +1149,21 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
if (nb_re_pusch > 0) {
+ gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol] = nb_re_pusch;
+
start_meas(&gNB->ulsch_rbs_extraction_stats);
nr_ulsch_extract_rbs_single(gNB->common_vars.rxdataF,
gNB->pusch_vars[ulsch_id],
symbol,
dmrs_symbol_flag,
- ptrs_symbol_flag,
rel15_ul,
frame_parms);
stop_meas(&gNB->ulsch_rbs_extraction_stats);
+ //----------------------------------------------------------
+ //--------------------- Channel Scaling --------------------
+ //----------------------------------------------------------
+
nr_ulsch_scale_channel(gNB->pusch_vars[ulsch_id]->ul_ch_estimates_ext,
frame_parms,
gNB->ulsch[ulsch_id],
@@ -1244,6 +1192,10 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
gNB->pusch_vars[ulsch_id]->cl_done = 1;
}
+ //----------------------------------------------------------
+ //--------------------- Channel Compensation ---------------
+ //----------------------------------------------------------
+
start_meas(&gNB->ulsch_channel_compensation_stats);
nr_ulsch_channel_compensation(gNB->pusch_vars[ulsch_id]->rxdataF_ext,
gNB->pusch_vars[ulsch_id]->ul_ch_estimates_ext,
@@ -1271,29 +1223,54 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
nr_idft(&((uint32_t*)gNB->pusch_vars[ulsch_id]->rxdataF_ext[0])[symbol * rel15_ul->rb_size * NR_NB_SC_PER_RB], nb_re_pusch);
#endif
- //----------------------------------------------------------
- //-------------------- LLRs computation --------------------
- //----------------------------------------------------------
- start_meas(&gNB->ulsch_llr_stats);
- AssertFatal(gNB->pusch_vars[ulsch_id]->rxdataF_ext_offset * rel15_ul->qam_mod_order+nb_re_pusch*rel15_ul->qam_mod_order < (8*((3*8*6144)+12)) , "Mysterious llr buffer size check");
+
+ //----------------------------------------------------------
+ //--------------------- PTRS Processing --------------------
+ //----------------------------------------------------------
+
+ /* In case PTRS is enabled then LLR will be calculated after PTRS symbols are processed *
+ * otherwise LLR are calculated for each symbol based upon DMRS channel estimates only. */
+ if (rel15_ul->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS)
+ {
+ start_meas(&gNB->ulsch_ptrs_processing_stats);
+ nr_pusch_ptrs_processing(gNB,
+ rel15_ul,
+ ulsch_id,
+ nr_tti_rx,
+ dmrs_symbol_flag,
+ symbol,
+ nb_re_pusch);
+ stop_meas(&gNB->ulsch_ptrs_processing_stats);
+
+ /* Subtract total PTRS RE's in the symbol from PUSCH RE's */
+ gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol] -= gNB->pusch_vars[ulsch_id]->ptrs_sc_per_ofdm_symbol;
+ }
+
+ /*---------------------------------------------------------------------------------------------------- */
+ /*-------------------- LLRs computation -------------------------------------------------------------*/
+ /*-----------------------------------------------------------------------------------------------------*/
+ if(symbol == (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols -1))
+ {
#ifdef __AVX2__
- int off = ((rel15_ul->rb_size&1) == 1)? 4:0;
+ int off = ((rel15_ul->rb_size&1) == 1)? 4:0;
#else
- int off = 0;
+ int off = 0;
#endif
- nr_ulsch_compute_llr(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[0][symbol * (off+(rel15_ul->rb_size * NR_NB_SC_PER_RB))],
- gNB->pusch_vars[ulsch_id]->ul_ch_mag0,
- gNB->pusch_vars[ulsch_id]->ul_ch_magb0,
- &gNB->pusch_vars[ulsch_id]->llr[gNB->pusch_vars[ulsch_id]->rxdataF_ext_offset * rel15_ul->qam_mod_order],
- rel15_ul->rb_size,
- nb_re_pusch,
- symbol,
- rel15_ul->qam_mod_order);
- stop_meas(&gNB->ulsch_llr_stats);
-
+ uint32_t rxdataF_ext_offset = 0;
+ for(uint8_t i =rel15_ul->start_symbol_index; i< (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols);i++) {
+ start_meas(&gNB->ulsch_llr_stats);
+ nr_ulsch_compute_llr(&gNB->pusch_vars[ulsch_id]->rxdataF_comp[0][i * (off + rel15_ul->rb_size * NR_NB_SC_PER_RB)],
+ gNB->pusch_vars[ulsch_id]->ul_ch_mag0,
+ gNB->pusch_vars[ulsch_id]->ul_ch_magb0,
+ &gNB->pusch_vars[ulsch_id]->llr[rxdataF_ext_offset * rel15_ul->qam_mod_order],
+ rel15_ul->rb_size,
+ gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[i],
+ i,
+ rel15_ul->qam_mod_order);
+ stop_meas(&gNB->ulsch_llr_stats);
+ rxdataF_ext_offset += gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[i];
+ }// symbol loop
+ }// last symbol check
}
-
- gNB->pusch_vars[ulsch_id]->rxdataF_ext_offset = gNB->pusch_vars[ulsch_id]->rxdataF_ext_offset + nb_re_pusch;
return (0);
-
}
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
index bb82140905..c85a7691f6 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
@@ -226,12 +226,12 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
/////////////////////////PTRS parameters' initialization/////////////////////////
///////////
- int16_t mod_ptrs[(nb_rb/2)*(NR_SYMBOLS_PER_SLOT-1)*2]; // assume maximum number of PTRS per pusch allocation
+ int16_t mod_ptrs[nb_rb] __attribute((aligned(16))); // assume maximum number of PTRS per pusch allocation
K_ptrs = 0; // just to avoid a warning
if (harq_process_ul_ue->pusch_pdu.pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
- K_ptrs = (harq_process_ul_ue->pusch_pdu.pusch_ptrs.ptrs_freq_density)?4:2;
+ K_ptrs = harq_process_ul_ue->pusch_pdu.pusch_ptrs.ptrs_freq_density;
L_ptrs = 1<pusch_pdu.pusch_ptrs.ptrs_time_density;
beta_ptrs = 1; // temp value until power control is implemented
@@ -322,7 +322,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
uint16_t m=0, n=0, dmrs_idx=0, ptrs_idx = 0;
for (l=start_symbol; lsymbols_per_tti[
int32_t **rxdataF_ext2;
- /// \brief Offset for calculating the index of rxdataF_ext for the current symbol
- uint32_t rxdataF_ext_offset;
/// \brief Hold the channel estimates in time domain based on DRS.
/// - first index: rx antenna id [0..nb_antennas_rx[
/// - second index: ? [0..4*ofdm_symbol_size[
@@ -466,6 +464,13 @@ typedef struct {
uint16_t ptrs_symbols;
// PTRS subcarriers per OFDM symbol
uint16_t ptrs_sc_per_ofdm_symbol;
+ /// \brief Estimated phase error based upon PTRS on each symbol .
+ /// - first index: ? [0..7] Number of Antenna
+ /// - second index: ? [0...14] smybol per slot
+ int32_t **ptrs_phase_per_slot;
+ /// \brief Total RE count after DMRS/PTRS RE's are extracted from respective symbol.
+ /// - first index: ? [0...14] smybol per slot
+ int16_t *ul_valid_re_per_slot;
/// flag to verify if channel level computation is done
uint8_t cl_done;
} NR_gNB_PUSCH;
@@ -807,10 +812,12 @@ typedef struct PHY_VARS_gNB_s {
time_stats_t ulsch_deinterleaving_stats;
time_stats_t ulsch_unscrambling_stats;
time_stats_t ulsch_channel_estimation_stats;
+ time_stats_t ulsch_ptrs_processing_stats;
time_stats_t ulsch_channel_compensation_stats;
time_stats_t ulsch_rbs_extraction_stats;
time_stats_t ulsch_mrc_stats;
time_stats_t ulsch_llr_stats;
+
/*
time_stats_t rx_dft_stats;
time_stats_t ulsch_freq_offset_estimation_stats;
diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c
index 6e4970525d..9dd6d61557 100644
--- a/openair1/SIMULATION/NR_PHY/ulsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulsim.c
@@ -165,6 +165,13 @@ int main(int argc, char **argv)
//float eff_tp_check = 0.7;
uint8_t snrRun;
+ int enable_ptrs = 0;
+ int modify_dmrs = 0;
+ /* L_PTRS = ptrs_arg[0], K_PTRS = ptrs_arg[1] */
+ int ptrs_arg[2] = {-1,-1};// Invalid values
+ /* DMRS TYPE = dmrs_arg[0], Add Pos = dmrs_arg[1] */
+ int dmrs_arg[2] = {-1,-1};// Invalid values
+
UE_nr_rxtx_proc_t UE_proc;
FILE *scg_fd=NULL;
int file_offset = 0;
@@ -181,7 +188,7 @@ int main(int argc, char **argv)
//logInit();
randominit(0);
- while ((c = getopt(argc, argv, "a:b:c:d:ef:g:h:i:j:kl:m:n:p:r:s:y:z:F:M:N:PR:S:L:G:H:")) != -1) {
+ while ((c = getopt(argc, argv, "a:b:c:d:ef:g:h:i:j:kl:m:n:p:r:s:y:z:F:G:H:M:N:PR:S:T:U:L:")) != -1) {
printf("handling optarg %c\n",c);
switch (c) {
@@ -359,7 +366,15 @@ int main(int argc, char **argv)
}
break;
-
+
+ case 'G':
+ file_offset = atoi(optarg);
+ break;
+
+ case 'H':
+ slot = atoi(optarg);
+ break;
+
case 'M':
// SSB_positions = atoi(optarg);
break;
@@ -388,14 +403,20 @@ int main(int argc, char **argv)
loglvl = atoi(optarg);
break;
- case 'G':
- file_offset = atoi(optarg);
+ case 'T':
+ enable_ptrs=1;
+ for(i=0; i < atoi(optarg); i++){
+ ptrs_arg[i] = atoi(argv[optind++]);
+ }
break;
- case 'H':
- slot = atoi(optarg);
+ case 'U':
+ modify_dmrs = 1;
+ for(i=0; i < atoi(optarg); i++){
+ dmrs_arg[i] = atoi(argv[optind++]);
+ }
break;
-
+
default:
case 'h':
printf("%s -h(elp) -p(extended_prefix) -N cell_id -f output_filename -F input_filename -g channel_model -n n_frames -t Delayspread -s snr0 -S snr1 -x transmission_mode -y TXant -z RXant -i Intefrence0 -j Interference1 -A interpolation_file -C(alibration offset dB) -N CellId\n", argv[0]);
@@ -425,6 +446,8 @@ int main(int argc, char **argv)
printf("-t Acceptable effective throughput (in percentage)\n");
printf("-S Ending SNR, runs from SNR0 to SNR1\n");
printf("-P Print ULSCH performances\n");
+ printf("-T Enable PTRS, arguments list L_PTRS{0,1,2} K_PTRS{2,4}, e.g. -T 2 0 2 \n");
+ printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:3}, e.g. -U 2 0 2 \n");
exit(-1);
break;
@@ -469,7 +492,7 @@ int main(int argc, char **argv)
UE2gNB->max_Doppler = maxDoppler;
RC.gNB = (PHY_VARS_gNB **) malloc(sizeof(PHY_VARS_gNB *));
- RC.gNB[0] = malloc(sizeof(PHY_VARS_gNB));
+ RC.gNB[0] = calloc(1,sizeof(PHY_VARS_gNB));
gNB = RC.gNB[0];
//gNB_config = &gNB->gNB_config;
@@ -513,7 +536,7 @@ int main(int argc, char **argv)
0);
fix_scc(scc,ssb_bitmap);
- xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup);
+ // xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void*)secondaryCellGroup);
AssertFatal((gNB->if_inst = NR_IF_Module_init(0))!=NULL,"Cannot register interface");
@@ -607,13 +630,9 @@ int main(int argc, char **argv)
nr_scheduled_response_t scheduled_response;
fapi_nr_ul_config_request_t ul_config;
+ fapi_nr_tx_request_t tx_req;
+ fapi_nr_tx_request_body_t tx_req_body;
- unsigned int TBS;
- uint16_t number_dmrs_symbols = 0;
- unsigned int available_bits;
- uint8_t nb_re_dmrs;
- unsigned char mod_order;
- uint16_t code_rate;
uint8_t ptrs_mcs1 = 2;
uint8_t ptrs_mcs2 = 4;
uint8_t ptrs_mcs3 = 10;
@@ -624,23 +643,74 @@ int main(int argc, char **argv)
uint8_t max_rounds = 4;
uint8_t crc_status = 0;
- uint8_t length_dmrs = pusch_len1; // [hna] remove dmrs struct
- uint16_t l_prime_mask = get_l_prime(nb_symb_sch, typeB, pusch_dmrs_pos0, length_dmrs); // [hna] remove dmrs struct
+ unsigned char mod_order = nr_get_Qm_ul(Imcs, 0);
+ uint16_t code_rate = nr_get_code_rate_ul(Imcs, 0);
+
+ uint8_t mapping_type = typeB; // Default Values
+ pusch_dmrs_type_t dmrs_config_type = pusch_dmrs_type1; // Default Values
+ pusch_dmrs_AdditionalPosition_t add_pos = pusch_dmrs_pos0; // Default Values
+
+ /* validate parameters othwerwise default values are used */
+ /* -U flag can be used to set DMRS parameters*/
+ if(modify_dmrs)
+ {
+ if(dmrs_arg[0] == 0)
+ {
+ mapping_type = typeA;
+ }
+ else if (dmrs_arg[0] == 1)
+ {
+ mapping_type = typeB;
+ }
+ /* Additional DMRS positions */
+ if(dmrs_arg[1] >= 0 && dmrs_arg[1] <=3 )
+ {
+ add_pos = dmrs_arg[1];
+ }
+ printf("NOTE: DMRS config is modified with Mapping Type %d , Additional Position %d \n", mapping_type, add_pos );
+ }
+
+ uint8_t length_dmrs = pusch_len1;
+ uint16_t l_prime_mask = get_l_prime(nb_symb_sch, mapping_type, add_pos, length_dmrs);
+ uint16_t number_dmrs_symbols = get_dmrs_symbols_in_slot(l_prime_mask, nb_symb_sch);
+ uint8_t nb_re_dmrs = (dmrs_config_type == pusch_dmrs_type1) ? 6 : 4;
+ unsigned int available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, number_dmrs_symbols, mod_order, 1);
+ unsigned int TBS = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs * number_dmrs_symbols, 0, 0, precod_nbr_layers);
+
+ uint8_t ulsch_input_buffer[TBS/8];
+
+ ulsch_input_buffer[0] = 0x31;
+ for (i = 1; i < TBS/8; i++) {
+ ulsch_input_buffer[i] = (unsigned char) rand();
+ }
+
uint8_t ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, Imcs, mcs_table);
uint8_t ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, nb_rb);
+ int ptrs_symbols = 0; // to calculate total PTRS RE's in a slot
+
+ double ts = 1.0/(frame_parms->subcarrier_spacing * frame_parms->ofdm_symbol_size);
+
+ /* -T option enable PTRS */
+ if(enable_ptrs)
+ {
+ /* validate parameters othwerwise default values are used */
+ if(ptrs_arg[0] == 0 || ptrs_arg[0] == 1 || ptrs_arg[0] == 2 )
+ {
+ ptrs_time_density = ptrs_arg[0];
+ }
+ if(ptrs_arg[1] == 2 || ptrs_arg[1] == 4 )
+ {
+ ptrs_freq_density = ptrs_arg[1];
+ }
+ pdu_bit_map |= PUSCH_PDU_BITMAP_PUSCH_PTRS;
+ printf("NOTE: PTRS Enabled with L %d, K %d \n", ptrs_time_density, ptrs_freq_density );
+ }
if (input_fd != NULL) max_rounds=1;
if(1<= nb_symb_sch)
pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
- for (i = 0; i < nb_symb_sch; i++) {
- number_dmrs_symbols += (l_prime_mask >> i) & 0x01;
- }
-
- mod_order = nr_get_Qm_ul(Imcs, 0);
- code_rate = nr_get_code_rate_ul(Imcs, 0);
-
printf("\n");
//for (int i=0;i<16;i++) printf("%f\n",gaussdouble(0.0,1.0));
@@ -715,6 +785,7 @@ int main(int argc, char **argv)
reset_meas(&gNB->ulsch_ldpc_decoding_stats);
reset_meas(&gNB->ulsch_unscrambling_stats);
reset_meas(&gNB->ulsch_channel_estimation_stats);
+ reset_meas(&gNB->ulsch_ptrs_processing_stats);
reset_meas(&gNB->ulsch_llr_stats);
reset_meas(&gNB->ulsch_mrc_stats);
reset_meas(&gNB->ulsch_channel_compensation_stats);
@@ -723,23 +794,6 @@ int main(int argc, char **argv)
UE_proc.nr_tti_tx = slot;
UE_proc.frame_tx = frame;
- // --------- setting parameters for gNB --------
- /*
- rel15_ul->rnti = n_rnti;
- rel15_ul->ulsch_pdu_rel15.start_rb = start_rb;
- rel15_ul->ulsch_pdu_rel15.number_rbs = nb_rb;
- rel15_ul->ulsch_pdu_rel15.start_symbol = start_symbol;
- rel15_ul->ulsch_pdu_rel15.number_symbols = nb_symb_sch;
- rel15_ul->ulsch_pdu_rel15.length_dmrs = length_dmrs;
- rel15_ul->ulsch_pdu_rel15.Qm = mod_order;
- rel15_ul->ulsch_pdu_rel15.mcs = Imcs;
- rel15_ul->ulsch_pdu_rel15.rv = 0;
- rel15_ul->ulsch_pdu_rel15.ndi = 0;
- rel15_ul->ulsch_pdu_rel15.n_layers = precod_nbr_layers;
- rel15_ul->ulsch_pdu_rel15.R = code_rate;
- ///////////////////////////////////////////////////
- */
-
UL_tti_req->SFN = frame;
UL_tti_req->Slot = slot;
UL_tti_req->n_pdus = 1;
@@ -766,6 +820,7 @@ int main(int argc, char **argv)
pusch_pdu->bwp_size = abwp_size;
}
+ pusch_pdu->pusch_data.tb_size = TBS/8;
pusch_pdu->pdu_bit_map = pdu_bit_map;
pusch_pdu->rnti = n_rnti;
pusch_pdu->mcs_index = Imcs;
@@ -776,7 +831,7 @@ int main(int argc, char **argv)
pusch_pdu->data_scrambling_id = *scc->physCellId;
pusch_pdu->nrOfLayers = 1;
pusch_pdu->ul_dmrs_symb_pos = l_prime_mask << start_symbol;
- pusch_pdu->dmrs_config_type = 0;
+ pusch_pdu->dmrs_config_type = dmrs_config_type;
pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId;
pusch_pdu->scid = 0;
pusch_pdu->dmrs_ports = 1;
@@ -809,8 +864,17 @@ int main(int argc, char **argv)
scheduled_response.slot = slot;
scheduled_response.dl_config = NULL;
scheduled_response.ul_config = &ul_config;
- scheduled_response.tx_request = (fapi_nr_tx_request_t *) malloc(sizeof(fapi_nr_tx_request_t));
- scheduled_response.tx_request->tx_request_body = (fapi_nr_tx_request_body_t *) malloc(sizeof(fapi_nr_tx_request_body_t));
+ scheduled_response.tx_request = &tx_req;
+ scheduled_response.tx_request->tx_request_body = &tx_req_body;
+
+ // Config UL TX PDU
+ tx_req.slot = slot;
+ tx_req.sfn = frame;
+ // tx_req->tx_config // TbD
+ tx_req.number_of_pdus = 1;
+ tx_req_body.pdu_length = TBS/8;
+ tx_req_body.pdu_index = 0;
+ tx_req_body.pdu = &ulsch_input_buffer[0];
ul_config.slot = slot;
ul_config.number_pdus = 1;
@@ -822,27 +886,22 @@ int main(int argc, char **argv)
ul_config.ul_config_list[0].pusch_config_pdu.nr_of_symbols = nb_symb_sch;
ul_config.ul_config_list[0].pusch_config_pdu.start_symbol_index = start_symbol;
ul_config.ul_config_list[0].pusch_config_pdu.ul_dmrs_symb_pos = l_prime_mask << start_symbol;
- ul_config.ul_config_list[0].pusch_config_pdu.dmrs_config_type = 0;
+ ul_config.ul_config_list[0].pusch_config_pdu.dmrs_config_type = dmrs_config_type;
ul_config.ul_config_list[0].pusch_config_pdu.mcs_index = Imcs;
ul_config.ul_config_list[0].pusch_config_pdu.mcs_table = mcs_table;
- ul_config.ul_config_list[0].pusch_config_pdu.num_dmrs_cdm_grps_no_data = 1;
+ ul_config.ul_config_list[0].pusch_config_pdu.num_dmrs_cdm_grps_no_data = msg3_flag == 0 ? 1 : 2;
+ ul_config.ul_config_list[0].pusch_config_pdu.nrOfLayers = precod_nbr_layers;
+ ul_config.ul_config_list[0].pusch_config_pdu.absolute_delta_PUSCH = 0;
+
+ ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.tb_size = TBS;
ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.new_data_indicator = trial & 0x1;
ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.rv_index = rv_index;
- ul_config.ul_config_list[0].pusch_config_pdu.nrOfLayers = precod_nbr_layers;
ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.harq_process_id = harq_pid;
+
ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_time_density = ptrs_time_density;
ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_freq_density = ptrs_freq_density;
ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list = (nfapi_nr_ue_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ue_ptrs_ports_t));
ul_config.ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
- //there are plenty of other parameters that we don't seem to be using for now. e.g.
- ul_config.ul_config_list[0].pusch_config_pdu.absolute_delta_PUSCH = 0;
-
- nb_re_dmrs = ((ul_config.ul_config_list[0].pusch_config_pdu.dmrs_config_type == pusch_dmrs_type1) ? 6 : 4);
-
- available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, number_dmrs_symbols, mod_order, 1);
- TBS = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs * number_dmrs_symbols, 0, 0, precod_nbr_layers);
- pusch_pdu->pusch_data.tb_size = TBS>>3;
- ul_config.ul_config_list[0].pusch_config_pdu.pusch_data.tb_size = TBS;
nr_fill_ulsch(gNB,frame,slot,pusch_pdu);
@@ -905,10 +964,15 @@ int main(int argc, char **argv)
for (ap=0; apnb_antennas_rx; ap++) {
((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i) + (delay*2)] = (int16_t)((tx_gain*r_re[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0))); // convert to fixed point
((int16_t*) &gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1 + (delay*2)] = (int16_t)((tx_gain*r_im[ap][i]) + (sqrt(sigma/2)*gaussdouble(0.0,1.0)));
+ /* Add phase noise if enabled */
+ if (pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
+ phase_noise(ts, &((int16_t*)&gNB->common_vars.rxdata[ap][slot_offset])[(2*i)],
+ &((int16_t*)&gNB->common_vars.rxdata[ap][slot_offset])[(2*i)+1]);
+ }
}
}
-
- }
+
+ }
////////////////////////////////////////////////////////////
@@ -963,6 +1027,20 @@ int main(int argc, char **argv)
}
if(n_trials==1) printf("end of round %d rv_index %d\n",round, rv_index);
+ //----------------------------------------------------------
+ //----------------- count and print errors -----------------
+ //----------------------------------------------------------
+
+ if ((pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) && (SNR==snr0) && (trial==0) && (round==0)) {
+ ptrs_symbols = 0;
+ for (int i = pusch_pdu->start_symbol_index; i < pusch_pdu->start_symbol_index + pusch_pdu->nr_of_symbols; i++){
+ ptrs_symbols += ((gNB->pusch_vars[UE_id]->ptrs_symbols) >> i) & 1;
+ }
+ /* 2*5*(50/2), for RB = 50,K = 2 for 5 OFDM PTRS symbols */
+ available_bits -= 2 * ptrs_symbols * ((nb_rb + ptrs_freq_density - 1) /ptrs_freq_density);
+ printf("After PTRS subtraction available_bits are : %u \n", available_bits);
+ }
+
for (i = 0; i < available_bits; i++) {
if(((ulsch_ue[0]->g[i] == 0) && (gNB->pusch_vars[UE_id]->llr[i] <= 0)) ||
@@ -977,12 +1055,6 @@ int main(int argc, char **argv)
} // round
- //----------------------------------------------------------
- //----------------- count and print errors -----------------
- //----------------------------------------------------------
-
-
-
if (n_trials == 1 && errors_scrambling[0] > 0) {
printf("\x1B[31m""[frame %d][trial %d]\tnumber of errors in unscrambling = %u\n" "\x1B[0m", frame, trial, errors_scrambling[0]);
}
@@ -1044,6 +1116,7 @@ int main(int argc, char **argv)
printDistribution(&gNB->phy_proc_rx,table_rx,"Total PHY proc rx");
printStatIndent(&gNB->rx_pusch_stats,"RX PUSCH time");
printStatIndent2(&gNB->ulsch_channel_estimation_stats,"ULSCH channel estimation time");
+ printStatIndent2(&gNB->ulsch_ptrs_processing_stats,"ULSCH PTRS Processing time");
printStatIndent2(&gNB->ulsch_rbs_extraction_stats,"ULSCH rbs extraction time");
printStatIndent2(&gNB->ulsch_channel_compensation_stats,"ULSCH channel compensation time");
printStatIndent2(&gNB->ulsch_mrc_stats,"ULSCH mrc computation");
@@ -1055,17 +1128,17 @@ int main(int argc, char **argv)
printStatIndent2(&gNB->ulsch_ldpc_decoding_stats,"ULSCH ldpc decoding");
printf("\n");
}
-
+
if(n_trials==1)
break;
-
+
if ((float)n_errors[0]/(float)n_trials <= target_error_rate) {
printf("*************\n");
printf("PUSCH test OK\n");
printf("*************\n");
break;
}
-
+
snrRun++;
n_errs = n_errors[0];
} // SNR loop
diff --git a/openair1/SIMULATION/TOOLS/phase_noise.c b/openair1/SIMULATION/TOOLS/phase_noise.c
new file mode 100644
index 0000000000..f243a09c59
--- /dev/null
+++ b/openair1/SIMULATION/TOOLS/phase_noise.c
@@ -0,0 +1,42 @@
+/*
+ * 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
+ */
+
+#include
+#include
+#include
+#include
+#include "sim.h"
+
+
+/* linear phase noise model */
+void phase_noise(double ts, int16_t * InRe, int16_t * InIm)
+{
+ double fd = 300;//0.01*30000
+ static double i=0;
+ double real, imag,x ,y;
+ i++;
+ real = cos(fd * 2 * M_PI * i * ts);
+ imag = sin (fd * 2 * M_PI * i * ts);
+ x = ((real * (double)InRe[0]) - (imag * (double)InIm[0])) ;
+ y= ((real * (double)InIm[0]) + (imag * (double)InRe[0])) ;
+ InRe[0]= (int16_t)(x);
+ InIm[0]= (int16_t)(y);
+}
diff --git a/openair1/SIMULATION/TOOLS/sim.h b/openair1/SIMULATION/TOOLS/sim.h
index 2f5ab99b41..d2684b15c1 100644
--- a/openair1/SIMULATION/TOOLS/sim.h
+++ b/openair1/SIMULATION/TOOLS/sim.h
@@ -460,6 +460,14 @@ void init_channelmod(void) ;
double N_RB2sampling_rate(uint16_t N_RB);
double N_RB2channel_bandwidth(uint16_t N_RB);
+/* Linear phase noise model */
+/*!
+ \brief This function produce phase noise and add to input signal
+ \param ts Sampling time
+ \param *Re *Im Real and Imag part of the signal
+*/
+void phase_noise(double ts, int16_t * InRe, int16_t * InIm);
+
#include "targets/RT/USER/rfsim.h"
void do_DL_sig(sim_t *sim,
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
index 8220d088d0..bc105b9080 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
@@ -1940,9 +1940,9 @@ uint8_t get_K_ptrs(uint16_t nrb0, uint16_t nrb1, uint16_t N_RB) {
LOG_I(PHY,"PUSH PT-RS is not present.\n");
return -1;
} else if (N_RB >= nrb0 && N_RB < nrb1)
- return 0;
+ return 2;
else
- return 1;
+ return 4;
}
uint16_t nr_dci_size(NR_ServingCellConfigCommon_t *scc,