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/NOTICE.md b/NOTICE.md index 96b5d4c552..39dd33795d 100644 --- a/NOTICE.md +++ b/NOTICE.md @@ -21,3 +21,7 @@ The Regents of the University of California: BSD 3-Clause Licence. Niels Provos : BSD 2-Clause Licence. +## Credits for source code openair3/GTPV1-U/nw-gtpv1u: ## + +Amit Chawre : BSD 2-Clause Licence. + diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index c3b997a4e8..7e9e3800db 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -30,7 +30,6 @@ def sendSocialMediaMessage(pipeChannel, pipeColor, pipeMessage) { } } -def doRedHatBuild = false def doFlexranCtrlTest = false // Location of the executor node @@ -85,21 +84,6 @@ pipeline { echo "Platform is ${env.TESTPLATFORM_OWNER}" } - if (params.RedHatRemoteServer == null) { - allParametersPresent = false - } - if (params.RedHatRemoteCredentials == null) { - allParametersPresent = false - } - if (params.RedHatWorkingPath == null) { - allParametersPresent = false - } - if (allParametersPresent) { - echo "Performing Red Hat Build" - doRedHatBuild = true - } else { - doRedHatBuild = false - } if (params.FlexRanRtcGitLabRepository_Credentials != null) { doFlexranCtrlTest = true } @@ -279,7 +263,7 @@ pipeline { steps { gitlabCommitStatus(name: "Build eNB-USRP") { timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant enb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" + sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant enb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID}" } } } @@ -311,28 +295,6 @@ pipeline { } } } - stage ("Build eNB-USRP on Red Hat") { - when { - expression {doRedHatBuild} - } - steps { - gitlabCommitStatus(name: "Build eNB-USRP-RHE") { - script { - try { - withCredentials([ - [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.RedHatRemoteCredentials}", usernameVariable: 'RH_Username', passwordVariable: 'RH_Password'] - ]) { - timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/buildOnRH.sh --workspace $WORKSPACE --job-name ${JOB_NAME} --build-id ${BUILD_ID} --remote-host ${params.RedHatRemoteServer} --remote-path ${params.RedHatWorkingPath} --remote-user-name ${RH_Username} --remote-password ${RH_Password}" - } - } - } catch (Exception e) { - echo "Red Hat build failed but we could keep running pipeline if all ubuntu-based build passed" - } - } - } - } - } } post { failure { 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/checkCodingFormattingRules.sh b/ci-scripts/checkCodingFormattingRules.sh index fb159d4da0..d47b90a9dd 100755 --- a/ci-scripts/checkCodingFormattingRules.sh +++ b/ci-scripts/checkCodingFormattingRules.sh @@ -77,7 +77,7 @@ then IS_NFAPI=`echo $FILE | egrep -c "nfapi/open-nFAPI|nfapi/oai_integration/vendor_ext"` IS_OAI_LICENCE_PRESENT=`egrep -c "OAI Public License" $FILE` IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence" $FILE` - IS_EXCEPTION=`echo $FILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|common/utils/itti_analyzer/common/queue.h|openair3/UTILS/tree.h|openair3/UTILS/queue.h"` + IS_EXCEPTION=`echo $FILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|common/utils/itti_analyzer/common/queue.h|openair3/UTILS/tree.h|openair3/UTILS/queue.h|openair3/GTPV1-U/nw-gtpv1u|openair2/UTIL/OPT/ws_"` if [ $IS_OAI_LICENCE_PRESENT -eq 0 ] && [ $IS_BSD_LICENCE_PRESENT -eq 0 ] then if [ $IS_NFAPI -eq 0 ] && [ $IS_EXCEPTION -eq 0 ] @@ -194,12 +194,12 @@ do IS_NFAPI=`echo $FULLFILE | egrep -c "nfapi/open-nFAPI|nfapi/oai_integration/vendor_ext"` IS_OAI_LICENCE_PRESENT=`egrep -c "OAI Public License" $FULLFILE` IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence" $FULLFILE` - IS_EXCEPTION=`echo $FILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|common/utils/itti_analyzer/common/queue.h|openair3/UTILS/tree.h|openair3/UTILS/queue.h"` + IS_EXCEPTION=`echo $FULLFILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|common/utils/itti_analyzer/common/queue.h|openair3/UTILS/tree.h|openair3/UTILS/queue.h|openair3/GTPV1-U/nw-gtpv1u|openair2/UTIL/OPT/ws_"` if [ $IS_OAI_LICENCE_PRESENT -eq 0 ] && [ $IS_BSD_LICENCE_PRESENT -eq 0 ] then if [ $IS_NFAPI -eq 0 ] && [ $IS_EXCEPTION -eq 0 ] then - echo $FILE >> ./files-w-suspect-banner.txt + echo $FULLFILE >> ./files-w-suspect-banner.txt fi fi fi 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/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf index d92804ae44..36e93ba14e 100644 --- a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf @@ -71,6 +71,12 @@ gNBs = initialDLBWPmappingType_2 = 0; #this is SS=1,L=12 initialDLBWPstartSymbolAndLength_2 = 54; + + initialDLBWPk0_3 = 0; + initialDLBWPmappingType_3 = 0; + #this is SS=1,L=4 + initialDLBWPstartSymbolAndLength_3 = 57; + #uplinkConfigCommon #frequencyInfoUL ul_frequencyBand = 78; @@ -105,8 +111,8 @@ gNBs = #1,2,4,8,10,20,40,80 ra_ResponseWindow = 4; #ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR -#0=oneeighth,1=onefourth,2=half,3=one,4=two,5=four,6=eight,7=sixteen - ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3; +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; #oneHalf (0..15) 4,8,12,16,...60,64 ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; #ra_ContentionResolutionTimer @@ -114,8 +120,8 @@ gNBs = ra_ContentionResolutionTimer = 7; rsrp_ThresholdSSB = 19; #prach-RootSequenceIndex_PR -#0 = 839, 1 = 139 - prach_RootSequenceIndex_PR = 1; +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; prach_RootSequenceIndex = 1; # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex # @@ -135,7 +141,11 @@ gNBs = # this is SS=0 L=12 initialULBWPstartSymbolAndLength_1 = 69; - + initialULBWPk2_2 = 7; + initialULBWPmappingType_2 = 1; + # this is SS=10 L=4 + initialULBWPstartSymbolAndLength_2 = 52; + msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; @@ -235,8 +245,10 @@ RUs = ( att_rx = 0; bands = [7]; max_pdschReferenceSignalPower = -27; - max_rxgain = 114; + max_rxgain = 75; eNB_instances = [0]; + #beamforming 1x4 matrix: + bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2"; clock_src = "external"; } 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/cppcheck_suppressions.list b/ci-scripts/cppcheck_suppressions.list index 727fd22e74..4b9fb97427 100644 --- a/ci-scripts/cppcheck_suppressions.list +++ b/ci-scripts/cppcheck_suppressions.list @@ -83,6 +83,10 @@ nullPointer:common/utils/T/tracer/multi.c:265 // the tests arrayIndexOutOfBounds:openair2/LAYER2/rlc_v2/tests/test.c:401 // +//----------------------------------------------------------------------------- +// cppcheck does not understand the different lengths of arrays +arrayIndexOutOfBounds:openair1/SIMULATION/TOOLS/random_channel.c:705 +arrayIndexOutOfBounds:openair1/SIMULATION/TOOLS/random_channel.c:706 //***************************************************************************** // // True problems we don't know how to fix, Suppression is commented out, 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/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index b9b9a2bafa..e6b93b5b4d 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -2027,30 +2027,6 @@ function run_test_on_vm { done - full_l2_sim_destroy - - echo "############################################################" - echo "Checking run status" - echo "############################################################" - - if [ $PING_STATUS -ne 0 ]; then STATUS=-1; fi - if [ $IPERF_STATUS -ne 0 ]; then STATUS=-1; fi - if [ $MBMS_STATUS -eq 0 ] - then - echo "LTE MBMS RFSIM seems OK" - else - echo "LTE MBMS RFSIM seems to FAIL" - STATUS=-1 - fi - if [ $STATUS -eq 0 ] - then - echo "LTE RFSIM seems OK" - echo "LTE: TEST_OK" > $ARCHIVES_LOC/test_final_status.log - else - echo "LTE RFSIM seems to FAIL" - echo "LTE: TEST_KO" > $ARCHIVES_LOC/test_final_status.log - fi - #################### ## FeMBMS CASE noS1 ## #################### @@ -2123,6 +2099,13 @@ function run_test_on_vm { if [ $PING_STATUS -ne 0 ]; then STATUS=-1; fi if [ $IPERF_STATUS -ne 0 ]; then STATUS=-1; fi + if [ $MBMS_STATUS -eq 0 ] + then + echo "LTE MBMS RFSIM seems OK" + else + echo "LTE MBMS RFSIM seems to FAIL" + STATUS=-1 + fi if [ $FeMBMS_STATUS -eq 0 ] then echo "LTE FeMBMS RFSIM seems OK" @@ -2153,7 +2136,7 @@ function run_test_on_vm { NR_STATUS=0 ######### start of loop - while [ $try_cnt -lt 1 ] + while [ $try_cnt -lt 4 ] do SYNC_STATUS=0 PING_STATUS=0 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/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml b/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml index c51093c178..a344cb6a7f 100644 --- a/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml +++ b/ci-scripts/xml_files/gnb_nr_ue_usrp_run.xml @@ -52,7 +52,7 @@ Initialize_OAI_UE Initialize NR UE USRP - --phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --threadoffset 16 --rrc_config_path . + --phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --ue-rxgain 75 --threadoffset 16 --rrc_config_path . NR diff --git a/ci-scripts/xml_files/gnb_nr_ue_usrp_run_multi_thread.xml b/ci-scripts/xml_files/gnb_nr_ue_usrp_run_multi_thread.xml index b4290ae6a3..9e5e0a2bac 100644 --- a/ci-scripts/xml_files/gnb_nr_ue_usrp_run_multi_thread.xml +++ b/ci-scripts/xml_files/gnb_nr_ue_usrp_run_multi_thread.xml @@ -52,7 +52,7 @@ Initialize_OAI_UE Initialize NR UE USRP - --phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --threadoffset 16 --rrc_config_path . + --phy-test --usrp-args "addr=192.168.30.2,second_addr=192.168.50.2,clock_source=external,time_source=external" --ue-rxgain 75 --threadoffset 16 --rrc_config_path . NR diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index e76dafbe73..17d2cf8e8a 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -763,6 +763,42 @@ set(HWLIB_TCP_BRIDGE_OAI_SOURCE add_library(tcp_bridge_oai MODULE ${HWLIB_TCP_BRIDGE_OAI_SOURCE} ) set_target_properties(tcp_bridge_oai PROPERTIES COMPILE_FLAGS "-fvisibility=hidden") +# Benetel 4G library +###################################################################### + +set(HWLIB_BENETEL_4G_SOURCE + ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/4g/benetel.c + ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/4g/shared_buffers.c + ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/4g/low.c + ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/4g/low_dpdk.c + ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/4g/dpdk_driver.c + ) +add_library(benetel_4g MODULE ${HWLIB_BENETEL_4G_SOURCE} ) + +set_target_properties(benetel_4g PROPERTIES COMPILE_FLAGS "-fvisibility=hidden -march=native -I$ENV{RTE_SDK}/$ENV{RTE_TARGET}/include") + +SET(DPDK_LIBS "-Wl,-rpath,$ENV{RTE_SDK}/$ENV{RTE_TARGET}/lib -Wl,--whole-archive -L$ENV{RTE_SDK}/$ENV{RTE_TARGET}/lib -ldpdk -Wl,--no-whole-archive") +TARGET_LINK_LIBRARIES(benetel_4g ${DPDK_LIBS}) +TARGET_LINK_LIBRARIES(benetel_4g pthread dl rt m numa) + +# Benetel 5G library +###################################################################### + +set(HWLIB_BENETEL_5G_SOURCE + ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/5g/benetel.c + ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/5g/shared_buffers.c + ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/5g/low.c + ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/5g/low_dpdk.c + ${OPENAIR_TARGETS}/ARCH/ETHERNET/benetel/5g/dpdk_driver.c + ) +add_library(benetel_5g MODULE ${HWLIB_BENETEL_5G_SOURCE} ) + +set_target_properties(benetel_5g PROPERTIES COMPILE_FLAGS "-fvisibility=hidden -march=native -I$ENV{RTE_SDK}/$ENV{RTE_TARGET}/include") + +SET(DPDK_LIBS "-Wl,-rpath,$ENV{RTE_SDK}/$ENV{RTE_TARGET}/lib -Wl,--whole-archive -L$ENV{RTE_SDK}/$ENV{RTE_TARGET}/lib -ldpdk -Wl,--no-whole-archive") +TARGET_LINK_LIBRARIES(benetel_5g ${DPDK_LIBS}) +TARGET_LINK_LIBRARIES(benetel_5g pthread dl rt m numa) + ########################################################## include_directories ("${OPENAIR_TARGETS}/ARCH/COMMON") @@ -2342,6 +2378,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 @@ -3133,7 +3170,7 @@ if (${T_TRACER}) SECU_OSA SECU_CN SCHED_LIB SCHED_NR_LIB SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB default_sched remote_sched RAL NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_VNF_LIB NFAPI_USER_LIB PHY_COMMON PHY PHY_UE PHY_NR PHY_NR_COMMON PHY_NR_UE PHY_RU PHY_MEX - L2 L2_LTE L2_NR L2_UE NR_L2_UE MAC_NR_COMMON MAC_NR MAC_UE_NR + L2 L2_LTE L2_NR L2_LTE_NR L2_UE NR_L2_UE MAC_NR_COMMON MAC_NR MAC_UE_NR CN_UTILS GTPV1U NR_GTPV1U SCTP_CLIENT MME_APP UDP LIB_NAS_UE NB_IoT LFDS LFDS7 SIMU_COMMON SIMU SIMU_ETH OPENAIR0_LIB ldpc_orig ldpc_optim ldpc_optim8seg ldpc PROTO_AGENT dfts) if (TARGET ${i}) 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/common/utils/T/defs.h b/common/utils/T/defs.h index 69b379ce0b..a194e621db 100644 --- a/common/utils/T/defs.h +++ b/common/utils/T/defs.h @@ -1,5 +1,5 @@ -#ifndef _TRACER_DEFS_H_ -#define _TRACER_DEFS_H_ +#ifndef _COMMON_UTILS_T_DEFS_H_ +#define _COMMON_UTILS_T_DEFS_H_ /* types of plots */ #define PLOT_VS_TIME 0 @@ -27,4 +27,4 @@ void *forwarder(char *ip, int port); void forward(void *forwarder, char *buf, int size); void forward_start_client(void *forwarder, int socket); -#endif /* _TRACER_DEFS_H_ */ +#endif /* _COMMON_UTILS_T_DEFS_H_ */ diff --git a/common/utils/T/tracer/defs.h b/common/utils/T/tracer/defs.h index 443fabdde8..394351eab0 100644 --- a/common/utils/T/tracer/defs.h +++ b/common/utils/T/tracer/defs.h @@ -1,5 +1,5 @@ -#ifndef _TRACER_DEFS_H_ -#define _TRACER_DEFS_H_ +#ifndef _COMMON_UTILS_T_TRACER_DEFS_H_ +#define _COMMON_UTILS_T_TRACER_DEFS_H_ /* types of plots */ #define PLOT_VS_TIME 0 @@ -21,4 +21,4 @@ void t_gui_start(void); void t_gui_set_input_signal(int eNB, int frame, int subframe, int antenna, int size, void *buf); -#endif /* _TRACER_DEFS_H_ */ +#endif /* _COMMON_UTILS_T_TRACER_DEFS_H_ */ diff --git a/doc/BUILD.md b/doc/BUILD.md index 97f9047596..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). @@ -33,7 +34,7 @@ The main oai binaries, which are tested by the Continuous Integration process ar Running the [build_oai](../cmake_targets/build_oai) script also generates some utilities required to build and/or run the oai softmodem binaries: -- `con2uedata`: a binary used to build the UE data from a configuration file. The created file emulates the sim card of a 3GPP compliant phone. +- `conf2uedata`: a binary used to build the UE data from a configuration file. The created file emulates the sim card of a 3GPP compliant phone. - `nvram`: a binary used to build UE (IMEI...) and EMM (IMSI, registered PLMN) non volatile data. - `rb_tool`: radio bearer utility - `genids` T Tracer utility, used at build time to generate T_IDs.h include file. This binary is located in the [T Tracer source file directory](../common/utils/T) . 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 + +![image info](./testbenches_doc_resources/legacy1.jpg) + +## Legacy 2 Bench + +**Purpose** : TDD Band 40, TM2 2xTX 2xRX +**Note** : CN can run in a container, could also run on Massive + +![image info](./testbenches_doc_resources/legacy2.jpg) + +## Next Bench for DEV + +**Note** : Benetel CI can also run on this bench at night + +![image info](./testbenches_doc_resources/next_dev.jpg) + + +## Next Bench for CI + +**Note** : The current test running on Caracal could run on this bench with a N300/N300 setup + +![image info](./testbenches_doc_resources/next_ci.jpg) + +## Indoor Live Network Bench + +![image info](./testbenches_doc_resources/indoor_live.jpg) + +## Outdoor Live Network Bench + +![image info](./testbenches_doc_resources/outdoor_live.jpg) diff --git a/doc/TESTING_GNB_W_COTS_UE.md b/doc/TESTING_GNB_W_COTS_UE.md index a16b4dbe13..17f37ad2d7 100644 --- a/doc/TESTING_GNB_W_COTS_UE.md +++ b/doc/TESTING_GNB_W_COTS_UE.md @@ -1,4 +1,4 @@ -STATUS 2020/07/30 : under continuous improvement ; updated the configuration files links with CI approved reference files +STATUS 2020/09/10 : updated the status of interop (end to end UL/DL traffic) ## Table of Contents ## @@ -12,6 +12,7 @@ STATUS 2020/07/30 : under continuous improvement ; updated the configuration fil 7. [Log file monitoring](#log-file-monitoring) 6. [Required tools for debug](#required-tools-for-debug) 7. [Status of interoperability](#status-of-interoperability) +8. [CI integration](#ci-integration) ## Configuration Overview @@ -70,7 +71,7 @@ cd cmake_targets/ - **EPC** for reference: -https://github.com/OPENAIRINTERFACE/openair-epc-fed/blob/master-documentation/docs/DEPLOY_HOME.md +https://github.com/OPENAIRINTERFACE/openair-epc-fed/blob/master/docs/DEPLOY_HOME.md @@ -194,7 +195,7 @@ The order to run the different components is important: 1- first, CN 2- then, eNB 3- then, gNB -4- finally, switch UE from airplane mode OFF to ON +4- finally, switch UE from airplane mode ON to OFF (ie Radio from OFF to ON) It is recommended to redirect the run commands to the same log file (fur further analysis and debug), using ```| tee **YOUR_LOG_FILE**``` especially for eNB and gNB. It is not very useful for the CN. @@ -204,7 +205,7 @@ The test takes typically a few seconds, max 10-15 seconds. If it takes more than - **EPC** (on EPC host): for reference: -https://github.com/OPENAIRINTERFACE/openair-epc-fed/blob/master-documentation/docs/DEPLOY_HOME.md +https://github.com/OPENAIRINTERFACE/openair-epc-fed/blob/master/docs/DEPLOY_HOME.md @@ -220,17 +221,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 @@ -377,13 +377,24 @@ The following parts have been validated with FR1 COTS UE: PDCCH DCI format 1_1 and correponding PDSCH are decoded correctlyby the phone ACK/NACK (PUCCH format 0) are successfully received at gNB -- On going: - validation of HARQ procedures - Integration with higher layers to replace dummy data with real traffic +- **End-to end UL / DL traffic with HARQ procedures validated (ping, iperf)** -- Known limitations as of May 2020: - only dummy DL traffic - no UL traffic - no end-to-end traffic possible +- Known limitations as of September 2020: + DL traffic : 3Mbps + UL traffic : 1Mbps + some packet losses might still occur even in ideal channel conditions +## CI integration +The automation scripts are available on ILIADE. +The end-to-end test is integrated in the CI flow in a semi-automated manner, comprising 3 steps: +- update a YAML file comprising the IT resources definition, branch and commit number the test has to run on +- run the python script that generates the test from the YAML file +``` +python3 obj_build_from_yaml.py py_params_template.yaml fr1.sh +``` +- run the test (fr1.sh) + +At the date of writing, the test comprises the deployment of the components (epc, eNB, gNB, cots ue) and the execution of 2 pings procedures (20 pings in 20sec, then 5 pings in 1sec) + +This automation is run for every integration branch to be merged into develop. 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/executables/main-fs6.c b/executables/main-fs6.c index d2d64d0959..c4a0d85b34 100644 --- a/executables/main-fs6.c +++ b/executables/main-fs6.c @@ -917,7 +917,7 @@ void phy_procedures_eNB_TX_fromsplit(uint8_t *bufferZone, int nbBlocks, PHY_VARS if (NFAPI_MODE==NFAPI_MONOLITHIC || NFAPI_MODE==NFAPI_MODE_PNF) { if (is_pmch_subframe(frame,subframe,fp)) { - pmch_procedures(eNB,proc); + pmch_procedures(eNB,proc,0); } else { // this is not a pmch subframe, so generate PSS/SSS/PBCH common_signal_procedures(eNB,frame, subframe); diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 969ad21b8e..a0f5710128 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -180,6 +180,17 @@ int attach_rru(RU_t *ru) ((RRU_config_t *)&rru_config_msg.msg[0])->prach_ConfigIndex[0]); AssertFatal((ru->ifdevice.trx_ctlsend_func(&ru->ifdevice,&rru_config_msg,rru_config_msg.len)!=-1), "RU %d failed send configuration to remote radio\n",ru->idx); + + if ((len = ru->ifdevice.trx_ctlrecv_func(&ru->ifdevice, + &rru_config_msg, + msg_len))<0) { + LOG_I(PHY,"Waiting for RRU %d\n",ru->idx); + } else if (rru_config_msg.type == RRU_config_ok) { + LOG_I(PHY, "RRU_config_ok received\n"); + } else { + LOG_E(PHY,"Received incorrect message %d from RRU %d\n",rru_config_msg.type,ru->idx); + } + return 0; } @@ -1442,6 +1453,8 @@ void *ru_thread( void *param ) { LOG_I(PHY,"Starting RU %d (%s,%s),\n",ru->idx,NB_functions[ru->function],NB_timing[ru->if_timing]); + memcpy((void*)&ru->config,(void*)&RC.gNB[0]->gNB_config,sizeof(ru->config)); + if(emulate_rf) { fill_rf_config(ru,ru->rf_config_file); nr_init_frame_parms(&ru->config, fp); @@ -1464,8 +1477,6 @@ void *ru_thread( void *param ) { AssertFatal(ret==0,"Cannot connect to remote radio\n"); } - memcpy((void*)&ru->config,(void*)&RC.gNB[0]->gNB_config,sizeof(ru->config)); - if (ru->if_south == LOCAL_RF) { // configure RF parameters only nr_init_frame_parms(&ru->config, fp); nr_dump_frame_parms(fp); @@ -1571,7 +1582,8 @@ void *ru_thread( void *param ) { if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) { //if (proc->tti_rx==8) { - if (ru->feprx) ru->feprx(ru,proc->tti_rx); + if (ru->feprx) { + ru->feprx(ru,proc->tti_rx); //LOG_M("rxdata.m","rxs",ru->common.rxdata[0],1228800,1,1); LOG_D(PHY,"RU proc: frame_rx = %d, tti_rx = %d\n", proc->frame_rx, proc->tti_rx); @@ -1591,6 +1603,7 @@ void *ru_thread( void *param ) { proc->frame_rx,proc->tti_rx); free_nr_ru_prach_entry(ru,prach_id); } + } } // At this point, all information for subframe has been received on FH interface @@ -2131,26 +2144,29 @@ void set_function_spec_param(RU_t *ru) { ru->fh_north_out = NULL; // no outgoing fronthaul to north ru->nr_start_if = NULL; // no if interface ru->rfdevice.host_type = RAU_HOST; + + // FK this here looks messed up. The following lines should be part of the if (ru->function == gNodeB_3GPP), shouldn't they? + + ru->fh_south_in = rx_rf; // local synchronous RF RX + ru->fh_south_out = tx_rf; // local synchronous RF TX + ru->start_rf = start_rf; // need to start the local RF interface + ru->stop_rf = stop_rf; + ru->start_write_thread = start_write_thread; // starting RF TX in different thread + printf("configuring ru_id %u (start_rf %p)\n", ru->idx, start_rf); } - ru->fh_south_in = rx_rf; // local synchronous RF RX - ru->fh_south_out = tx_rf; // local synchronous RF TX - ru->start_rf = start_rf; // need to start the local RF interface - ru->stop_rf = stop_rf; - ru->start_write_thread = start_write_thread; // starting RF TX in different thread - printf("configuring ru_id %u (start_rf %p)\n", ru->idx, start_rf); /* - if (ru->function == gNodeB_3GPP) { // configure RF parameters only for 3GPP eNodeB, we need to get them from RAU otherwise - fill_rf_config(ru,rf_config_file); - init_frame_parms(&ru->frame_parms,1); - nr_phy_init_RU(ru); - } + printf("configuring ru_id %u (start_rf %p)\n", ru->idx, start_rf); + fill_rf_config(ru,rf_config_file); + init_frame_parms(&ru->frame_parms,1); + nr_phy_init_RU(ru); - ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); - if (setup_RU_buffers(ru)!=0) { - printf("Exiting, cannot initialize RU Buffers\n"); - exit(-1); - }*/ + ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg); + if (setup_RU_buffers(ru)!=0) { + printf("Exiting, cannot initialize RU Buffers\n"); + exit(-1); + } + */ break; case REMOTE_IF5: // the remote unit is IF5 RRU @@ -2203,6 +2219,15 @@ void set_function_spec_param(RU_t *ru) { exit(-1); } + if (ru->ifdevice.get_internal_parameter != NULL) { + void *t = ru->ifdevice.get_internal_parameter("fh_if4p5_south_in"); + if (t != NULL) + ru->fh_south_in = t; + t = ru->ifdevice.get_internal_parameter("fh_if4p5_south_out"); + if (t != NULL) + ru->fh_south_out = t; + } + malloc_IF4p5_buffer(ru); break; diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 9493ba11cf..1600d8add0 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -471,21 +471,22 @@ void UE_processing(void *arg) { UE_nr_rxtx_proc_t *proc = &rxtxD->proc; PHY_VARS_NR_UE *UE = rxtxD->UE; - uint8_t gNB_id = 0; - - // params for UL time alignment procedure - NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &UE->ul_time_alignment[gNB_id]; - uint8_t numerology = UE->frame_parms.numerology_index; - uint16_t bwp_ul_NB_RB = UE->frame_parms.N_RB_UL; - int slot_tx = proc->nr_tti_tx; - int frame_tx = proc->frame_tx; + processSlotRX(UE, proc); + processSlotTX(UE, proc); /* UL time alignment // If the current tx frame and slot match the TA configuration in ul_time_alignment // then timing advance is processed and set to be applied in the next UL transmission */ if (UE->mac_enabled == 1) { + uint8_t gNB_id = 0; + NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &UE->ul_time_alignment[gNB_id]; + int slot_tx = proc->nr_tti_tx; + int frame_tx = proc->frame_tx; if (frame_tx == ul_time_alignment->ta_frame && slot_tx == ul_time_alignment->ta_slot) { + uint8_t numerology = UE->frame_parms.numerology_index; + uint16_t bwp_ul_NB_RB = UE->frame_parms.N_RB_UL; + LOG_D(PHY,"Applying timing advance -- frame %d -- slot %d\n", frame_tx, slot_tx); //if (nfapi_mode!=3){ @@ -495,9 +496,6 @@ void UE_processing(void *arg) { //} } } - - processSlotRX(UE, proc); - processSlotTX(UE, proc); } void dummyWrite(PHY_VARS_NR_UE *UE,openair0_timestamp timestamp, int writeBlockSize) { @@ -622,6 +620,7 @@ void *UE_thread(void *arg) { notifiedFIFO_t freeBlocks; initNotifiedFIFO_nothreadSafe(&freeBlocks); NR_UE_MAC_INST_t *mac = get_mac_inst(0); + int timing_advance = UE->timing_advance; for (int i=0; iframe_parms.nb_antennas_tx; i++) txp[i] = (void *)&UE->common_vars.txdata[i][UE->frame_parms.get_samples_slot_timestamp( - ((curMsg->proc.nr_tti_rx + DURATION_RX_TO_TX -2)%nb_slot_frame),&UE->frame_parms,0)]; + ((slot_nr + DURATION_RX_TO_TX - RX_NB_TH)%nb_slot_frame),&UE->frame_parms,0)]; int readBlockSize, writeBlockSize; if (slot_nr<(nb_slot_frame - 1)) { readBlockSize=get_readBlockSize(slot_nr, &UE->frame_parms); - writeBlockSize=UE->frame_parms.get_samples_per_slot(curMsg->proc.nr_tti_tx,&UE->frame_parms); + writeBlockSize=UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX - RX_NB_TH) % nb_slot_frame, &UE->frame_parms); } else { UE->rx_offset_diff = computeSamplesShift(UE); readBlockSize=get_readBlockSize(slot_nr, &UE->frame_parms) - UE->rx_offset_diff; - writeBlockSize=UE->frame_parms.get_samples_per_slot(curMsg->proc.nr_tti_tx,&UE->frame_parms) - + writeBlockSize=UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX - RX_NB_TH) % nb_slot_frame, &UE->frame_parms)- UE->rx_offset_diff; } + if (UE->timing_advance != timing_advance) { + writeBlockSize -= UE->timing_advance - timing_advance; + timing_advance = UE->timing_advance; + } + AssertFatal(readBlockSize == UE->rfdevice.trx_read_func(&UE->rfdevice, ×tamp, @@ -748,29 +752,19 @@ void *UE_thread(void *arg) { readBlockSize, UE->frame_parms.nb_antennas_rx),""); - AssertFatal( writeBlockSize == - UE->rfdevice.trx_write_func(&UE->rfdevice, - timestamp+ - UE->frame_parms.get_samples_slot_timestamp(slot_nr, - &UE->frame_parms,DURATION_RX_TO_TX -2) - firstSymSamp - - openair0_cfg[0].tx_sample_advance, - txp, - writeBlockSize, - UE->frame_parms.nb_antennas_tx, - 1),""); - if( slot_nr==(nb_slot_frame-1)) { // read in first symbol of next frame and adjust for timing drift int first_symbols=UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0; // first symbol of every frames - if ( first_symbols > 0 ) + if ( first_symbols > 0 ) { + openair0_timestamp ignore_timestamp; AssertFatal(first_symbols == UE->rfdevice.trx_read_func(&UE->rfdevice, - ×tamp, + &ignore_timestamp, (void **)UE->common_vars.rxdata, first_symbols, UE->frame_parms.nb_antennas_rx),""); - else + } else LOG_E(PHY,"can't compensate: diff =%d\n", first_symbols); } @@ -781,18 +775,15 @@ void *UE_thread(void *arg) { notifiedFIFO_elt_t *res; while (nbSlotProcessing >= RX_NB_TH) { - if ( (res=tryPullTpool(&nf, Tpool)) != NULL ) { - nbSlotProcessing--; - processingData_t *tmp=(processingData_t *)res->msgData; + res=pullTpool(&nf, Tpool); + nbSlotProcessing--; + processingData_t *tmp=(processingData_t *)res->msgData; - if (tmp->proc.decoded_frame_rx != -1) - decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx); - //decoded_frame_rx=tmp->proc.decoded_frame_rx; + if (tmp->proc.decoded_frame_rx != -1) + decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx); + //decoded_frame_rx=tmp->proc.decoded_frame_rx; - pushNotifiedFIFO_nothreadSafe(&freeBlocks,res); - } - - usleep(200); + pushNotifiedFIFO_nothreadSafe(&freeBlocks,res); } if ( (decoded_frame_rx != curMsg->proc.frame_rx) && @@ -801,6 +792,20 @@ void *UE_thread(void *arg) { LOG_E(PHY,"Decoded frame index (%d) is not compatible with current context (%d), UE should go back to synch mode\n", decoded_frame_rx, curMsg->proc.frame_rx ); + AssertFatal( writeBlockSize == + UE->rfdevice.trx_write_func(&UE->rfdevice, + timestamp+ + UE->frame_parms.get_samples_slot_timestamp(slot_nr, + &UE->frame_parms,DURATION_RX_TO_TX - RX_NB_TH) - firstSymSamp - + openair0_cfg[0].tx_sample_advance - UE->N_TA_offset - UE->timing_advance, + txp, + writeBlockSize, + UE->frame_parms.nb_antennas_tx, + 1),""); + + for (int i=0; iframe_parms.nb_antennas_tx; i++) + memset(txp[i], 0, writeBlockSize); + nbSlotProcessing++; msgToPush->key=slot_nr; pushTpool(Tpool, msgToPush); diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 2781f94bda..e6d644453c 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -687,11 +687,12 @@ int main( int argc, char **argv ) { nr_init_frame_parms_ue(frame_parms[CC_id],nrUE_config,NORMAL); // Overwrite DL frequency (for FR2 testing) - if (downlink_frequency[0][0]!=0) + if (downlink_frequency[0][0]!=0) { frame_parms[CC_id]->dl_CarrierFreq = downlink_frequency[0][0]; - - init_symbol_rotation(frame_parms[CC_id],frame_parms[CC_id]->dl_CarrierFreq); + frame_parms[CC_id]->ul_CarrierFreq = downlink_frequency[0][0]; + } + init_symbol_rotation(frame_parms[CC_id],frame_parms[CC_id]->dl_CarrierFreq); init_nr_ue_vars(UE[CC_id],frame_parms[CC_id],0,abstraction_flag); UE[CC_id]->mac_enabled = 1; @@ -768,13 +769,7 @@ int main( int argc, char **argv ) { for(int CC_id=0; CC_idrf_map.card=0; PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+chain_offset; -#if defined(OAI_USRP) || defined(OAI_ADRV9371_ZC706) - PHY_vars_UE_g[0][CC_id]->hw_timing_advance = timing_advance; PHY_vars_UE_g[0][CC_id]->timing_advance = timing_advance; -#else - PHY_vars_UE_g[0][CC_id]->hw_timing_advance = 160; -#endif - } init_NR_UE_threads(1); diff --git a/executables/stats.h b/executables/stats.h index 6c847a2860..9bd4c6f080 100644 --- a/executables/stats.h +++ b/executables/stats.h @@ -21,8 +21,8 @@ /* Header file generated by fdesign on Thu Aug 28 12:13:51 2014 */ -#ifndef FD_stats_form_h_ -#define FD_stats_form_h_ +#ifndef _EXECUTABLES_STATS_H_ +#define _EXECUTABLES_STATS_H_ #include @@ -43,4 +43,4 @@ typedef struct { extern FD_stats_form *create_form_stats_form( void ); -#endif /* FD_stats_form_h_ */ +#endif /* _EXECUTABLES_STATS_H_ */ diff --git a/executables/threads_t.h b/executables/threads_t.h index 0671f40988..c4b233ccc9 100644 --- a/executables/threads_t.h +++ b/executables/threads_t.h @@ -1,5 +1,5 @@ -#ifndef _THREADS_T_H_ -#define _THREADS_T_H_ +#ifndef _EXECUTABLES_THREADS_T_H_ +#define _EXECUTABLES_THREADS_T_H_ typedef struct threads_s { int main; @@ -18,4 +18,4 @@ typedef struct threads_s { //int dlsch_td1_three; } threads_t; -#endif /* _THREADS_T_H_ */ +#endif /* _EXECUTABLES_THREADS_T_H_ */ diff --git a/openair1/PHY/CODING/nr_rate_matching.c b/openair1/PHY/CODING/nr_rate_matching.c index f315365127..a16a8d100f 100644 --- a/openair1/PHY/CODING/nr_rate_matching.c +++ b/openair1/PHY/CODING/nr_rate_matching.c @@ -236,13 +236,12 @@ void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e,uint8_t *f) } */ - int j2=0; fp=f; switch (Qm) { case 2: e0=e; e1=e0+EQm; - for (int j = 0; j< EQm; j++,j2+=2){ + for (int j = 0, j2 = 0; j< EQm; j++,j2+=2){ fp=&f[j2]; fp[0] = e0[j]; fp[1] = e1[j]; @@ -253,7 +252,7 @@ void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e,uint8_t *f) e1=e0+EQm; e2=e1+EQm; e3=e2+EQm; - for (int j = 0; j< EQm; j++,j2+=4){ + for (int j = 0, j2 = 0; j< EQm; j++,j2+=4){ fp=&f[j2]; fp[0] = e0[j]; fp[1] = e1[j]; @@ -287,7 +286,7 @@ void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e,uint8_t *f) e5=e4+EQm; e6=e5+EQm; e7=e6+EQm; - for (int j = 0; j< EQm; j++,j2+=8){ + for (int j = 0, j2 = 0; j< EQm; j++,j2+=8){ fp=&f[j2]; fp[0] = e0[j]; fp[1] = e1[j]; @@ -310,7 +309,6 @@ void nr_interleaving_ldpc(uint32_t E, uint8_t Qm, uint8_t *e,uint8_t *f) void nr_deinterleaving_ldpc(uint32_t E, uint8_t Qm, int16_t *e,int16_t *f) { - int j2; int16_t *e1,*e2,*e3,*e4,*e5,*e6,*e7; switch(Qm) { case 2: diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 7039764a7e..6c6793967c 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -269,10 +269,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*) ); @@ -286,16 +287,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]); @@ -371,6 +375,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/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index fed58dea12..39e99e6ec3 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -643,10 +643,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, // create shortcuts NR_DL_FRAME_PARMS *const fp = &ue->frame_parms; NR_UE_COMMON *const common_vars = &ue->common_vars; - NR_UE_PDSCH **const pdsch_vars_SI = ue->pdsch_vars_SI; - NR_UE_PDSCH **const pdsch_vars_ra = ue->pdsch_vars_ra; - NR_UE_PDSCH **const pdsch_vars_p = ue->pdsch_vars_p; - NR_UE_PDSCH **const pdsch_vars_mch = ue->pdsch_vars_MCH; NR_UE_PBCH **const pbch_vars = ue->pbch_vars; NR_UE_PRACH **const prach_vars = ue->prach_vars; int i,j,k,l,slot,symb,q; @@ -799,10 +795,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, ue->pdcch_vars[th_id][eNB_id] = (NR_UE_PDCCH *)malloc16_clear(sizeof(NR_UE_PDCCH)); } - pdsch_vars_SI[eNB_id] = (NR_UE_PDSCH *)malloc16_clear(sizeof(NR_UE_PDSCH)); - pdsch_vars_ra[eNB_id] = (NR_UE_PDSCH *)malloc16_clear(sizeof(NR_UE_PDSCH)); - pdsch_vars_p[eNB_id] = (NR_UE_PDSCH *)malloc16_clear(sizeof(NR_UE_PDSCH)); - pdsch_vars_mch[eNB_id] = (NR_UE_PDSCH *)malloc16_clear(sizeof(NR_UE_PDSCH)); prach_vars[eNB_id] = (NR_UE_PRACH *)malloc16_clear(sizeof(NR_UE_PRACH)); pbch_vars[eNB_id] = (NR_UE_PBCH *)malloc16_clear(sizeof(NR_UE_PBCH)); @@ -864,11 +856,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, } } - phy_init_nr_ue__PDSCH( pdsch_vars_SI[eNB_id], fp ); - phy_init_nr_ue__PDSCH( pdsch_vars_ra[eNB_id], fp ); - phy_init_nr_ue__PDSCH( pdsch_vars_p[eNB_id], fp ); - phy_init_nr_ue__PDSCH( pdsch_vars_mch[eNB_id], fp ); - // 100 PRBs * 12 REs/PRB * 4 PDCCH SYMBOLS * 2 LLRs/RE for (th_id=0; th_idpdcch_vars[th_id][eNB_id]->llr = (int16_t *)malloc16_clear( 2*4*100*12*sizeof(uint16_t) ); @@ -932,10 +919,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, ue->pdsch_vars[th_id][eNB_id] = (NR_UE_PDSCH *)malloc16_clear( sizeof(NR_UE_PDSCH) ); } - pdsch_vars_SI[eNB_id] = (NR_UE_PDSCH *)malloc16_clear( sizeof(NR_UE_PDSCH) ); - pdsch_vars_ra[eNB_id] = (NR_UE_PDSCH *)malloc16_clear( sizeof(NR_UE_PDSCH) ); - pdsch_vars_p[eNB_id] = (NR_UE_PDSCH *)malloc16_clear( sizeof(NR_UE_PDSCH) ); - if (abstraction_flag == 0) { for (th_id=0; th_idpdsch_vars[th_id][eNB_id], fp ); 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 455c7fa0fd..f82a7880bb 100644 --- a/openair1/PHY/NR_REFSIG/nr_refsig.h +++ b/openair1/PHY/NR_REFSIG/nr_refsig.h @@ -53,6 +53,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_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index 2849986833..4461edb33b 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -109,220 +109,255 @@ void nr_pdsch_codeword_scrambling_optim(uint8_t *in, } -uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t *dlsch, - uint32_t ***pdsch_dmrs, - int32_t** txdataF, - int16_t amp, - int frame, - uint8_t slot, - NR_DL_FRAME_PARMS *frame_parms, - int xOverhead, - time_stats_t *dlsch_encoding_stats, - time_stats_t *dlsch_scrambling_stats, - time_stats_t *dlsch_modulation_stats, - time_stats_t *tinput, - time_stats_t *tprep, - time_stats_t *tparity, - time_stats_t *toutput, - time_stats_t *dlsch_rate_matching_stats, - time_stats_t *dlsch_interleaving_stats, - time_stats_t *dlsch_segmentation_stats) { +uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, + int frame, + int slot) { - int harq_pid = dlsch->harq_ids[frame%2][slot]; - NR_DL_gNB_HARQ_t *harq = dlsch->harq_processes[harq_pid]; - nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15; - uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5]; - int16_t **mod_symbs = (int16_t**)dlsch->mod_symbs; - int16_t **tx_layers = (int16_t**)dlsch->txdataF; - int8_t Wf[2], Wt[2], l0, l_prime[2], delta; - uint8_t dmrs_Type = rel15->dmrsConfigType; - int nb_re_dmrs; - uint16_t n_dmrs; - if (rel15->dmrsConfigType==NFAPI_NR_DMRS_TYPE1) { - nb_re_dmrs = 6*rel15->numDmrsCdmGrpsNoData; - n_dmrs = ((rel15->rbSize+rel15->rbStart)*6)<<1; - } - else { - nb_re_dmrs = 4*rel15->numDmrsCdmGrpsNoData; - n_dmrs = ((rel15->rbSize+rel15->rbStart)*4)<<1; - } - uint16_t nb_re; - nb_re = ((12*rel15->NrOfSymbols)-nb_re_dmrs-xOverhead)*rel15->rbSize*rel15->NrOfCodewords; - uint8_t Qm = rel15->qamModOrder[0]; - uint32_t encoded_length = nb_re*Qm; - int16_t mod_dmrs[n_dmrs<<1] __attribute__ ((aligned(16))); + NR_gNB_DLSCH_t *dlsch; + uint32_t ***pdsch_dmrs = gNB->nr_gold_pdsch_dmrs[slot]; + int32_t** txdataF = gNB->common_vars.txdataF; + int16_t amp = AMP; + NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; + int xOverhead = 0; + time_stats_t *dlsch_encoding_stats=&gNB->dlsch_encoding_stats; + time_stats_t *dlsch_scrambling_stats=&gNB->dlsch_scrambling_stats; + time_stats_t *dlsch_modulation_stats=&gNB->dlsch_modulation_stats; + time_stats_t *tinput=&gNB->tinput; + time_stats_t *tprep=&gNB->tprep; + time_stats_t *tparity=&gNB->tparity; + time_stats_t *toutput=&gNB->toutput; + time_stats_t *dlsch_rate_matching_stats=&gNB->dlsch_rate_matching_stats; + time_stats_t *dlsch_interleaving_stats=&gNB->dlsch_interleaving_stats; + time_stats_t *dlsch_segmentation_stats=&gNB->dlsch_segmentation_stats; - /// CRC, coding, interleaving and rate matching - AssertFatal(harq->pdu!=NULL,"harq->pdu is null\n"); - start_meas(dlsch_encoding_stats); - nr_dlsch_encoding(harq->pdu, frame, slot, dlsch, frame_parms,tinput,tprep,tparity,toutput, - dlsch_rate_matching_stats, - dlsch_interleaving_stats, - dlsch_segmentation_stats); - stop_meas(dlsch_encoding_stats); + for (int dlsch_id=0;dlsch_iddlsch[dlsch_id][0]; + if (dlsch->slot_tx[slot] == 0) continue; + + int harq_pid = dlsch->harq_ids[frame%2][slot]; + NR_DL_gNB_HARQ_t *harq = dlsch->harq_processes[harq_pid]; + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15 = &harq->pdsch_pdu.pdsch_pdu_rel15; + uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5]; + int16_t **mod_symbs = (int16_t**)dlsch->mod_symbs; + int16_t **tx_layers = (int16_t**)dlsch->txdataF; + int8_t Wf[2], Wt[2], l0, l_prime[2], delta; + uint8_t dmrs_Type = rel15->dmrsConfigType; + int nb_re_dmrs; + uint16_t n_dmrs; + if (rel15->dmrsConfigType==NFAPI_NR_DMRS_TYPE1) { + nb_re_dmrs = 6*rel15->numDmrsCdmGrpsNoData; + n_dmrs = ((rel15->rbSize+rel15->rbStart)*6)<<1; + } + else { + nb_re_dmrs = 4*rel15->numDmrsCdmGrpsNoData; + n_dmrs = ((rel15->rbSize+rel15->rbStart)*4)<<1; + } + uint16_t nb_re; + nb_re = ((12*rel15->NrOfSymbols)-nb_re_dmrs-xOverhead)*rel15->rbSize*rel15->NrOfCodewords; + uint8_t Qm = rel15->qamModOrder[0]; + uint32_t encoded_length = nb_re*Qm; + int16_t mod_dmrs[n_dmrs<<1] __attribute__ ((aligned(16))); + + + /// CRC, coding, interleaving and rate matching + AssertFatal(harq->pdu!=NULL,"harq->pdu is null\n"); + start_meas(dlsch_encoding_stats); + nr_dlsch_encoding(gNB, + harq->pdu, frame, slot, dlsch, frame_parms,tinput,tprep,tparity,toutput, + dlsch_rate_matching_stats, + dlsch_interleaving_stats, + dlsch_segmentation_stats); + stop_meas(dlsch_encoding_stats); #ifdef DEBUG_DLSCH - printf("PDSCH encoding:\nPayload:\n"); - for (int i=0; iB>>7; i++) { - for (int j=0; j<16; j++) - printf("0x%02x\t", harq->pdu[(i<<4)+j]); - printf("\n"); - } - printf("\nEncoded payload:\n"); - for (int i=0; i>3; i++) { - for (int j=0; j<8; j++) - printf("%d", harq->f[(i<<3)+j]); - printf("\t"); - } - printf("\n"); -#endif - - - - /// scrambling - start_meas(dlsch_scrambling_stats); - for (int q=0; qNrOfCodewords; q++) - memset((void*)scrambled_output[q], 0, (encoded_length>>5)*sizeof(uint32_t)); - for (int q=0; qNrOfCodewords; q++) - nr_pdsch_codeword_scrambling_optim(harq->f, - encoded_length, - q, - rel15->dlDmrsScramblingId, - rel15->rnti, - scrambled_output[q]); - - stop_meas(dlsch_scrambling_stats); -#ifdef DEBUG_DLSCH - printf("PDSCH scrambling:\n"); - for (int i=0; i>8; i++) { - for (int j=0; j<8; j++) - printf("0x%08x\t", scrambled_output[0][(i<<3)+j]); - printf("\n"); - } -#endif - - /// Modulation - start_meas(dlsch_modulation_stats); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PDSCH_MODULATION, 1); - for (int q=0; qNrOfCodewords; q++) - nr_modulation(scrambled_output[q], - encoded_length, - Qm, - mod_symbs[q]); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PDSCH_MODULATION, 0); - stop_meas(dlsch_modulation_stats); -#ifdef DEBUG_DLSCH - printf("PDSCH Modulation: Qm %d(%d)\n", Qm, nb_re); - for (int i=0; i>3; i++) { - for (int j=0; j<8; j++) { - printf("%d %d\t", mod_symbs[0][((i<<3)+j)<<1], mod_symbs[0][(((i<<3)+j)<<1)+1]); + printf("PDSCH encoding:\nPayload:\n"); + for (int i=0; iB>>7; i++) { + for (int j=0; j<16; j++) + printf("0x%02x\t", harq->pdu[(i<<4)+j]); + printf("\n"); + } + printf("\nEncoded payload:\n"); + for (int i=0; i>3; i++) { + for (int j=0; j<8; j++) + printf("%d", harq->f[(i<<3)+j]); + printf("\t"); } printf("\n"); - } #endif - - - /// Layer mapping - nr_layer_mapping(mod_symbs, - rel15->nrOfLayers, - nb_re, - tx_layers); + + + + /// scrambling + start_meas(dlsch_scrambling_stats); + for (int q=0; qNrOfCodewords; q++) + memset((void*)scrambled_output[q], 0, (encoded_length>>5)*sizeof(uint32_t)); + for (int q=0; qNrOfCodewords; q++) + nr_pdsch_codeword_scrambling_optim(harq->f, + encoded_length, + q, + rel15->dlDmrsScramblingId, + rel15->rnti, + scrambled_output[q]); + + stop_meas(dlsch_scrambling_stats); #ifdef DEBUG_DLSCH - printf("Layer mapping (%d layers):\n", rel15->nrOfLayers); - for (int l=0; lnrOfLayers; l++) - for (int i=0; i<(nb_re/rel15->nrOfLayers)>>3; i++) { - printf("layer %d, Re %d..%d : ",l,i<<3,(i<<3)+7); + printf("PDSCH scrambling:\n"); + for (int i=0; i>8; i++) { + for (int j=0; j<8; j++) + printf("0x%08x\t", scrambled_output[0][(i<<3)+j]); + printf("\n"); + } +#endif + + /// Modulation + start_meas(dlsch_modulation_stats); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PDSCH_MODULATION, 1); + for (int q=0; qNrOfCodewords; q++) + nr_modulation(scrambled_output[q], + encoded_length, + Qm, + mod_symbs[q]); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PDSCH_MODULATION, 0); + stop_meas(dlsch_modulation_stats); +#ifdef DEBUG_DLSCH + printf("PDSCH Modulation: Qm %d(%d)\n", Qm, nb_re); + for (int i=0; i>3; i++) { for (int j=0; j<8; j++) { - printf("l%d %d\t", tx_layers[l][((i<<3)+j)<<1], tx_layers[l][(((i<<3)+j)<<1)+1]); + printf("%d %d\t", mod_symbs[0][((i<<3)+j)<<1], mod_symbs[0][(((i<<3)+j)<<1)+1]); } printf("\n"); } #endif - - /// Antenna port mapping - //to be moved to init phase potentially, for now tx_layers 1-8 are mapped on antenna ports 1000-1007 - - /// DMRS QPSK modulation - - - l0 = get_l0(rel15->dlDmrsSymbPos); - nr_modulation(pdsch_dmrs[l0][0], n_dmrs, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated - + + + /// Layer mapping + nr_layer_mapping(mod_symbs, + rel15->nrOfLayers, + nb_re, + tx_layers); #ifdef DEBUG_DLSCH - printf("DMRS modulation (single symbol %d, %d symbols, type %d):\n", l0, n_dmrs>>1, dmrs_Type); - for (int i=0; i>4; i++) { - for (int j=0; j<8; j++) { - printf("%d %d\t", mod_dmrs[((i<<3)+j)<<1], mod_dmrs[(((i<<3)+j)<<1)+1]); + printf("Layer mapping (%d layers):\n", rel15->nrOfLayers); + for (int l=0; lnrOfLayers; l++) + for (int i=0; i<(nb_re/rel15->nrOfLayers)>>3; i++) { + printf("layer %d, Re %d..%d : ",l,i<<3,(i<<3)+7); + for (int j=0; j<8; j++) { + printf("l%d %d\t", tx_layers[l][((i<<3)+j)<<1], tx_layers[l][(((i<<3)+j)<<1)+1]); + } + printf("\n"); + } +#endif + + /// Antenna port mapping + //to be moved to init phase potentially, for now tx_layers 1-8 are mapped on antenna ports 1000-1007 + + /// DMRS QPSK modulation + + + l0 = get_l0(rel15->dlDmrsSymbPos); + nr_modulation(pdsch_dmrs[l0][0], n_dmrs, DMRS_MOD_ORDER, mod_dmrs); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated + +#ifdef DEBUG_DLSCH + printf("DMRS modulation (single symbol %d, %d symbols, type %d):\n", l0, n_dmrs>>1, dmrs_Type); + for (int i=0; i>4; i++) { + for (int j=0; j<8; j++) { + printf("%d %d\t", mod_dmrs[((i<<3)+j)<<1], mod_dmrs[(((i<<3)+j)<<1)+1]); + } + printf("\n"); } - printf("\n"); - } #endif - - - /// Resource mapping - - // Non interleaved VRB to PRB mapping - uint16_t start_sc = frame_parms->first_carrier_offset + rel15->rbStart*NR_NB_SC_PER_RB; - if (start_sc >= frame_parms->ofdm_symbol_size) - start_sc -= frame_parms->ofdm_symbol_size; - + + + /// Resource mapping + + // Non interleaved VRB to PRB mapping + uint16_t start_sc = frame_parms->first_carrier_offset + rel15->rbStart*NR_NB_SC_PER_RB; + if (start_sc >= frame_parms->ofdm_symbol_size) + start_sc -= frame_parms->ofdm_symbol_size; + #ifdef DEBUG_DLSCH_MAPPING - printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_re %d,nb_layers %d)\n", - start_sc, rel15->StartSymbolIndex, rel15->rbSize, nb_re,rel15->nrOfLayers); + printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_re %d,nb_layers %d)\n", + start_sc, rel15->StartSymbolIndex, rel15->rbSize, nb_re,rel15->nrOfLayers); #endif - for (int ap=0; apnrOfLayers; ap++) { - - // DMRS params for this ap - get_Wt(Wt, ap, dmrs_Type); - get_Wf(Wf, ap, dmrs_Type); - delta = get_delta(ap, dmrs_Type); - l_prime[0] = 0; // single symbol ap 0 - uint8_t dmrs_symbol = l0+l_prime[0]; + for (int ap=0; apnrOfLayers; ap++) { + + // DMRS params for this ap + get_Wt(Wt, ap, dmrs_Type); + get_Wf(Wf, ap, dmrs_Type); + delta = get_delta(ap, dmrs_Type); + l_prime[0] = 0; // single symbol ap 0 + uint8_t dmrs_symbol = l0+l_prime[0]; #ifdef DEBUG_DLSCH_MAPPING - printf("DMRS Type %d params for ap %d: Wt %d %d \t Wf %d %d \t delta %d \t l_prime %d \t l0 %d\tDMRS symbol %d\n", - 1+dmrs_Type,ap, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime[0], l0, dmrs_symbol); + printf("DMRS Type %d params for ap %d: Wt %d %d \t Wf %d %d \t delta %d \t l_prime %d \t l0 %d\tDMRS symbol %d\n", + 1+dmrs_Type,ap, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime[0], l0, dmrs_symbol); #endif - uint8_t k_prime=0; - uint16_t m=0, n=0, dmrs_idx=0, k=0; - - int txdataF_offset = (slot%2)*frame_parms->samples_per_slot_wCP; - if (dmrs_Type == NFAPI_NR_DMRS_TYPE1) // another if condition to be included to check pdsch config type (reference of k) - dmrs_idx = rel15->rbStart*6; - else - dmrs_idx = rel15->rbStart*4; - - for (int l=rel15->StartSymbolIndex; lStartSymbolIndex+rel15->NrOfSymbols; l++) { - k = start_sc; - for (int i=0; irbSize*NR_NB_SC_PER_RB; i++) { - if ((l == dmrs_symbol) && (k == ((start_sc+get_dmrs_freq_idx(n, k_prime, delta, dmrs_Type))%(frame_parms->ofdm_symbol_size)))) { - ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (Wt[l_prime[0]]*Wf[k_prime]*amp*mod_dmrs[dmrs_idx<<1]) >> 15; - ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (Wt[l_prime[0]]*Wf[k_prime]*amp*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15; + uint8_t k_prime=0; + uint16_t m=0, n=0, dmrs_idx=0, k=0; + + int txdataF_offset = (slot%2)*frame_parms->samples_per_slot_wCP; + if (dmrs_Type == NFAPI_NR_DMRS_TYPE1) // another if condition to be included to check pdsch config type (reference of k) + dmrs_idx = rel15->rbStart*6; + else + dmrs_idx = rel15->rbStart*4; + + for (int l=rel15->StartSymbolIndex; lStartSymbolIndex+rel15->NrOfSymbols; l++) { + k = start_sc; + for (int i=0; irbSize*NR_NB_SC_PER_RB; i++) { + if ((l == dmrs_symbol) && (k == ((start_sc+get_dmrs_freq_idx(n, k_prime, delta, dmrs_Type))%(frame_parms->ofdm_symbol_size)))) { + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (Wt[l_prime[0]]*Wf[k_prime]*amp*mod_dmrs[dmrs_idx<<1]) >> 15; + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (Wt[l_prime[0]]*Wf[k_prime]*amp*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15; #ifdef DEBUG_DLSCH_MAPPING - printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n", - dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)], - ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]); -#endif - dmrs_idx++; - k_prime++; - k_prime&=1; - n+=(k_prime)?0:1; - } - - else { - if( (l != dmrs_symbol) || allowed_xlsch_re_in_dmrs_symbol(k,start_sc,rel15->numDmrsCdmGrpsNoData,dmrs_Type)) { - ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (amp * tx_layers[ap][m<<1]) >> 15; - ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15; -#ifdef DEBUG_DLSCH_MAPPING - printf("m %d\t l %d \t k %d \t txdataF: %d %d\n", - m, l, k, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)], + printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n", + dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)], ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]); #endif - m++; - } - } - if (++k >= frame_parms->ofdm_symbol_size) - k -= frame_parms->ofdm_symbol_size; - } - } - } + dmrs_idx++; + k_prime++; + k_prime&=1; + n+=(k_prime)?0:1; + } + + else { + if( (l != dmrs_symbol) || allowed_xlsch_re_in_dmrs_symbol(k,start_sc,rel15->numDmrsCdmGrpsNoData,dmrs_Type)) { + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (amp * tx_layers[ap][m<<1]) >> 15; + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15; +#ifdef DEBUG_DLSCH_MAPPING + printf("m %d\t l %d \t k %d \t txdataF: %d %d\n", + m, l, k, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)], + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]); +#endif + m++; + } + } + if (++k >= frame_parms->ofdm_symbol_size) + k -= frame_parms->ofdm_symbol_size; + } //RE loop + } // symbol loop + }// layer loop + dlsch->slot_tx[slot]=0; + }// dlsch loop return 0; } + +void dump_pdsch_stats(PHY_VARS_gNB *gNB) { + + for (int i=0;idlsch_stats[i].rnti > 0) + LOG_I(PHY,"DLSCH RNTI %x: round_trials %d(%1.1e):%d(%1.1e):%d(%1.1e):%d, current_Qm %d, current_RI %d, total_bytes TX %d\n", + gNB->dlsch_stats[i].rnti, + gNB->dlsch_stats[i].round_trials[0], + (double)gNB->dlsch_stats[i].round_trials[1]/gNB->dlsch_stats[i].round_trials[0], + gNB->dlsch_stats[i].round_trials[1], + (double)gNB->dlsch_stats[i].round_trials[2]/gNB->dlsch_stats[i].round_trials[0], + gNB->dlsch_stats[i].round_trials[2], + (double)gNB->dlsch_stats[i].round_trials[3]/gNB->dlsch_stats[i].round_trials[0], + gNB->dlsch_stats[i].round_trials[3], + gNB->dlsch_stats[i].current_Qm, + gNB->dlsch_stats[i].current_RI, + gNB->dlsch_stats[i].total_bytes_tx); + +} + +void clear_pdsch_stats(PHY_VARS_gNB *gNB) { + + for (int i=0;idlsch_stats[i],0,sizeof(gNB->dlsch_stats[i])); +} diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h index 3a6851ee8f..23ec756531 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h @@ -69,27 +69,9 @@ void nr_fill_dlsch(PHY_VARS_gNB *gNB, nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu, unsigned char *sdu); -uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t *dlsch, - uint32_t ***pdsch_dmrs, - int32_t** txdataF, - int16_t amp, - int frame, - uint8_t slot, - NR_DL_FRAME_PARMS *frame_parms, - int xOverhead, - time_stats_t *dlsch_encoding_stats, - time_stats_t *dlsch_scrambling_stats, - time_stats_t *dlsch_modulation_stats, - time_stats_t *tinput, - time_stats_t *tprep, - time_stats_t *tparity, - time_stats_t *toutput, - time_stats_t *dlsch_rate_matching_stats, - time_stats_t *dlsch_interleaving_stats, - time_stats_t *dlsch_segmentation_stats); - - - +uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, + int frame, + int slot); void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr, uint16_t N_RB); void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch); @@ -98,7 +80,10 @@ void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch); int16_t find_nr_dlsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type); -int nr_dlsch_encoding(unsigned char *a,int frame, +NR_gNB_SCH_STATS_t *find_nr_dlsch_stats(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type); + +int nr_dlsch_encoding(PHY_VARS_gNB *gNB, + unsigned char *a,int frame, uint8_t slot, NR_gNB_DLSCH_t *dlsch, NR_DL_FRAME_PARMS* frame_parms, @@ -113,4 +98,8 @@ int nr_dlsch_encoding(unsigned char *a,int frame, void nr_emulate_dlsch_payload(uint8_t* payload, uint16_t size); +void dump_pdsch_stats(PHY_VARS_gNB *gNB); + +void clear_pdsch_stats(PHY_VARS_gNB *gNB); + #endif diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index de5e9415b1..e5841d3262 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -309,7 +309,8 @@ void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch) } } -int nr_dlsch_encoding(unsigned char *a, +int nr_dlsch_encoding(PHY_VARS_gNB *gNB, + unsigned char *a, int frame, uint8_t slot, NR_gNB_DLSCH_t *dlsch, @@ -354,6 +355,28 @@ int nr_dlsch_encoding(unsigned char *a, A = rel15->TBSize[0]<<3; + NR_gNB_SCH_STATS_t *stats=NULL; + int first_free=-1; + for (int i=0;idlsch_stats[i].rnti == 0 && first_free == -1) { + first_free = i; + stats=&gNB->dlsch_stats[i]; + } + if (gNB->dlsch_stats[i].rnti == dlsch->rnti) { + stats=&gNB->dlsch_stats[i]; + break; + } + } + + if (stats) { + stats->round_trials[dlsch->harq_processes[harq_pid]->round]++; + stats->rnti = dlsch->rnti; + if (dlsch->harq_processes[harq_pid]->round == 0){ + stats->total_bytes_tx += rel15->TBSize[0]; + stats->current_RI = rel15->nrOfLayers; + stats->current_Qm = rel15->qamModOrder[0]; + } + } G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs,mod_order,rel15->nrOfLayers); LOG_D(PHY,"dlsch coding A %d G %d mod_order %d\n", A,G, mod_order); diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c index ba0bf6b4bf..5ce2c45a7d 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c @@ -255,27 +255,28 @@ void nr_emulate_dlsch_payload(uint8_t* pdu, uint16_t size) { } int16_t find_nr_dlsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type) { - - uint16_t i; - int16_t first_free_index=-1; - - AssertFatal(gNB!=NULL,"gNB is null\n"); - for (i=0; idlsch[i]!=NULL,"gNB->dlsch[%d] is null\n",i); - AssertFatal(gNB->dlsch[i][0]!=NULL,"gNB->dlsch[%d][0] is null\n",i); - LOG_D(PHY,"searching for rnti %x : dlsch_index %d=> harq_mask %x, rnti %x, first_free_index %d\n", rnti,i,gNB->dlsch[i][0]->harq_mask,gNB->dlsch[i][0]->rnti,first_free_index); - if ((gNB->dlsch[i][0]->harq_mask >0) && - (gNB->dlsch[i][0]->rnti==rnti)) return i; - else if ((gNB->dlsch[i][0]->harq_mask == 0) && (first_free_index==-1)) first_free_index=i; - } - if (type == SEARCH_EXIST) return -1; - if (first_free_index != -1) - gNB->dlsch[first_free_index][0]->rnti = 0; - return first_free_index; + + uint16_t i; + int16_t first_free_index=-1; + + AssertFatal(gNB!=NULL,"gNB is null\n"); + for (i=0; idlsch[i]!=NULL,"gNB->dlsch[%d] is null\n",i); + AssertFatal(gNB->dlsch[i][0]!=NULL,"gNB->dlsch[%d][0] is null\n",i); + LOG_D(PHY,"searching for rnti %x : dlsch_index %d=> harq_mask %x, rnti %x, first_free_index %d\n", rnti,i, + gNB->dlsch[i][0]->harq_mask,gNB->dlsch[i][0]->rnti,first_free_index); + if ((gNB->dlsch[i][0]->harq_mask >0) && + (gNB->dlsch[i][0]->rnti==rnti)) return i; + else if ((gNB->dlsch[i][0]->harq_mask == 0) && (first_free_index==-1)) first_free_index=i; + } + if (type == SEARCH_EXIST) return -1; + if (first_free_index != -1) + gNB->dlsch[first_free_index][0]->rnti = 0; + return first_free_index; + } - void nr_fill_dlsch(PHY_VARS_gNB *gNB, int frame, int slot, diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index 782df3dbba..27aa48128a 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.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c index 9928f3f604..0040f01544 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c @@ -111,7 +111,6 @@ void nr_ulsch_unscrambling_optim(int16_t* llr, uint32_t n_RNTI) { #if defined(__x86_64__) || defined(__i386__) - uint8_t reset; uint32_t x1, x2, s=0; x2 = (n_RNTI<<15) + Nid; @@ -137,3 +136,29 @@ void nr_ulsch_unscrambling_optim(int16_t* llr, n_RNTI); #endif } + +void dump_pusch_stats(PHY_VARS_gNB *gNB) { + + for (int i=0;iulsch_stats[i].rnti>0) + LOG_I(PHY,"ULSCH RNTI %x: round_trials %d(%1.1e):%d(%1.1e):%d(%1.1e):%d, current_Qm %d, current_RI %d, total_bytes RX/SCHED %d/%d\n", + gNB->ulsch_stats[i].rnti, + gNB->ulsch_stats[i].round_trials[0], + (double)gNB->ulsch_stats[i].round_trials[1]/gNB->ulsch_stats[i].round_trials[0], + gNB->ulsch_stats[i].round_trials[1], + (double)gNB->ulsch_stats[i].round_trials[2]/gNB->ulsch_stats[i].round_trials[0], + gNB->ulsch_stats[i].round_trials[2], + (double)gNB->ulsch_stats[i].round_trials[3]/gNB->ulsch_stats[i].round_trials[0], + gNB->ulsch_stats[i].round_trials[3], + gNB->ulsch_stats[i].current_Qm, + gNB->ulsch_stats[i].current_RI, + gNB->ulsch_stats[i].total_bytes_rx, + gNB->ulsch_stats[i].total_bytes_tx); + +} + +void clear_pusch_stats(PHY_VARS_gNB *gNB) { + + for (int i=0;iulsch_stats[i],0,sizeof(gNB->ulsch_stats[i])); +} diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h index f4f977ff74..a9845b6bbb 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h @@ -87,3 +87,7 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int UE_id, uint8_t harq_pid); int16_t find_nr_ulsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type); + +void dump_pusch_stats(PHY_VARS_gNB *gNB); + +void clear_pusch_stats(PHY_VARS_gNB *gNB); diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index f033941518..7980206eb4 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -208,8 +208,6 @@ void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch) ulsch->Mlimit = 0; ulsch->max_ldpc_iterations = 0; ulsch->last_iteration_cnt = 0; - ulsch->num_active_cba_groups = 0; - for (i=0;icba_rnti[i] = 0; for (i=0;iharq_process_id[i] = 0; for (i=0; iharq_processes[i]->rar_alloc=0; ulsch->harq_processes[i]->status=NR_SCH_IDLE; ulsch->harq_processes[i]->subframe_scheduling_flag=0; - ulsch->harq_processes[i]->subframe_cba_scheduling_flag=0; ulsch->harq_processes[i]->phich_active=0; ulsch->harq_processes[i]->phich_ACK=0; ulsch->harq_processes[i]->previous_first_rb=0; @@ -289,7 +286,7 @@ void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch) static uint32_t prnt_crc_cnt = 0; #endif -uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, +uint32_t nr_ulsch_decoding(PHY_VARS_gNB *gNB, uint8_t UE_id, short *ulsch_llr, NR_DL_FRAME_PARMS *frame_parms, @@ -311,7 +308,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, #endif - NR_gNB_ULSCH_t *ulsch = phy_vars_gNB->ulsch[UE_id][0]; + NR_gNB_ULSCH_t *ulsch = gNB->ulsch[UE_id][0]; NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_processes[harq_pid]; t_nrLDPC_dec_params decParams; @@ -366,15 +363,14 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, LOG_D(PHY,"ULSCH Decoding, harq_pid %d TBS %d G %d mcs %d Nl %d nb_rb %d, Qm %d, n_layers %d\n",harq_pid,A,G, mcs, n_layers, nb_rb, Qm, n_layers); - - if (R<1024) - Coderate = (float) R /(float) 1024; - else - Coderate = (float) R /(float) 2048; - - if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){ - p_decParams->BG = 2; - if (Coderate < 0.3333) { + if (R<1024) + Coderate = (float) R /(float) 1024; + else + Coderate = (float) R /(float) 2048; + + if ((A <=292) || ((A<=3824) && (Coderate <= 0.6667)) || Coderate <= 0.25){ + p_decParams->BG = 2; + if (Coderate < 0.3333) { p_decParams->R = 15; kc = 52; } @@ -401,8 +397,29 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, kc = 27; } } - + + NR_gNB_SCH_STATS_t *stats=NULL; + int first_free=-1; + for (int i=0;iulsch_stats[i].rnti == 0 && first_free == -1) { + first_free = i; + stats=&gNB->ulsch_stats[i]; + } + if (gNB->ulsch_stats[i].rnti == ulsch->rnti) { + stats=&gNB->ulsch_stats[i]; + break; + } + } + if (stats) { + stats->rnti = ulsch->rnti; + stats->round_trials[harq_process->round]++; + } if (harq_process->round == 0) { + if (stats) { + stats->current_Qm = Qm; + stats->current_RI = n_layers; + stats->total_bytes_tx += harq_process->TBS; + } // This is a new packet, so compute quantities regarding segmentation if (A > 3824) harq_process->B = A+24; @@ -460,7 +477,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, E = nr_get_E(G, harq_process->C, Qm, n_layers, r); - start_meas(&phy_vars_gNB->ulsch_deinterleaving_stats); + start_meas(&gNB->ulsch_deinterleaving_stats); //////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////// nr_deinterleaving_ldpc /////////////////////////////////// @@ -476,10 +493,10 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, //for (int i =0; i<16; i++) // printf("rx output deinterleaving w[%d]= %d r_offset %d\n", i,harq_process->w[r][i], r_offset); - stop_meas(&phy_vars_gNB->ulsch_deinterleaving_stats); + stop_meas(&gNB->ulsch_deinterleaving_stats); - LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rv %d, round %d)...\n", + LOG_D(PHY,"HARQ_PID %d Rate Matching Segment %d (coded bits %d,unpunctured/repeated bits %d, TBS %d, mod_order %d, nb_rb %d, Nl %d, rvidx %d, round %d)...\n", harq_pid,r, G, Kr*3, harq_process->TBS, @@ -497,7 +514,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, ///////////////////////// harq_process->e =====> harq_process->d ///////////////////////// - start_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats); + start_meas(&gNB->ulsch_rate_unmatching_stats); Tbslbrm = nr_compute_tbslbrm(0,nb_rb,n_layers,harq_process->C); @@ -514,12 +531,12 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, harq_process->F, Kr-harq_process->F-2*(p_decParams->Z))==-1) { - stop_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats); + stop_meas(&gNB->ulsch_rate_unmatching_stats); LOG_E(PHY,"ulsch_decoding.c: Problem in rate_matching\n"); return (ulsch->max_ldpc_iterations + 1); } else { - stop_meas(&phy_vars_gNB->ulsch_rate_unmatching_stats); + stop_meas(&gNB->ulsch_rate_unmatching_stats); } r_offset += E; @@ -557,7 +574,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, if (err_flag == 0) { - start_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats); + start_meas(&gNB->ulsch_ldpc_decoding_stats); //LOG_E(PHY,"AbsSubframe %d.%d Start LDPC segment %d/%d A %d ",frame%1024,nr_tti_rx,r,harq_process->C-1, A); @@ -625,7 +642,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, //write_output("dec_output.m","dec0",harq_process->c[0],Kr_bytes,1,4); #endif - stop_meas(&phy_vars_gNB->ulsch_ldpc_decoding_stats); + stop_meas(&gNB->ulsch_ldpc_decoding_stats); } if ((err_flag == 0) && (ret >= (ulsch->max_ldpc_iterations + 1))) { @@ -648,7 +665,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, #ifdef gNB_DEBUG_TRACE LOG_I(PHY,"[gNB %d] ULSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d) Kr %d r %d\n", - phy_vars_gNB->Mod_id, frame, nr_tti_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,Kr,r); + gNB->Mod_id, frame, nr_tti_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,Kr,r); #endif // harq_process->harq_ack.ack = 0; @@ -665,7 +682,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, } // LOG_D(PHY,"[gNB %d] ULSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n", - // phy_vars_gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,ulsch->Mlimit,harq_process->TBS); + // gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,ulsch->Mlimit,harq_process->TBS); harq_process->handled = 1; ret = ulsch->max_ldpc_iterations + 1; @@ -674,7 +691,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, #ifdef gNB_DEBUG_TRACE LOG_I(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d TBS %d\n", - phy_vars_gNB->Mod_id,nr_tti_rx,harq_process->TBS); + gNB->Mod_id,nr_tti_rx,harq_process->TBS); #endif harq_process->status = SCH_IDLE; @@ -685,7 +702,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, // harq_process->harq_ack.harq_id = harq_pid; // harq_process->harq_ack.send_harq_status = 1; - // LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->round,harq_process->TBS); + // LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d (pid %d, round %d, TBS %d)\n",gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->round,harq_process->TBS); // Reassembly of Transport block here @@ -708,6 +725,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, #endif } + if (stats) stats->total_bytes_rx += harq_process->TBS; } #ifdef DEBUG_ULSCH_DECODING diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index d7adc5c8a4..77ff9449ca 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, @@ -1046,6 +1013,67 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, } +void nr_ulsch_detection_mrc(NR_DL_FRAME_PARMS *frame_parms, + int32_t **rxdataF_comp, + int32_t **ul_ch_mag, + int32_t **ul_ch_magb, + uint8_t symbol, + uint16_t nb_rb) { + int n_rx = frame_parms->nb_antennas_rx; +#if defined(__x86_64__) || defined(__i386__) + __m128i *rxdataF_comp128[1+n_rx],*ul_ch_mag128[1+n_rx],*ul_ch_mag128b[1+n_rx]; +#elif defined(__arm__) + int16x8_t *rxdataF_comp128_0,*ul_ch_mag128_0,*ul_ch_mag128_0b; + int16x8_t *rxdataF_comp128_1,*ul_ch_mag128_1,*ul_ch_mag128_1b; +#endif + int32_t i; + +#ifdef __AVX2__ + int off = ((nb_rb&1) == 1)? 4:0; +#else + int off = 0; +#endif + + if (frame_parms->nb_antennas_rx>1) { +#if defined(__x86_64__) || defined(__i386__) + int nb_re = nb_rb*12; + for (int aa=0;aanb_antennas_rx;aa++) { + rxdataF_comp128[aa] = (__m128i *)&rxdataF_comp[aa][(symbol*(nb_re + off))]; + ul_ch_mag128[aa] = (__m128i *)&ul_ch_mag[aa][(symbol*(nb_re + off))]; + ul_ch_mag128b[aa] = (__m128i *)&ul_ch_magb[aa][(symbol*(nb_re + off))]; + + // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation) + for (i=0; iN_RB_DL*12]; + rxdataF_comp128_1 = (int16x8_t *)&rxdataF_comp[1][symbol*frame_parms->N_RB_DL*12]; + ul_ch_mag128_0 = (int16x8_t *)&ul_ch_mag[0][symbol*frame_parms->N_RB_DL*12]; + ul_ch_mag128_1 = (int16x8_t *)&ul_ch_mag[1][symbol*frame_parms->N_RB_DL*12]; + ul_ch_mag128_0b = (int16x8_t *)&ul_ch_magb[0][symbol*frame_parms->N_RB_DL*12]; + ul_ch_mag128_1b = (int16x8_t *)&ul_ch_magb[1][symbol*frame_parms->N_RB_DL*12]; + + // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation) + for (i=0; iframe_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); - } } @@ -1111,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 --------------------- //---------------------------------------------------------- @@ -1145,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], @@ -1183,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, @@ -1198,34 +1211,66 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, gNB->pusch_vars[ulsch_id]->log2_maxh); stop_meas(&gNB->ulsch_channel_compensation_stats); - + start_meas(&gNB->ulsch_mrc_stats); + nr_ulsch_detection_mrc(frame_parms, + gNB->pusch_vars[ulsch_id]->rxdataF_comp, + gNB->pusch_vars[ulsch_id]->ul_ch_mag, + gNB->pusch_vars[ulsch_id]->ul_ch_magb, + symbol, + rel15_ul->rb_size); + stop_meas(&gNB->ulsch_mrc_stats); #ifdef NR_SC_FDMA 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_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index 7006b54c29..36bcb2f379 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -590,6 +590,9 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, // Fixme: correct type is unsigned, but nrLDPC_decoder and all called behind use signed int if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) { LOG_D(PHY,"Segment %u CRC OK\n\033[0m",r); + if (r==0) + for (int i=0;i<10;i++) LOG_D(PHY,"byte %d : %x\n",i,((uint8_t*)llrProcBuf)[i]); + //Temporary hack no_iteration_ldpc = dlsch->max_ldpc_iterations; ret = no_iteration_ldpc; @@ -663,9 +666,8 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, harq_process->harq_ack.harq_id = harq_pid; harq_process->harq_ack.send_harq_status = 1; harq_process->errors[harq_process->round]++; - harq_process->round++; // [hna] uncomment this line when HARQ is implemented - // printf("Rate: [UE %d] DLSCH: Setting NACK for subframe %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,subframe,harq_pid,harq_process->round); + // printf("Rate: [UE %d] DLSCH: Setting NACK for slot %d (pid %d, round %d)\n",phy_vars_ue->Mod_id,nr_tti_rx,harq_pid,harq_process->round); if (harq_process->round >= dlsch->Mlimit) { harq_process->status = SCH_IDLE; harq_process->round = 0; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 2d61e764f3..7aa0e357aa 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -159,20 +159,17 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, switch (type) { case SI_PDSCH: - pdsch_vars = ue->pdsch_vars_SI; + pdsch_vars = ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]]; dlsch = &ue->dlsch_SI[eNB_id]; dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; break; case RA_PDSCH: - pdsch_vars = ue->pdsch_vars_ra; + pdsch_vars = ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]]; dlsch = &ue->dlsch_ra[eNB_id]; dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; - // WIP TBR Hotfix - memcpy((void*)&pdsch_vars[eNB_id]->dl_ch_estimates[0][ue->frame_parms.ofdm_symbol_size*2], (void*)&ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][0]->dl_ch_estimates[0][ue->frame_parms.ofdm_symbol_size*2], ue->frame_parms.ofdm_symbol_size*sizeof(int32_t)); - break; case PDSCH: @@ -189,7 +186,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, break; } - if (dlsch1_harq){ + if (dlsch0_harq && dlsch1_harq){ //printf("status TB0 = %d, status TB1 = %d \n", dlsch[0]->harq_processes[harq_pid]->status, dlsch[1]->harq_processes[harq_pid]->status); LOG_D(PHY,"AbsSubframe %d.%d / Sym %d harq_pid %d, harq status %d.%d \n", frame, nr_tti_rx, symbol, harq_pid, dlsch0_harq->status, dlsch1_harq->status); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c index ce1c0df156..e0b24a033a 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c @@ -786,16 +786,16 @@ void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms, //---------------------------------------------------------------------------------------------- void nr_dlsch_64qam_llr(NR_DL_FRAME_PARMS *frame_parms, - int32_t **rxdataF_comp, - int16_t *dlsch_llr, - int32_t **dl_ch_mag, - int32_t **dl_ch_magb, - uint8_t symbol, - uint32_t len, - uint8_t first_symbol_flag, - uint16_t nb_rb, - uint32_t llr_offset, - uint8_t beamforming_mode) + int32_t **rxdataF_comp, + int16_t *dlsch_llr, + int32_t **dl_ch_mag, + int32_t **dl_ch_magb, + uint8_t symbol, + uint32_t len, + uint8_t first_symbol_flag, + uint16_t nb_rb, + uint32_t llr_offset, + uint8_t beamforming_mode) { #if defined(__x86_64__) || defined(__i386__) __m128i *rxF = (__m128i*)&rxdataF_comp[0][(symbol*nb_rb*12)]; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c index e4cab0b9a6..29841c3186 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c @@ -71,7 +71,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ int16_t prach_tmp[98304*2*4] __attribute__((aligned(32))); int16_t Ncp = 0, amp, *prach, *prach2, *prachF, *Xu; - int32_t Xu_re, Xu_im, samp_count; + int32_t Xu_re, Xu_im; int prach_start, prach_sequence_length, i, prach_len, dftlen, mu, kbar, K, n_ra_prb, k; //int restricted_Type; @@ -103,22 +103,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index, ue->X_u); - if (mu == 0) - samp_count = fp->samples_per_subframe; - else - samp_count = (slot%(fp->slots_per_subframe/2)) ? fp->samples_per_slotN0 : fp->samples_per_slot0; - - #ifdef OAI_USRP - prach_start = (ue->rx_offset + slot*samp_count - ue->hw_timing_advance - ue->N_TA_offset); - #else //normal case (simulation) - prach_start = slot*samp_count - ue->N_TA_offset; - #endif - - if (prach_start<0) - prach_start += (fp->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME); - - if (prach_start >= (fp->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME)) - prach_start -= (fp->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME); + prach_start = fp->get_samples_slot_timestamp(slot, fp, 0); // First compute physical root sequence /************************************************************************ @@ -796,40 +781,16 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ } #ifdef NR_PRACH_DEBUG - LOG_I(PHY, "PRACH [UE %d] N_RB_UL %d prach_start %d, prach_len %d, rx_offset %d, hw_timing_advance %d, N_TA_offset %d\n", Mod_id, + LOG_I(PHY, "PRACH [UE %d] N_RB_UL %d prach_start %d, prach_len %d\n", Mod_id, fp->N_RB_UL, prach_start, - prach_len, - ue->rx_offset, - ue->hw_timing_advance, - ue->N_TA_offset); + prach_len); #endif - #if defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) - int j, overflow = prach_start + prach_len - NR_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_subframe; - - #ifdef NR_PRACH_DEBUG - LOG_I( PHY, "PRACH [UE %d] overflow = %d\n", Mod_id, overflow); - #endif - - // prach_start=414.730, overflow=-39470 prach_len=6600 fp->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME 460.800 prach_start+prach_len 421.330 fp->samples_per_subframe 46080 - - // from prach_start=414.730 to prach_start+prach_len 421.330 - for (i = prach_start, j = 0; i < min(fp->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME, prach_start + prach_len); i++, j++) { - ((int16_t*)ue->common_vars.txdata[0])[2*i] = prach[2*j]; - ((int16_t*)ue->common_vars.txdata[0])[2*i+1] = prach[2*j+1]; - } - - for (i = 0; i < overflow; i++,j++) { - ((int16_t*)ue->common_vars.txdata[0])[2*i] = prach[2*j]; - ((int16_t*)ue->common_vars.txdata[0])[2*i+1] = prach[2*j+1]; - } - #else // simulators - for (i=0; icommon_vars.txdata[0][prach_start]))[2*i] = prach[2*i]; - ((int16_t*)(&ue->common_vars.txdata[0][prach_start]))[2*i+1] = prach[2*i+1]; - } - #endif + for (i=0; icommon_vars.txdata[0][prach_start]))[2*i] = prach[2*i]; + ((int16_t*)(&ue->common_vars.txdata[0][prach_start]))[2*i+1] = prach[2*i+1]; + } //printf("----------------------\n"); //for(int ii = prach_start; ii<2*(prach_start + prach_len); ii++){ diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index c02228bc9f..6f5fba7812 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -424,19 +424,15 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, } } -#ifdef DEBUG_DLSCH_CODING - printf("Rate Matching, Code segment %d (coded bits (G) %u, unpunctured/repeated bits per code segment %d, mod_order %d, nb_rb %d)...\n", - r, - G, - Kr*3, - mod_order,nb_rb); -#endif + + LOG_D(PHY,"Rate Matching, Code segment %d (coded bits (G) %u, unpunctured/repeated bits per code segment %d, mod_order %d, nb_rb %d, rvidx %d)...\n", + r, + G, + Kr*3, + mod_order,nb_rb, + harq_process->pusch_pdu.pusch_data.rv_index); //start_meas(rm_stats); -#ifdef DEBUG_DLSCH_CODING - printf("rvidx in encoding = %d\n", harq_process->pusch_pdu.pusch_data.rv_index); -#endif - ///////////////////////// d---->| Rate matching bit selection |---->e ///////////////////////// /////////// diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index cdc084b35f..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; ltiming_advance; -#else - timing_advance = 0; -#endif - - tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0) - timing_advance; - - if (tx_offset < 0) - tx_offset += frame_parms->samples_per_frame; + tx_offset = frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0); // clear the transmit data array for the current subframe /*for (int aa=0; aaframe_parms.nb_antennas_tx; aa++) { @@ -471,49 +461,19 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE, } } - if(UE->N_TA_offset > tx_offset) { - int32_t *tmp_idft_out = (int32_t*)malloc16(frame_parms->get_samples_per_slot(slot, frame_parms) * sizeof(int32_t)); - - for(ap = 0; ap < Nl; ap++) { - if (frame_parms->Ncp == 1) { // extended cyclic prefix - PHY_ofdm_mod(txdataF[ap], - tmp_idft_out, - frame_parms->ofdm_symbol_size, - 12, - frame_parms->nb_prefix_samples, - CYCLIC_PREFIX); - } else { // normal cyclic prefix - nr_normal_prefix_mod(txdataF[ap], - tmp_idft_out, - 14, - frame_parms); - } - - memcpy((void *) &txdata[ap][frame_parms->samples_per_frame - UE->N_TA_offset + tx_offset], - (void *) tmp_idft_out, - (UE->N_TA_offset - tx_offset) * sizeof(int32_t)); - - memcpy((void *) &txdata[ap][0], - (void *) &tmp_idft_out[UE->N_TA_offset - tx_offset], - (frame_parms->get_samples_per_slot(slot, frame_parms) - UE->N_TA_offset + tx_offset) * sizeof(int32_t)); - } - - free(tmp_idft_out); - } else { // UE->N_TA_offset <= tx_offset - for (ap = 0; ap < Nl; ap++) { - if (frame_parms->Ncp == 1) { // extended cyclic prefix - PHY_ofdm_mod(txdataF[ap], - &txdata[ap][tx_offset-UE->N_TA_offset], - frame_parms->ofdm_symbol_size, - 12, - frame_parms->nb_prefix_samples, - CYCLIC_PREFIX); - } else { // normal cyclic prefix - nr_normal_prefix_mod(txdataF[ap], - &txdata[ap][tx_offset-UE->N_TA_offset], - 14, - frame_parms); - } + for (ap = 0; ap < Nl; ap++) { + if (frame_parms->Ncp == 1) { // extended cyclic prefix + PHY_ofdm_mod(txdataF[ap], + &txdata[ap][tx_offset], + frame_parms->ofdm_symbol_size, + 12, + frame_parms->nb_prefix_samples, + CYCLIC_PREFIX); + } else { // normal cyclic prefix + nr_normal_prefix_mod(txdataF[ap], + &txdata[ap][tx_offset], + 14, + frame_parms); } } diff --git a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c index c977118df3..cf0fc716f9 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pss_nr.c @@ -270,7 +270,6 @@ void generate_pss_nr(NR_DL_FRAME_PARMS *fp,int N_ID_2) if (k>= fp->ofdm_symbol_size) k-=fp->ofdm_symbol_size; - for (int i=0; i < LENGTH_PSS_NR; i++) { synchroF_tmp[2*k] = primary_synchro[2*i]; synchroF_tmp[2*k+1] = primary_synchro[2*i+1]; diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c index 44d7b93ae2..78e34036a3 100644 --- a/openair1/PHY/TOOLS/nr_phy_scope.c +++ b/openair1/PHY/TOOLS/nr_phy_scope.c @@ -525,32 +525,25 @@ static void uePcchLLR (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_ if (!phy_vars_ue->pdcch_vars[0][eNB_id]->llr) return; - NR_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms; - uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx; - uint8_t nb_antennas_tx = frame_parms->nb_antennas_tx; - scopeSample_t **chest_f = (scopeSample_t **) phy_vars_ue->pbch_vars[eNB_id]->dl_ch_estimates; - int ind = 0; - float chest_f_abs[frame_parms->ofdm_symbol_size]; - float freq[frame_parms->ofdm_symbol_size]; + int num_re = 4*273*12; // 12*frame_parms->N_RB_DL*num_pdcch_symbols + int Qm = 2; + int coded_bits_per_codeword = num_re*Qm; + localBuff(llr,coded_bits_per_codeword*RX_NB_TH_MAX); + localBuff(bit,coded_bits_per_codeword*RX_NB_TH_MAX); + int base=0; - for (int atx=0; atxofdm_symbol_size; k++) { - freq[ind] = (float)ind; - chest_f_abs[ind] = (short)10*log10(1.0+SquaredNorm(chest_f[(atx<<1)+arx][6144+k])); - ind++; - } - } + for (int thr=0 ; thr < RX_NB_TH_MAX ; thr ++ ) { + int16_t *pdcch_llr = (int16_t *) phy_vars_ue->pdcch_vars[thr][eNB_id]->llr; + + for (int i=0; ichest_f,0,nb_antennas_rx*nb_antennas_tx*nsymb_ce); - //fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*frame_parms->symbols_per_tti,2); - // fl_set_xyplot_xtics(form->chest_f,nb_antennas_rx*nb_antennas_tx*2,2); - //fl_set_xyplot_xgrid(form->chest_f,FL_GRID_MAJOR); - oai_xygraph(graph,freq,chest_f_abs,frame_parms->ofdm_symbol_size,0,10); + oai_xygraph(graph,bit,llr,base,0,10); } static void uePcchIQ (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) { diff --git a/openair1/PHY/defs_UE.h b/openair1/PHY/defs_UE.h index 9163fc13b6..e17b752e7b 100644 --- a/openair1/PHY/defs_UE.h +++ b/openair1/PHY/defs_UE.h @@ -452,55 +452,6 @@ typedef struct { uint32_t llr_length[14]; } LTE_UE_PDSCH; -typedef struct { - /// \brief Received frequency-domain signal after extraction. - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..] - int32_t **rxdataF_ext; - /// \brief Received frequency-domain signal after extraction and channel compensation. - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..] - double **rxdataF_comp; - /// \brief Downlink channel estimates extracted in PRBS. - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..] - int32_t **dl_ch_estimates_ext; - /// \brief Downlink cross-correlation of MIMO channel estimates (unquantized PMI) extracted in PRBS. - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..] - double **dl_ch_rho_ext; - /// \brief Downlink PMIs extracted in PRBS and grouped in subbands. - /// - first index: ressource block [0..N_RB_DL[ - uint8_t *pmi_ext; - /// \brief Magnitude of Downlink Channel (16QAM level/First 64QAM level). - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..] - double **dl_ch_mag; - /// \brief Magnitude of Downlink Channel (2nd 64QAM level). - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..] - double **dl_ch_magb; - /// \brief Cross-correlation of two eNB signals. - /// - first index: rx antenna [0..nb_antennas_rx[ - /// - second index: ? [0..] - double **rho; - /// never used... always send dl_ch_rho_ext instead... - double **rho_i; - /// \brief Pointers to llr vectors (2 TBs). - /// - first index: ? [0..1] (hard coded) - /// - second index: ? [0..1179743] (hard coded) - int16_t *llr[2]; - /// \f$\log_2(\max|H_i|^2)\f$ - uint8_t log2_maxh; - /// \brief Pointers to llr vectors (128-bit alignment). - /// - first index: ? [0..0] (hard coded) - /// - second index: ? [0..] - int16_t **llr128; - //uint32_t *rb_alloc; - //uint8_t Qm[2]; - //MIMO_mode_t mimo_mode; -} LTE_UE_PDSCH_FLP; - typedef struct { /// \brief Pointers to extracted PDCCH symbols in frequency-domain. /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx @@ -667,7 +618,6 @@ typedef struct { uint8_t current_thread_id[10]; LTE_UE_PDSCH *pdsch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX+1]; // two RxTx Threads - LTE_UE_PDSCH_FLP *pdsch_vars_flp[NUMBER_OF_CONNECTED_eNB_MAX+1]; LTE_UE_PDSCH *pdsch_vars_SI[NUMBER_OF_CONNECTED_eNB_MAX+1]; LTE_UE_PDSCH *pdsch_vars_ra[NUMBER_OF_CONNECTED_eNB_MAX+1]; LTE_UE_PDSCH *pdsch_vars_p[NUMBER_OF_CONNECTED_eNB_MAX+1]; diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 72aa2afaed..2554cc2aba 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -124,6 +124,15 @@ typedef struct { nfapi_nr_ul_dci_request_pdus_t pdcch_pdu; } NR_gNB_UL_PDCCH_t; +typedef struct { + uint16_t rnti; + int round_trials[8]; + int total_bytes_tx; + int total_bytes_rx; + int current_Qm; + int current_RI; +} NR_gNB_SCH_STATS_t; + typedef struct { /// Pointers to 16 HARQ processes for the DLSCH NR_DL_gNB_HARQ_t *harq_processes[NR_MAX_NB_HARQ_PROCESSES]; @@ -169,6 +178,8 @@ typedef struct { int16_t sqrt_rho_b; } NR_gNB_DLSCH_t; + + typedef struct { int frame; int slot; @@ -345,10 +356,6 @@ typedef struct { uint8_t max_ldpc_iterations; /// number of iterations used in last LDPC decoding uint8_t last_iteration_cnt; - /// num active cba group - uint8_t num_active_cba_groups; - /// num active cba group - uint16_t cba_rnti[NUM_MAX_CBA_GROUP]; } NR_gNB_ULSCH_t; typedef struct { @@ -390,8 +397,6 @@ typedef struct { /// - first index: rx antenna id [0..nb_antennas_rx[ /// - second index (definition from phy_init_lte_eNB()): ? [0..12*N_RB_UL*frame_parms->symbols_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[ @@ -459,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; @@ -704,6 +716,11 @@ typedef struct PHY_VARS_gNB_s { NR_gNB_ULSCH_t *ulsch[NUMBER_OF_NR_ULSCH_MAX][2]; // [Nusers times][2 codewords] NR_gNB_DLSCH_t *dlsch_SI,*dlsch_ra,*dlsch_p; NR_gNB_DLSCH_t *dlsch_PCH; + /// statistics for DLSCH measurement collection + NR_gNB_SCH_STATS_t dlsch_stats[NUMBER_OF_NR_SCH_STATS_MAX]; + /// statistics for ULSCH measurement collection + NR_gNB_SCH_STATS_t ulsch_stats[NUMBER_OF_NR_SCH_STATS_MAX]; + t_nrPolar_params *uci_polarParams; uint8_t pbch_configured; @@ -798,9 +815,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/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 9bdf892ceb..62ffeaaea8 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -416,55 +416,6 @@ typedef struct { uint32_t llr_length[14]; } NR_UE_PDSCH; -typedef struct { - /// \brief Received frequency-domain signal after extraction. - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..] - int32_t **rxdataF_ext; - /// \brief Received frequency-domain signal after extraction and channel compensation. - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..] - double **rxdataF_comp; - /// \brief Downlink channel estimates extracted in PRBS. - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..] - int32_t **dl_ch_estimates_ext; - /// \brief Downlink cross-correlation of MIMO channel estimates (unquantized PMI) extracted in PRBS. - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..] - double **dl_ch_rho_ext; - /// \brief Downlink PMIs extracted in PRBS and grouped in subbands. - /// - first index: ressource block [0..N_RB_DL[ - uint8_t *pmi_ext; - /// \brief Magnitude of Downlink Channel (16QAM level/First 64QAM level). - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..] - double **dl_ch_mag; - /// \brief Magnitude of Downlink Channel (2nd 64QAM level). - /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx - /// - second index: ? [0..] - double **dl_ch_magb; - /// \brief Cross-correlation of two eNB signals. - /// - first index: rx antenna [0..nb_antennas_rx[ - /// - second index: ? [0..] - double **rho; - /// never used... always send dl_ch_rho_ext instead... - double **rho_i; - /// \brief Pointers to llr vectors (2 TBs). - /// - first index: ? [0..1] (hard coded) - /// - second index: ? [0..1179743] (hard coded) - int16_t *llr[2]; - /// \f$\log_2(\max|H_i|^2)\f$ - uint8_t log2_maxh; - /// \brief Pointers to llr vectors (128-bit alignment). - /// - first index: ? [0..0] (hard coded) - /// - second index: ? [0..] - int16_t **llr128; - //uint32_t *rb_alloc; - //uint8_t Qm[2]; - //MIMO_mode_t mimo_mode; -} NR_UE_PDSCH_FLP; - #define NR_PDCCH_DEFS_NR_UE #define NR_NBR_CORESET_ACT_BWP 3 // The number of CoreSets per BWP is limited to 3 (including initial CORESET: ControlResourceId 0) #define NR_NBR_SEARCHSPACE_ACT_BWP 10 // The number of SearchSpaces per BWP is limited to 10 (including initial SEARCHSPACE: SearchSpaceId 0) @@ -902,11 +853,6 @@ typedef struct { t_nrPolar_params *polarList; NR_UE_PDSCH *pdsch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX+1]; // two RxTx Threads - NR_UE_PDSCH_FLP *pdsch_vars_flp[NUMBER_OF_CONNECTED_eNB_MAX+1]; - NR_UE_PDSCH *pdsch_vars_SI[NUMBER_OF_CONNECTED_eNB_MAX+1]; - NR_UE_PDSCH *pdsch_vars_ra[NUMBER_OF_CONNECTED_eNB_MAX+1]; - NR_UE_PDSCH *pdsch_vars_p[NUMBER_OF_CONNECTED_eNB_MAX+1]; - NR_UE_PDSCH *pdsch_vars_MCH[NUMBER_OF_CONNECTED_eNB_MAX]; NR_UE_PBCH *pbch_vars[NUMBER_OF_CONNECTED_eNB_MAX]; NR_UE_PDCCH *pdcch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX]; NR_UE_PRACH *prach_vars[NUMBER_OF_CONNECTED_eNB_MAX]; @@ -1022,7 +968,6 @@ typedef struct { /// Timing Advance updates variables /// Timing advance update computed from the TA command signalled from gNB int timing_advance; - int hw_timing_advance; int N_TA_offset; ///timing offset used in TDD NR_UL_TIME_ALIGNMENT_t ul_time_alignment[NUMBER_OF_CONNECTED_gNB_MAX]; diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c index 974441e5db..84490bfad4 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.c +++ b/openair1/SCHED_NR/fapi_nr_l1.c @@ -218,7 +218,7 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PRACH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot); nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[i].prach_pdu; nr_fill_prach(gNB, UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu); - nr_fill_prach_ru(gNB->RU_list[0], UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu); + if (gNB->RU_list[0]->if_south == LOCAL_RF) nr_fill_prach_ru(gNB->RU_list[0], UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu); break; } } diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 8ddec64455..48cbfd9e09 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -192,20 +192,8 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, for (int i=0; inum_pdsch_rnti[slot]; i++) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,1); LOG_D(PHY, "PDSCH generation started (%d) in frame %d.%d\n", gNB->num_pdsch_rnti[slot],frame,slot); - nr_generate_pdsch(gNB->dlsch[i][0], - gNB->nr_gold_pdsch_dmrs[slot], - gNB->common_vars.txdataF, - AMP, frame, slot, fp, 0, - &gNB->dlsch_encoding_stats, - &gNB->dlsch_scrambling_stats, - &gNB->dlsch_modulation_stats, - &gNB->tinput, - &gNB->tprep, - &gNB->tparity, - &gNB->toutput, - &gNB->dlsch_rate_matching_stats, - &gNB->dlsch_interleaving_stats, - &gNB->dlsch_segmentation_stats); + nr_generate_pdsch(gNB,frame, slot); + if ((frame&127) == 0) dump_pdsch_stats(gNB); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,0); } @@ -251,7 +239,7 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH pusch_pdu->qam_mod_order, pusch_pdu->nrOfLayers); - AssertFatal(G>0,"G is 0 : rb_size %d, number_symbols %d, nb_re_dmrs %d, number_dmrs_symbols %d, qam_mod_order %d, nrOfLayer %d\n", + AssertFatal(G>0,"G is 0 : rb_size %u, number_symbols %d, nb_re_dmrs %d, number_dmrs_symbols %d, qam_mod_order %u, nrOfLayer %u\n", pusch_pdu->rb_size, number_symbols, nb_re_dmrs, @@ -598,5 +586,8 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) } } } + // figure out a better way to choose slot_rx, 19 is ok for a particular TDD configuration with 30kHz SCS + if ((frame_rx&127) == 0 && slot_rx==19) dump_pusch_stats(gNB); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,0); } diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index 2ea7b806e9..4cdb70d79c 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -118,6 +118,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ dlsch0_harq->harq_ack.rx_status = downlink_harq_process(dlsch0_harq, dlsch0->current_harq_pid, dlsch_config_pdu->ndi, dlsch0->rnti_type); dlsch0_harq->harq_ack.vDAI_DL = dlsch_config_pdu->dai; LOG_D(MAC, ">>>> \tdlsch0->g_pucch = %d\tdlsch0_harq.mcs = %d\n", dlsch0->g_pucch, dlsch0_harq->mcs); + } } } diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 8fad144c94..ec42cb92eb 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -1103,169 +1103,6 @@ uint16_t nr_get_n1_pucch(PHY_VARS_NR_UE *ue, return(-1); } - - -void ulsch_common_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t empty_subframe) { - - int aa; - NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; - - int nsymb; - int nr_tti_tx = proc->nr_tti_tx; - int frame_tx = proc->frame_tx; - int ulsch_start; - int overflow=0; -#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) - int k,l; - int dummy_tx_buffer[frame_parms->samples_per_subframe] __attribute__((aligned(16))); -#endif - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_COMMON,VCD_FUNCTION_IN); -#if UE_TIMING_TRACE - start_meas(&ue->ofdm_mod_stats); -#endif - nsymb = (frame_parms->Ncp == 0) ? 14 : 12; - -#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)//this is the EXPRESS MIMO case - ulsch_start = (ue->rx_offset+nr_tti_tx*frame_parms->samples_per_subframe- - ue->hw_timing_advance- - ue->timing_advance- - ue->N_TA_offset+5); - //LOG_E(PHY,"ul-signal [nr_tti_rx: %d, ulsch_start %d]\n",nr_tti_tx, ulsch_start); - - if(ulsch_start < 0) - ulsch_start = ulsch_start + (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_subframe); - - if (ulsch_start > (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_subframe)) - ulsch_start = ulsch_start % (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_subframe); - - //LOG_E(PHY,"ul-signal [nr_tti_rx: %d, ulsch_start %d]\n",nr_tti_tx, ulsch_start); -#else //this is the normal case - ulsch_start = (frame_parms->samples_per_subframe*nr_tti_tx)-ue->N_TA_offset; //-ue->timing_advance; -#endif //else EXMIMO - - //#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) - if (empty_subframe) - { - //#if 1 - overflow = ulsch_start - 9*frame_parms->samples_per_subframe; - for (aa=0; aanb_antennas_tx; aa++) { - - if (overflow > 0) - { - memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*(frame_parms->samples_per_subframe-overflow)); - memset(&ue->common_vars.txdata[aa][0],0,4*overflow); - } - else - { - memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*frame_parms->samples_per_subframe); - } - } - /*#else - overflow = ulsch_start - 9*frame_parms->samples_per_subframe; - for (aa=0; aanb_antennas_tx; aa++) { - for (k=ulsch_start; ksamples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME,ulsch_start+frame_parms->samples_per_subframe); k++) { - ((short*)ue->common_vars.txdata[aa])[2*k] = 0; - ((short*)ue->common_vars.txdata[aa])[2*k+1] = 0; - } - - for (k=0; kcommon_vars.txdata[aa])[2*k] = 0; - ((short*)ue->common_vars.txdata[aa])[2*k+1] = 0; - } - } - endif*/ - return; - } - - - if ((frame_tx%100) == 0) - LOG_D(PHY,"[UE %d] Frame %d, nr_tti_rx %d: ulsch_start = %d (rxoff %d, HW TA %d, timing advance %d, TA_offset %d\n", - ue->Mod_id,frame_tx,nr_tti_tx, - ulsch_start, - ue->rx_offset, - ue->hw_timing_advance, - ue->timing_advance, - ue->N_TA_offset); - - - for (aa=0; aanb_antennas_tx; aa++) { - if (frame_parms->Ncp == 1) - PHY_ofdm_mod(&ue->common_vars.txdataF[aa][nr_tti_tx*nsymb*frame_parms->ofdm_symbol_size], -#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) - dummy_tx_buffer, -#else - &ue->common_vars.txdata[aa][ulsch_start], -#endif - frame_parms->ofdm_symbol_size, - nsymb, - frame_parms->nb_prefix_samples, - CYCLIC_PREFIX); - else - normal_prefix_mod(&ue->common_vars.txdataF[aa][nr_tti_tx*nsymb*frame_parms->ofdm_symbol_size], -#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) - dummy_tx_buffer, -#else - &ue->common_vars.txdata[aa][ulsch_start], -#endif - nsymb, - &ue->frame_parms); - - -#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) - apply_7_5_kHz(ue,dummy_tx_buffer,0); - apply_7_5_kHz(ue,dummy_tx_buffer,1); -#else - apply_7_5_kHz(ue,&ue->common_vars.txdata[aa][ulsch_start],0); - apply_7_5_kHz(ue,&ue->common_vars.txdata[aa][ulsch_start],1); -#endif - - -#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) - overflow = ulsch_start - 9*frame_parms->samples_per_subframe; - - - for (k=ulsch_start,l=0; ksamples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME,ulsch_start+frame_parms->samples_per_subframe); k++,l++) { - ((short*)ue->common_vars.txdata[aa])[2*k] = ((short*)dummy_tx_buffer)[2*l]<<4; - ((short*)ue->common_vars.txdata[aa])[2*k+1] = ((short*)dummy_tx_buffer)[2*l+1]<<4; - } - - for (k=0; kcommon_vars.txdata[aa])[2*k] = ((short*)dummy_tx_buffer)[2*l]<<4; - ((short*)ue->common_vars.txdata[aa])[2*k+1] = ((short*)dummy_tx_buffer)[2*l+1]<<4; - } -#if defined(EXMIMO) - // handle switch before 1st TX nr_tti_rx, guarantee that the slot prior to transmission is switch on - for (k=ulsch_start - (frame_parms->samples_per_subframe>>1) ; kcommon_vars.txdata[aa][k+frame_parms->samples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] &= 0xFFFEFFFE; - else if (k>(frame_parms->samples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME)) - ue->common_vars.txdata[aa][k-frame_parms->samples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] &= 0xFFFEFFFE; - else - ue->common_vars.txdata[aa][k] &= 0xFFFEFFFE; - } -#endif -#endif - /* - only for debug - LOG_I(PHY,"ul-signal [nr_tti_rx: %d, ulsch_start %d, TA: %d, rxOffset: %d, timing_advance: %d, hw_timing_advance: %d]\n",nr_tti_tx, ulsch_start, ue->N_TA_offset, ue->rx_offset, ue->timing_advance, ue->hw_timing_advance); - if( (crash == 1) && (nr_tti_tx == 0) ) - { - LOG_E(PHY,"***** DUMP TX Signal [ulsch_start %d] *****\n",ulsch_start); - write_output("txBuff.m","txSignal",&ue->common_vars.txdata[aa][ulsch_start],frame_parms->samples_per_subframe,1,1); - } - */ - - } //nb_antennas_tx - -#if UE_TIMING_TRACE - stop_meas(&ue->ofdm_mod_stats); -#endif - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_COMMON,VCD_FUNCTION_OUT); - -} - #endif UE_MODE_t get_nrUE_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t gNB_id){ @@ -3028,7 +2865,7 @@ void copy_harq_proc_struct(NR_DL_UE_HARQ_t *harq_processes_dest, NR_DL_UE_HARQ_t memcpy(harq_ack_dest, current_harq_ack, sizeof(nr_harq_status_t)); }*/ -void nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_id, PDSCH_t pdsch, NR_UE_DLSCH_t *dlsch0, NR_UE_DLSCH_t *dlsch1) { +int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_id, PDSCH_t pdsch, NR_UE_DLSCH_t *dlsch0, NR_UE_DLSCH_t *dlsch1) { int nr_tti_rx = proc->nr_tti_rx; int m; @@ -3036,9 +2873,9 @@ void nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB int first_symbol_flag=0; if (!dlsch0) - return; + return 0; if (dlsch0->active == 0) - return; + return 0; if (!dlsch1) { int harq_pid = dlsch0->current_harq_pid; @@ -3049,7 +2886,7 @@ void nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB uint16_t s0 = dlsch0->harq_processes[harq_pid]->start_symbol; uint16_t s1 = dlsch0->harq_processes[harq_pid]->nb_symbols; - LOG_D(PHY,"[UE %d] PDSCH type %d active in nr_tti_rx %d, harq_pid %d, rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d, DMRS mask %x\n",ue->Mod_id,pdsch,nr_tti_rx,harq_pid,pdsch_start_rb,pdsch_nb_rb,s0,s1,dlsch0->harq_processes[harq_pid]->dlDmrsSymbPos); + LOG_D(PHY,"[UE %d] PDSCH type %d active in nr_tti_rx %d, harq_pid %d (%d), rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d, DMRS mask %x\n",ue->Mod_id,pdsch,nr_tti_rx,harq_pid,dlsch0->harq_processes[harq_pid]->status,pdsch_start_rb,pdsch_nb_rb,s0,s1,dlsch0->harq_processes[harq_pid]->dlDmrsSymbPos); // do channel estimation for first DMRS only for (m = s0; m < 3; m++) { @@ -3083,8 +2920,8 @@ void nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB #endif // process DLSCH received in first slot // skip DMRS symbols (will have to check later if PDSCH/DMRS are multiplexed - if (((1<harq_processes[harq_pid]->dlDmrsSymbPos) == 0) - nr_rx_pdsch(ue, + if (((1<harq_processes[harq_pid]->dlDmrsSymbPos) == 0) { + if (nr_rx_pdsch(ue, pdsch, eNB_id, eNB_id_i, @@ -3094,20 +2931,25 @@ void nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB first_symbol_flag, dual_stream_UE, i_mod, - dlsch0->current_harq_pid); + dlsch0->current_harq_pid) < 0) + return -1; + } else { // This is to adjust the llr offset in the case of skipping over a dmrs symbol (i.e. in case of no PDSCH REs in DMRS) - if (pdsch == RA_PDSCH) ue->pdsch_vars_ra[eNB_id]->llr_offset[m]=ue->pdsch_vars_ra[eNB_id]->llr_offset[m-1]; - else if (pdsch == PDSCH) nr_rx_pdsch(ue, - pdsch, - eNB_id, - eNB_id_i, - proc->frame_rx, - nr_tti_rx, // nr_tti_rx, - m, - first_symbol_flag, - dual_stream_UE, - i_mod, - dlsch0->current_harq_pid); + if (pdsch == RA_PDSCH) ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->llr_offset[m]=ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->llr_offset[m-1]; + else if (pdsch == PDSCH) { + if (nr_rx_pdsch(ue, + pdsch, + eNB_id, + eNB_id_i, + proc->frame_rx, + nr_tti_rx, // nr_tti_rx, + m, + first_symbol_flag, + dual_stream_UE, + i_mod, + dlsch0->current_harq_pid) < 0) + return -1; + } else AssertFatal(1==0,"not RA_PDSCH or PDSCH\n"); } if (pdsch == PDSCH) LOG_D(PHY,"Done processing symbol %d : llr_offset %d\n",m,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->llr_offset[m]); @@ -3126,6 +2968,7 @@ void nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB } } // CRNTI active } + return 0; } // WIP fix: @@ -3343,14 +3186,8 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, if (1) { switch (pdsch) { case SI_PDSCH: - pdsch_vars = ue->pdsch_vars_SI[eNB_id]; - break; case RA_PDSCH: - pdsch_vars = ue->pdsch_vars_ra[eNB_id]; - break; case P_PDSCH: - pdsch_vars = ue->pdsch_vars_p[eNB_id]; - break; case PDSCH: pdsch_vars = ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]; break; @@ -4059,7 +3896,6 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, int coreset_nb_rb=0; int coreset_start_rb=0; - int symbol_offset_in_subframe=0; if (pdcch_vars->nb_search_space > 0) get_coreset_rballoc(pdcch_vars->pdcch_config[0].coreset.frequency_domain_resource,&coreset_nb_rb,&coreset_start_rb); @@ -4070,7 +3906,6 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, if ((ue->decode_MIB == 1) && slot_pbch) { LOG_I(PHY," ------ PBCH ChannelComp/LLR: frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx); - symbol_offset_in_subframe = (nr_tti_rx % fp->slots_per_subframe)*fp->symbols_per_slot; for (int i=1; i<4; i++) { nr_slot_fep(ue, @@ -4157,27 +3992,29 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, } else if (ue->dlsch_ra[0]->active == 1){ dlsch = ue->dlsch_ra[0]; } - AssertFatal(dlsch != NULL, "Unsupported mode\n"); - uint8_t harq_pid = dlsch->current_harq_pid; - NR_DL_UE_HARQ_t *dlsch0_harq = dlsch->harq_processes[harq_pid]; - uint16_t nb_symb_sch = dlsch0_harq->nb_symbols; - uint16_t start_symb_sch = dlsch0_harq->start_symbol; - int symb_dmrs = -1; - LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx); - //to update from pdsch config + if (dlsch) { + uint8_t harq_pid = dlsch->current_harq_pid; + NR_DL_UE_HARQ_t *dlsch0_harq = dlsch->harq_processes[harq_pid]; + uint16_t nb_symb_sch = dlsch0_harq->nb_symbols; + uint16_t start_symb_sch = dlsch0_harq->start_symbol; + int symb_dmrs = -1; - for (int i=0;i<4;i++) if (((1<dlDmrsSymbPos) > 0) {symb_dmrs=i;break;} - AssertFatal(symb_dmrs>=0,"no dmrs in 0..3\n"); - LOG_D(PHY,"Initializing dmrs for symb %d DMRS mask %x\n",symb_dmrs,dlsch0_harq->dlDmrsSymbPos); - nr_gold_pdsch(ue,symb_dmrs,0, 1); + LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx); + //to update from pdsch config + + for (int i=0;i<4;i++) if (((1<dlDmrsSymbPos) > 0) {symb_dmrs=i;break;} + AssertFatal(symb_dmrs>=0,"no dmrs in 0..3\n"); + LOG_D(PHY,"Initializing dmrs for symb %d DMRS mask %x\n",symb_dmrs,dlsch0_harq->dlDmrsSymbPos); + nr_gold_pdsch(ue,symb_dmrs,0, 1); - for (uint16_t m=start_symb_sch;m<(nb_symb_sch+start_symb_sch) ; m++){ - nr_slot_fep(ue, + for (uint16_t m=start_symb_sch;m<(nb_symb_sch+start_symb_sch) ; m++){ + nr_slot_fep(ue, m, //to be updated from higher layer nr_tti_rx, 0, 0); + } } } else { LOG_D(PHY,"[UE %d] Frame %d, nr_tti_rx %d: No DCIs found\n", ue->Mod_id, frame_rx, nr_tti_rx); @@ -4189,9 +4026,10 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, start_meas(&ue->generic_stat); #endif // do procedures for C-RNTI + int ret_pdsch = 0; if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->active == 1) { //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); - nr_ue_pdsch_procedures(ue, + ret_pdsch = nr_ue_pdsch_procedures(ue, proc, eNB_id, PDSCH, @@ -4286,7 +4124,8 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]); #endif - nr_ue_dlsch_procedures(ue, + if (ret_pdsch >= 0) + nr_ue_dlsch_procedures(ue, proc, eNB_id, PDSCH, diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index ad0358300b..957495181a 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -501,7 +501,7 @@ int main(int argc, char **argv) //printf("crc32: [0]->0x%08x\n",crc24c(test_input, 32)); // generate signal if (input_fd == NULL) { - nr_dlsch_encoding(test_input, frame, slot, dlsch, frame_parms,NULL,NULL,NULL,NULL,NULL,NULL,NULL); + nr_dlsch_encoding(gNB, test_input, frame, slot, dlsch, frame_parms,NULL,NULL,NULL,NULL,NULL,NULL,NULL); } for (SNR = snr0; SNR < snr1; SNR += snr_step) { diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 4a03b52e01..38400cab51 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -41,6 +41,7 @@ #include "PHY/MODULATION/nr_modulation.h" #include "PHY/MODULATION/modulation_UE.h" #include "PHY/NR_REFSIG/refsig_defs_ue.h" +#include "PHY/NR_TRANSPORT/nr_dlsch.h" #include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" #include "SCHED_NR/fapi_nr_l1.h" @@ -181,7 +182,7 @@ int main(int argc, char **argv) //unsigned char frame_type = 0; - int frame=0,slot=1; + int frame=1,slot=1; int frame_length_complex_samples; int frame_length_complex_samples_no_prefix; NR_DL_FRAME_PARMS *frame_parms; @@ -716,12 +717,16 @@ int main(int argc, char **argv) reset_meas(&gNB->tparity); reset_meas(&gNB->toutput); + clear_pdsch_stats(gNB); + n_errors = 0; effRate = 0; //n_errors2 = 0; //n_alamouti = 0; errors_scrambling=0; n_false_positive = 0; + if (n_trials== 1) num_rounds = 1; + for (trial = 0; trial < n_trials; trial++) { errors_bit = 0; @@ -756,6 +761,7 @@ int main(int argc, char **argv) UE_list->UE_sched_ctrl[0].harq_processes[harq_pid].ndi = !(trial&1); + UE_list->UE_sched_ctrl[0].harq_processes[harq_pid].round = round; UE_list->UE_sched_ctrl[0].current_harq_pid = harq_pid; gNB->dlsch[0][0]->harq_processes[harq_pid]->round = round; @@ -953,6 +959,7 @@ int main(int argc, char **argv) (float) n_errors / (float) n_trials); printf("*****************************************\n"); printf("\n"); + dump_pdsch_stats(gNB); printf("SNR %f : n_errors (negative CRC) = %d/%d, Avg round %.2f, Channel BER %e, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %d bits/slot\n", SNR, n_errors, n_trials,roundStats[snrRun],(double)errors_scrambling/available_bits/n_trials,effRate,effRate/TBS*100,TBS); printf("\n"); @@ -1014,6 +1021,7 @@ int main(int argc, char **argv) LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1], frame_length_complex_samples, 1, 1); LOG_M("chestF0.m","chF0",UE->pdsch_vars[0][0]->dl_ch_estimates_ext,N_RB_DL*12*14,1,1); write_output("rxF_comp.m","rxFc",&UE->pdsch_vars[0][0]->rxdataF_comp0[0][0],N_RB_DL*12*14,1,1); + LOG_M("rxF_llr.m","rxFllr",UE->pdsch_vars[UE->current_thread_id[UE_proc.nr_tti_rx]][0]->llr[0],available_bits,1,0); break; } diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 883dcbf729..7d96e70809 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -604,7 +604,7 @@ int main(int argc, char **argv){ /* tx_lev_dB not used later, no need to set */ //tx_lev_dB = (unsigned int) dB_fixed(tx_lev); - prach_start = subframe*frame_parms->samples_per_subframe-UE->N_TA_offset; + prach_start = subframe*frame_parms->samples_per_subframe; #ifdef NR_PRACH_DEBUG LOG_M("txsig0.m", "txs0", &txdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1); diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 3a1e6b1c5c..9dd6d61557 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -55,7 +55,6 @@ //#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c" #include "openair2/LAYER2/NR_MAC_UE/mac_proto.h" #include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h" - #define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0)) #include "SIMULATION/LTE_PHY/common_sim.h" @@ -119,7 +118,7 @@ int main(int argc, char **argv) double sigma, sigma_dB; double snr_step = .2; uint8_t snr1set = 0; - int slot = 8, frame = 0; + int slot = 8, frame = 1; FILE *output_fd = NULL; double *s_re[2]= {s_re0,s_re1}; double *s_im[2]= {s_im0,s_im1}; @@ -163,12 +162,19 @@ int main(int argc, char **argv) int rv_index = 0; float roundStats[50]; float effRate; - float eff_tp_check = 0.7; + //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; + int file_offset = 0; double DS_TDL = .03; int pusch_tgt_snrx10 = 200; @@ -182,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) { @@ -311,10 +317,12 @@ int main(int argc, char **argv) snr0 = atof(optarg); printf("Setting SNR0 to %f\n", snr0); break; - + +/* case 't': eff_tp_check = (float)atoi(optarg)/100; break; +*/ /* case 'r': ricean_factor = pow(10,-.1*atof(optarg)); @@ -358,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; @@ -387,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]); @@ -424,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; @@ -460,14 +484,15 @@ int main(int argc, char **argv) DS_TDL, 0, 0, 0); - UE2gNB->max_Doppler = maxDoppler; if (UE2gNB == NULL) { printf("Problem generating channel model. Exiting.\n"); exit(-1); } + 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; @@ -511,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"); @@ -605,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; @@ -622,36 +643,81 @@ 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)); snrRun = 0; - int n_errs; + int n_errs = 0; - double factor = 1; - if (openair0_cfg[0].threequarter_fs== 1) factor =.75; - int ta_offset=1600; - if (N_RB_DL <217) ta_offset=800; - else if (N_RB_DL < 106) ta_offset = 400; - - int slot_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0);// - (int)(800*factor); + int slot_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0); int slot_length = slot_offset - frame_parms->get_samples_slot_timestamp(slot-1,frame_parms,0); if (input_fd != NULL) { @@ -659,8 +725,6 @@ int main(int argc, char **argv) // 800 samples is N_TA_OFFSET for FR1 @ 30.72 Ms/s, AssertFatal(frame_parms->subcarrier_spacing==30000,"only 30 kHz for file input for now (%d)\n",frame_parms->subcarrier_spacing); - // slot_offset -= (int)(800*factor); - fseek(input_fd,file_offset*((slot_length<<2)+4000+16),SEEK_SET); fread((void*)&n_rnti,sizeof(int16_t),1,input_fd); printf("rnti %x\n",n_rnti); @@ -690,7 +754,6 @@ int main(int argc, char **argv) slot_offset, ((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[i], ((int16_t*)&gNB->common_vars.rxdata[0][slot_offset])[1+i]); - fclose(input_fd); } for (SNR = snr0; SNR < snr1; SNR += snr_step) { @@ -702,11 +765,13 @@ int main(int argc, char **argv) int round_trials[4]={0,0,0,0}; uint32_t errors_scrambling[4] = {0,0,0,0}; + clear_pusch_stats(gNB); for (trial = 0; trial < n_trials; trial++) { uint8_t round = 0; crc_status = 1; errors_decoding = 0; + memset((void*)roundStats,0,50*sizeof(roundStats[0])); while (roundharq_processes[harq_pid]->round = round; @@ -720,30 +785,15 @@ 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); reset_meas(&gNB->ulsch_rbs_extraction_stats); 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; @@ -770,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; @@ -780,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; @@ -813,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; @@ -826,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); @@ -909,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]); + } } } - - } + + } //////////////////////////////////////////////////////////// @@ -967,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)) || @@ -981,14 +1055,8 @@ 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); + printf("\x1B[31m""[frame %d][trial %d]\tnumber of errors in unscrambling = %u\n" "\x1B[0m", frame, trial, errors_scrambling[0]); } for (i = 0; i < TBS; i++) { @@ -1027,7 +1095,8 @@ int main(int argc, char **argv) printf("*****************************************\n"); printf("SNR %f: n_errors (%d/%d,%d/%d,%d/%d,%d/%d) (negative CRC), false_positive %d/%d, errors_scrambling (%u/%u,%u/%u,%u/%u,%u/%u\n", SNR, n_errors[0], round_trials[0],n_errors[1], round_trials[1],n_errors[2], round_trials[2],n_errors[3], round_trials[3], n_false_positive, n_trials, errors_scrambling[0],available_bits*n_trials,errors_scrambling[1],available_bits*n_trials,errors_scrambling[2],available_bits*n_trials,errors_scrambling[3],available_bits*n_trials); printf("\n"); - printf("SNR %f: Channel BLER (%e,%e,%e,%e), Channel BER (%e,%e,%e,%e) Avg round %.2f, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %d bits/slot\n", SNR, + printf("SNR %f: Channel BLER (%e,%e,%e,%e), Channel BER (%e,%e,%e,%e) Avg round %.2f, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %u bits/slot\n", + SNR, (double)n_errors[0]/round_trials[0], (double)n_errors[1]/round_trials[0], (double)n_errors[2]/round_trials[0], @@ -1037,6 +1106,9 @@ int main(int argc, char **argv) (double)errors_scrambling[2]/available_bits/round_trials[0], (double)errors_scrambling[3]/available_bits/round_trials[0], roundStats[snrRun],effRate,effRate/TBS*100,TBS); + + dump_pusch_stats(gNB); + printf("*****************************************\n"); printf("\n"); @@ -1044,8 +1116,10 @@ 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"); printStatIndent2(&gNB->ulsch_llr_stats,"ULSCH llr computation"); printStatIndent(&gNB->ulsch_unscrambling_stats,"ULSCH unscrambling"); printStatIndent(&gNB->ulsch_decoding_stats,"ULSCH total decoding time"); @@ -1054,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/COMMON/platform_constants.h b/openair2/COMMON/platform_constants.h index 4ed928416b..af364437b8 100644 --- a/openair2/COMMON/platform_constants.h +++ b/openair2/COMMON/platform_constants.h @@ -101,6 +101,7 @@ #define NUMBER_OF_NR_DLSCH_MAX 2//16 #define NUMBER_OF_NR_ULSCH_MAX 2//16 +#define NUMBER_OF_NR_SCH_STATS_MAX 16 #define NUMBER_OF_NR_PUCCH_MAX 16 #define NUMBER_OF_NR_SR_MAX 16 #define NUMBER_OF_NR_PDCCH_MAX 16 diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 526fc17083..bc105b9080 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -1151,7 +1151,7 @@ uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config, if (NCS == 0) return nb_preambles; else { r = L_ra/NCS; - found_sequences = (nb_preambles/r) + (nb_preambles%r!=0); //ceil(nb_preambles/r) + found_sequences = (nb_preambles/r) + (nb_preambles%r!=0); //ceil(nb_preambles/r) printf(" found_sequences %u\n", found_sequences); return (found_sequences); } @@ -1616,92 +1616,156 @@ uint16_t Table_61412[28][2] = {{2,30},{2,40},{2,50},{2,64},{2,78},{2,99},{2,120} uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx) { switch(table_idx) { case 0: + if (Imcs > 28) { + LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,28])\n", Imcs); + Imcs = 28; + } return (Table_51311[Imcs][0]); break; case 1: + if (Imcs > 27) { + LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,27])\n", Imcs); + Imcs = 27; + } return (Table_51312[Imcs][0]); break; case 2: + if (Imcs > 28) { + LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,28])\n", Imcs); + Imcs = 28; + } return (Table_51313[Imcs][0]); break; default: - AssertFatal(0, "Invalid MCS table index %d (expected in range [1,3])\n", table_idx); + AssertFatal(0, "Invalid MCS table index %d (expected in range [0,2])\n", table_idx); } } uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx) { switch(table_idx) { case 0: + if (Imcs > 28) { + LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,28])\n", Imcs); + Imcs = 28; + } return (Table_51311[Imcs][1]); break; case 1: + if (Imcs > 27) { + LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,27])\n", Imcs); + Imcs = 27; + } return (Table_51312[Imcs][1]); break; case 2: + if (Imcs > 28) { + LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,28])\n", Imcs); + Imcs = 28; + } return (Table_51313[Imcs][1]); break; default: - AssertFatal(0, "Invalid MCS table index %d (expected in range [1,3])\n", table_idx); + AssertFatal(0, "Invalid MCS table index %d (expected in range [0,2])\n", table_idx); } } uint8_t nr_get_Qm_ul(uint8_t Imcs, uint8_t table_idx) { switch(table_idx) { case 0: + if (Imcs > 28) { + LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,28])\n", Imcs); + Imcs = 28; + } return (Table_51311[Imcs][0]); break; case 1: + if (Imcs > 27) { + LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,27])\n", Imcs); + Imcs = 27; + } return (Table_51312[Imcs][0]); break; case 2: + if (Imcs > 28) { + LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,28])\n", Imcs); + Imcs = 28; + } return (Table_51313[Imcs][0]); break; case 3: + if (Imcs > 27) { + LOG_E(MAC, "Invalid MCS index %d for MCS table 3 (expected range [0,27])\n", Imcs); + Imcs = 27; + } return (Table_61411[Imcs][0]); break; case 4: + if (Imcs > 27) { + LOG_E(MAC, "Invalid MCS index %d for MCS table 4 (expected range [0,27])\n", Imcs); + Imcs = 27; + } return (Table_61412[Imcs][0]); break; default: - AssertFatal(0, "Invalid MCS table index %d (expected in range [1,2])\n", table_idx); + AssertFatal(0, "Invalid MCS table index %d (expected in range [0,4])\n", table_idx); } } uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx) { switch(table_idx) { case 0: + if (Imcs > 28) { + LOG_E(MAC, "Invalid MCS index %d for MCS table 0 (expected range [0,28])\n", Imcs); + Imcs = 28; + } return (Table_51311[Imcs][1]); break; case 1: + if (Imcs > 27) { + LOG_E(MAC, "Invalid MCS index %d for MCS table 1 (expected range [0,27])\n", Imcs); + Imcs = 27; + } return (Table_51312[Imcs][1]); break; case 2: + if (Imcs > 28) { + LOG_E(MAC, "Invalid MCS index %d for MCS table 2 (expected range [0,28])\n", Imcs); + Imcs = 28; + } return (Table_51313[Imcs][1]); break; case 3: + if (Imcs > 27) { + LOG_E(MAC, "Invalid MCS index %d for MCS table 3 (expected range [0,27])\n", Imcs); + Imcs = 27; + } return (Table_61411[Imcs][1]); break; case 4: + if (Imcs > 27) { + LOG_E(MAC, "Invalid MCS index %d for MCS table 4 (expected range [0,27])\n", Imcs); + Imcs = 27; + } return (Table_61412[Imcs][1]); break; default: - AssertFatal(0, "Invalid MCS table index %d (expected in range [1,2])\n", table_idx); + AssertFatal(0, "Invalid MCS table index %d (expected in range [0,4])\n", table_idx); } } @@ -1876,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, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 60f331a086..ab533af941 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -2342,7 +2342,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc nr_ue_process_dci_freq_dom_resource_assignment(pusch_config_pdu_0_0,NULL,n_RB_ULBWP,0,dci->frequency_domain_assignment.val); /* TIME_DOM_RESOURCE_ASSIGNMENT */ if (nr_ue_process_dci_time_dom_resource_assignment(mac,pusch_config_pdu_0_0,NULL,dci->time_domain_assignment.val) < 0) - break; + return -1; /* FREQ_HOPPING_FLAG */ if ((mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.resource_allocation != 0) && (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.frequency_hopping !=0)) @@ -2416,7 +2416,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc nr_ue_process_dci_freq_dom_resource_assignment(pusch_config_pdu_0_1,NULL,n_RB_ULBWP,0,dci->frequency_domain_assignment.val); /* TIME_DOM_RESOURCE_ASSIGNMENT */ if (nr_ue_process_dci_time_dom_resource_assignment(mac,pusch_config_pdu_0_1,NULL,dci->time_domain_assignment.val) < 0) - break; + return -1; /* FREQ_HOPPING_FLAG */ if ((mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.resource_allocation != 0) && (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.frequency_hopping !=0)) @@ -2747,7 +2747,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc nr_ue_process_dci_freq_dom_resource_assignment(NULL,dlsch_config_pdu_1_0,0,n_RB_DLBWP,dci->frequency_domain_assignment.val); /* TIME_DOM_RESOURCE_ASSIGNMENT */ if (nr_ue_process_dci_time_dom_resource_assignment(mac,NULL,dlsch_config_pdu_1_0,dci->time_domain_assignment.val) < 0) - break; + return -1; /* dmrs symbol positions*/ dlsch_config_pdu_1_0->dlDmrsSymbPos = fill_dmrs_mask(pdsch_config, mac->scc->dmrs_TypeA_Position, @@ -2872,7 +2872,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc nr_ue_process_dci_freq_dom_resource_assignment(NULL,dlsch_config_pdu_1_1,0,n_RB_DLBWP,dci->frequency_domain_assignment.val); /* TIME_DOM_RESOURCE_ASSIGNMENT */ if (nr_ue_process_dci_time_dom_resource_assignment(mac,NULL,dlsch_config_pdu_1_1,dci->time_domain_assignment.val) < 0) - break; + return -1; /* dmrs symbol positions*/ dlsch_config_pdu_1_1->dlDmrsSymbPos = fill_dmrs_mask(pdsch_config, mac->scc->dmrs_TypeA_Position, @@ -3582,19 +3582,18 @@ void nr_ue_process_mac_pdu(module_id_t module_idP, // L: The Length field indicates the length of the corresponding MAC SDU or variable-sized MAC CE in bytes. There is one L field per MAC subheader except for subheaders corresponding to fixed-sized MAC CEs and padding. The size of the L field is indicated by the F field; // F: lenght of L is 0:8 or 1:16 bits wide // R: Reserved bit, set to zero. - while (!done && pdu_len > 0){ mac_ce_len = 0x0000; mac_subheader_len = 0x0001; // default to fixed-length subheader = 1-oct mac_sdu_len = 0x0000; rx_lcid = ((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID; + //#ifdef DEBUG_HEADER_PARSING + LOG_D(MAC, "[UE] LCID %d, PDU length %d\n", ((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID, pdu_len); + //#endif switch(rx_lcid){ // MAC CE - /*#ifdef DEBUG_HEADER_PARSING - LOG_D(MAC, "[UE] LCID %d, PDU length %d\n", ((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID, pdu_len); - #endif*/ case DL_SCH_LCID_CCCH: // MSG4 RRC Connection Setup 38.331 // varialbe length @@ -3802,7 +3801,8 @@ void nr_ue_process_mac_pdu(module_id_t module_idP, } pdu_ptr += ( mac_subheader_len + mac_ce_len + mac_sdu_len ); pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len ); - AssertFatal(pdu_len >= 0, "[MAC] nr_ue_process_mac_pdu, residual mac pdu length < 0!\n"); + if (pdu_len < 0) + LOG_E(MAC, "[MAC] nr_ue_process_mac_pdu, residual mac pdu length %d < 0!\n", pdu_len); } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 9c080d29d3..bee1d0a61d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -62,6 +62,32 @@ const uint8_t slots_per_frame[5] = {10, 20, 40, 80, 160}; uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 }; +void clear_mac_stats(gNB_MAC_INST *gNB) { + memset((void*)gNB->UE_list.mac_stats,0,MAX_MOBILES_PER_GNB*sizeof(NR_mac_stats_t)); +} + +void dump_mac_stats(gNB_MAC_INST *gNB) { + + NR_UE_list_t *UE_list = &gNB->UE_list; + NR_mac_stats_t *stats; + int lc_id; + + for (int UE_id=0;UE_idactive[UE_id] == TRUE) { + LOG_I(MAC,"UE %x\n",UE_list->rnti[UE_id]); + stats = &UE_list->mac_stats[UE_id]; + LOG_I(MAC,"dlsch_rounds %d/%d/%d/%d, dlsch_errors %d\n",stats->dlsch_rounds[0],stats->dlsch_rounds[1],stats->dlsch_rounds[2],stats->dlsch_rounds[3],stats->dlsch_errors); + LOG_I(MAC,"dlsch_total_bytes %d\n",stats->dlsch_total_bytes); + LOG_I(MAC,"ulsch_rounds %d/%d/%d/%d, ulsch_errors %d\n",stats->ulsch_rounds[0],stats->ulsch_rounds[1],stats->ulsch_rounds[2],stats->ulsch_rounds[3],stats->ulsch_errors); + LOG_I(MAC,"ulsch_total_bytes_scheduled %d, ulsch_total_bytes_received %d\n",stats->ulsch_total_bytes_scheduled,stats->ulsch_total_bytes_rx); + for (lc_id=0;lc_id<63;lc_id++) { + if (stats->lc_bytes_tx[lc_id]>0) LOG_I(MAC,"LCID %d : %d bytes TX\n",lc_id,stats->lc_bytes_tx[lc_id]); + if (stats->lc_bytes_rx[lc_id]>0) LOG_I(MAC,"LCID %d : %d bytes RX\n",lc_id,stats->lc_bytes_rx[lc_id]); + } + } + } +} + void clear_nr_nfapi_information(gNB_MAC_INST * gNB, int CC_idP, frame_t frameP, @@ -409,6 +435,11 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, pdcp_run(&ctxt); //rrc_rx_tx(&ctxt, CC_id); + /* send tick to RLC every ms */ + if ((slot & ((1 << *scc->ssbSubcarrierSpacing) - 1)) == 0) { + void nr_rlc_tick(int frame, int subframe); + nr_rlc_tick(frame, slot >> *scc->ssbSubcarrierSpacing); + } dlsch_in_slot_bitmap = &RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[UE_id].dlsch_in_slot_bitmap; // static bitmap signaling which slot in a tdd period contains dlsch ulsch_in_slot_bitmap = &RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[UE_id].ulsch_in_slot_bitmap; // static bitmap signaling which slot in a tdd period contains ulsch @@ -451,6 +482,8 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, } //END for (i = 0; i < MAX_MOBILES_PER_GNB; i++) */ + if ((slot == 0) && (frame & 127) == 0) dump_mac_stats(RC.nrmac[module_idP]); + // This schedules MIB if((slot == 0) && (frame & 7) == 0){ schedule_nr_mib(module_idP, frame, slot); @@ -472,8 +505,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, if (get_softmodem_params()->phy_test == 0) { nr_schedule_RA(module_idP, frame, slot); nr_schedule_reception_msg3(module_idP, 0, frame, slot); - } - else + } else UE_list->fiveG_connected[UE_id] = true; if (UE_list->fiveG_connected[UE_id]) { diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 705e1e2815..4c17ee3a0f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -437,7 +437,10 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t NR_UE_list_t *UE_list = &mac->UE_list; int UE_id = 0; - AssertFatal(ra->state != RA_IDLE, "RA is not active for RA %X\n", ra->rnti); + if (ra->state == RA_IDLE) { + LOG_W(MAC,"RA is not active for RA %X. skipping msg3 scheduling\n", ra->rnti); + return; + } LOG_D(MAC, "[gNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA is active, Msg3 in (%d,%d)\n", module_idP, frameP, slotP, CC_id, ra->Msg3_frame, ra->Msg3_slot); @@ -540,7 +543,7 @@ void nr_generate_Msg2(module_id_t module_idP, sub_frame_t slotP){ int UE_id = 0, dci_formats[2], rnti_types[2], mcsIndex; - int startSymbolAndLength = 0, StartSymbolIndex = -1, NrOfSymbols = 14, StartSymbolIndex_tmp, NrOfSymbols_tmp, x_Overhead, time_domain_assignment; + int startSymbolAndLength = 0, StartSymbolIndex = -1, NrOfSymbols = 14, StartSymbolIndex_tmp, NrOfSymbols_tmp, x_Overhead, time_domain_assignment = 0; gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = &nr_mac->common_channels[0]; NR_RA_t *ra = &cc->ra[0]; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 82721f7398..f4b06c63f2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -38,6 +38,7 @@ #include "NR_MAC_gNB/nr_mac_gNB.h" #include "NR_MAC_COMMON/nr_mac_extern.h" #include "LAYER2/MAC/mac.h" +#include "LAYER2/NR_MAC_gNB/mac_proto.h" /*NFAPI*/ #include "nfapi_nr_interface.h" @@ -76,6 +77,8 @@ int nr_generate_dlsch_pdu(module_id_t module_idP, //NR_CellGroupConfig_t *config = UE_list->secondaryCellGroup[UE_id]; ue_sched_ctl = &(UE_list->UE_sched_ctrl[UE_id]); + NR_mac_stats_t *mac_stats = &(UE_list->mac_stats[UE_id]); + // 1) Compute MAC CE and related subheaders // DRX command subheader (MAC CE size 0) @@ -112,6 +115,8 @@ int nr_generate_dlsch_pdu(module_id_t module_idP, memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size); ce_ptr += mac_ce_size; mac_pdu_ptr += (unsigned char) mac_ce_size; + + } // Contention resolution fixed subheader and MAC CE @@ -324,6 +329,8 @@ int nr_generate_dlsch_pdu(module_id_t module_idP, memcpy((void *) mac_pdu_ptr, (void *) dlsch_buffer_ptr, sdu_lengths[i]); dlsch_buffer_ptr += sdu_lengths[i]; mac_pdu_ptr += sdu_lengths[i]; + + mac_stats->lc_bytes_tx[sdu_lcids[i]] += sdu_lengths[i]; } // 4) Compute final offset for padding @@ -341,6 +348,95 @@ int nr_generate_dlsch_pdu(module_id_t module_idP, return offset; } +void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats, int target_snrx10) { + // TODO + int max_harq_rounds = 4; // TODO define macro + int num_ucis = UL_info->uci_ind.num_ucis; + nfapi_nr_uci_t *uci_list = UL_info->uci_ind.uci_list; + + for (int i = 0; i < num_ucis; i++) { + switch (uci_list[i].pdu_type) { + case NFAPI_NR_UCI_PUSCH_PDU_TYPE: break; + + case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: { + nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &uci_list[i].pucch_pdu_format_0_1; + // handle harq + int harq_idx_s = 0; + // tpc (power control) + sched_ctrl->tpc1 = nr_get_tpc(target_snrx10,uci_pdu->ul_cqi,30); + // iterate over received harq bits + for (int harq_bit = 0; harq_bit < uci_pdu->harq->num_harq; harq_bit++) { + // search for the right harq process + for (int harq_idx = harq_idx_s; harq_idx < NR_MAX_NB_HARQ_PROCESSES; harq_idx++) { + // if the gNB received ack with a good confidence + if ((UL_info->slot-1) == sched_ctrl->harq_processes[harq_idx].feedback_slot) { + if ((uci_pdu->harq->harq_list[harq_bit].harq_value == 1) && + (uci_pdu->harq->harq_confidence_level == 0)) { + // toggle NDI and reset round + sched_ctrl->harq_processes[harq_idx].ndi ^= 1; + sched_ctrl->harq_processes[harq_idx].round = 0; + } + else + sched_ctrl->harq_processes[harq_idx].round++; + sched_ctrl->harq_processes[harq_idx].is_waiting = 0; + harq_idx_s = harq_idx + 1; + // if the max harq rounds was reached + if (sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds) { + sched_ctrl->harq_processes[harq_idx].ndi ^= 1; + sched_ctrl->harq_processes[harq_idx].round = 0; + stats->dlsch_errors++; + } + break; + } + // if feedback slot processing is aborted + else if (((UL_info->slot-1) > sched_ctrl->harq_processes[harq_idx].feedback_slot) && + (sched_ctrl->harq_processes[harq_idx].is_waiting)) { + sched_ctrl->harq_processes[harq_idx].round++; + if (sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds) { + sched_ctrl->harq_processes[harq_idx].ndi ^= 1; + sched_ctrl->harq_processes[harq_idx].round = 0; + } + sched_ctrl->harq_processes[harq_idx].is_waiting = 0; + } + } + } + break; + } + case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: { + nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu = &uci_list[i].pucch_pdu_format_2_3_4; + int harq_idx_s = 0; + int acknack; + // tpc (power control) + sched_ctrl->tpc1 = nr_get_tpc(target_snrx10,uci_pdu->ul_cqi,30); + // iterate over received harq bits + for (int harq_bit = 0; harq_bit < uci_pdu->harq.harq_bit_len; harq_bit++) { + acknack = ((uci_pdu->harq.harq_payload[harq_bit>>3])>>harq_bit)&0x01; + for (int harq_idx = harq_idx_s; harq_idx < NR_MAX_NB_HARQ_PROCESSES-1; harq_idx++) { + // if the gNB received ack with a good confidence or if the max harq rounds was reached + if ((UL_info->slot-1) == sched_ctrl->harq_processes[harq_idx].feedback_slot) { + // TODO add some confidence level for when there is no CRC + if (((uci_pdu->harq.harq_crc != 1) && acknack) || + (sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds)) { + // toggle NDI and reset round + sched_ctrl->harq_processes[harq_idx].ndi ^= 1; + sched_ctrl->harq_processes[harq_idx].round = 0; + } + else + sched_ctrl->harq_processes[harq_idx].round++; + sched_ctrl->harq_processes[harq_idx].is_waiting = 0; + harq_idx_s = harq_idx + 1; + break; + } + } + } + break; + } + } + } + + UL_info->uci_ind.num_ucis = 0; +} + /* functionalities of this function have been moved to nr_schedule_uss_dlsch_phytest */ void nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) { } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 69bf41223c..35ebeccbe7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -320,7 +320,7 @@ int configure_fapi_dl_pdu(int Mod_idP, pdsch_pdu_rel15->nrOfLayers = 1; pdsch_pdu_rel15->transmissionScheme = 0; pdsch_pdu_rel15->refPoint = 0; // Point A - + UE_list->mac_stats[UE_id].dlsch_rounds[UE_list->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round]++; pdsch_pdu_rel15->dmrsConfigType = bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1; pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId; pdsch_pdu_rel15->SCID = 0; @@ -454,6 +454,9 @@ int configure_fapi_dl_pdu(int Mod_idP, // Hardcode it for now TBS = dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15.TBSize[0]; + if (UE_list->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round==0) + UE_list->mac_stats[UE_id].dlsch_total_bytes += TBS; + LOG_D(MAC, "DLSCH PDU: start PRB %d n_PRB %d startSymbolAndLength %d start symbol %d nb_symbols %d nb_layers %d nb_codewords %d mcs %d TBS: %d\n", pdsch_pdu_rel15->rbStart, pdsch_pdu_rel15->rbSize, @@ -751,14 +754,14 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, } #endif } else { - #if defined(ENABLE_MAC_PAYLOAD_DEBUG) +#if defined(ENABLE_MAC_PAYLOAD_DEBUG) if (frameP%100 == 0){ LOG_I(MAC, "Printing first 10 payload bytes at the gNB side, Frame: %d, slot: %d, TBS size: %d \n", frameP, slotP, TBS_bytes); for(int i = 0; i < 10; i++) { - LOG_I(MAC, "%x. ", ((uint8_t *)gNB_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0])[i]); //LOG_I(MAC, "%x. ", mac_payload[i]); + LOG_I(MAC, "byte %d : %x\n", i,((uint8_t *)gNB_mac->UE_list.DLSCH_pdu[0][0].payload[0])[i]); //LOG_I(MAC, "%x. ", mac_payload[i]); } } - #endif +#endif } } else { // There is no data from RLC or MAC header, so don't schedule @@ -1031,6 +1034,8 @@ void schedule_fapi_ul_pdu(int Mod_idP, 0, pusch_pdu->nrOfLayers)>>3; + UE_list->mac_stats[UE_id].ulsch_rounds[cur_harq->round]++; + if (cur_harq->round == 0) UE_list->mac_stats[UE_id].ulsch_total_bytes_scheduled+=pusch_pdu->pusch_data.tb_size; pusch_pdu->pusch_data.num_cb = 0; //CBG not supported //pusch_pdu->pusch_data.cb_present_and_position; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 16441d5096..6f6782fa1a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -1659,9 +1659,9 @@ void get_pdsch_to_harq_feedback(int Mod_idP, } -uint16_t get_csi_bitlen(int Mod_idP, - int UE_id, - uint8_t csi_report_id) { +uint16_t nr_get_csi_bitlen(int Mod_idP, + int UE_id, + uint8_t csi_report_id) { uint16_t csi_bitlen =0; NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list; @@ -1804,7 +1804,7 @@ void nr_csi_meas_reporting(int Mod_idP, } } } - curr_pucch->csi_bits += get_csi_bitlen(Mod_idP,UE_id,csi_report_id); // TODO function to compute CSI meas report bit size + curr_pucch->csi_bits += nr_get_csi_bitlen(Mod_idP,UE_id,csi_report_id); // TODO function to compute CSI meas report bit size curr_pucch->frame = frame; curr_pucch->ul_slot = sched_slot; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index c01c119c14..d66ec9c52f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -211,7 +211,8 @@ void nr_process_mac_pdu( } LOG_D(MAC, "[UE %d] Frame %d : ULSCH -> UL-DTCH %d (gNB %d, %d bytes)\n", module_idP, frameP, rx_lcid, module_idP, mac_sdu_len); - + int UE_id = find_nr_UE_id(module_idP, rnti); + RC.nrmac[module_idP]->UE_list.mac_stats[UE_id].lc_bytes_rx[rx_lcid] += mac_sdu_len; #if defined(ENABLE_MAC_PAYLOAD_DEBUG) LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP); @@ -264,6 +265,39 @@ void nr_process_mac_pdu( } } +void handle_nr_ul_harq(uint16_t slot, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats, nfapi_nr_crc_t crc_pdu) { + + int max_harq_rounds = 4; // TODO define macro + uint8_t hrq_id = crc_pdu.harq_id; + NR_UE_ul_harq_t *cur_harq = &sched_ctrl->ul_harq_processes[hrq_id]; + if (cur_harq->state==ACTIVE_SCHED) { + if (!crc_pdu.tb_crc_status) { + cur_harq->ndi ^= 1; + cur_harq->round = 0; + cur_harq->state = INACTIVE; // passed -> make inactive. can be used by scheduder for next grant +#ifdef UL_HARQ_PRINT + printf("[HARQ HANDLER] Ulharq id %d crc passed, freeing it for scheduler\n",hrq_id); +#endif + } else { + cur_harq->round++; + cur_harq->state = ACTIVE_NOT_SCHED; +#ifdef UL_HARQ_PRINT + printf("[HARQ HANDLER] Ulharq id %d crc failed, requesting retransmission\n",hrq_id); +#endif + } + + if (!(cur_harq->roundndi ^= 1; + cur_harq->state = INACTIVE; // failed after 4 rounds -> make inactive + cur_harq->round = 0; + LOG_D(MAC,"[HARQ HANDLER] RNTI %x: Ulharq id %d crc failed in all round, freeing it for scheduler\n",crc_pdu.rnti,hrq_id); + stats->ulsch_errors++; + } + return; + } else + LOG_E(MAC,"Incorrect ULSCH HARQ process %d or invalid state %d\n",hrq_id,cur_harq->state); +} + /* * When data are received on PHY and transmitted to MAC */ @@ -291,6 +325,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, if (UE_id != -1) { UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]); + UE_list->mac_stats[UE_id].ulsch_total_bytes_rx += sdu_lenP; LOG_D(MAC, "[gNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu from PHY (rnti %x, UE_id %d) ul_cqi %d\n", gnb_mod_idP, harq_pid, @@ -327,6 +362,9 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, LOG_D(MAC, "Received PDU at MAC gNB \n"); nr_process_mac_pdu(gnb_mod_idP, current_rnti, CC_idP, frameP, sduP, sdu_lenP); } + else { + + } } else { // random access pusch with TC-RNTI diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 5abc268dff..e101cf77a7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -361,4 +361,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, const uint8_t ul_cqi, const uint16_t rssi); +void handle_nr_ul_harq(uint16_t slot, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats, nfapi_nr_crc_t crc_pdu); + +void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats, int target_snrx10); #endif /*__LAYER2_NR_MAC_PROTO_H__*/ diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index c5fee8a8f4..2348bac431 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -326,6 +326,19 @@ typedef struct NR_preamble_ue { uint8_t *preamble_list; } NR_preamble_ue; +typedef struct { + + int lc_bytes_tx[64]; + int lc_bytes_rx[64]; + int dlsch_rounds[8]; + int dlsch_errors; + int dlsch_total_bytes; + int ulsch_rounds[8]; + int ulsch_errors; + int ulsch_total_bytes_scheduled; + int ulsch_total_bytes_rx; +} NR_mac_stats_t; + /*! \brief UE list used by gNB to order UEs/CC for scheduling*/ #define MAX_CSI_REPORTCONFIG 48 typedef struct { @@ -333,6 +346,7 @@ typedef struct { /// scheduling control info nr_csi_report_t csi_report_template[MAX_MOBILES_PER_GNB][MAX_CSI_REPORTCONFIG]; NR_UE_sched_ctrl_t UE_sched_ctrl[MAX_MOBILES_PER_GNB]; + NR_mac_stats_t mac_stats[MAX_MOBILES_PER_GNB]; int next[MAX_MOBILES_PER_GNB]; int head; int next_ul[MAX_MOBILES_PER_GNB]; diff --git a/openair2/LAYER2/nr_rlc/asn1_utils.h b/openair2/LAYER2/nr_rlc/asn1_utils.h index cf6309e330..6f010b02da 100644 --- a/openair2/LAYER2/nr_rlc/asn1_utils.h +++ b/openair2/LAYER2/nr_rlc/asn1_utils.h @@ -19,8 +19,8 @@ * contact@openairinterface.org */ -#ifndef _ASN1_UTILS_H_ -#define _ASN1_UTILS_H_ +#ifndef _OPENAIR2_LAYER2_NR_RLC_ASN1_UTILS_H_ +#define _OPENAIR2_LAYER2_NR_RLC_ASN1_UTILS_H_ int decode_t_reassembly(int v); int decode_t_status_prohibit(int v); @@ -31,4 +31,4 @@ int decode_max_retx_threshold(int v); int decode_sn_field_length_um(int v); int decode_sn_field_length_am(int v); -#endif /* _ASN1_UTILS_H_ */ +#endif /* _OPENAIR2_LAYER2_NR_RLC_ASN1_UTILS_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 919cf1a46a..5048dd245e 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -158,14 +158,6 @@ mac_rlc_status_resp_t mac_rlc_status_ind( mac_rlc_status_resp_t ret; nr_rlc_entity_t *rb; - /* TODO: handle time a bit more properly */ - if (nr_rlc_current_time_last_frame != frameP || - nr_rlc_current_time_last_subframe != subframeP) { - nr_rlc_current_time++; - nr_rlc_current_time_last_frame = frameP; - nr_rlc_current_time_last_subframe = subframeP; - } - nr_rlc_manager_lock(nr_rlc_ue_manager); ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rntiP); @@ -921,3 +913,10 @@ rlc_op_status_t rrc_rlc_remove_ue (const protocol_ctxt_t* const x) return RLC_OP_STATUS_OK; } + +void nr_rlc_tick(int frame, int subframe) +{ + if (frame != nr_rlc_current_time_last_frame || + subframe != nr_rlc_current_time_last_subframe) + nr_rlc_current_time++; +} diff --git a/openair2/LAYER2/nr_rlc/tests/LOG/log.h b/openair2/LAYER2/nr_rlc/tests/LOG/log.h index 5c9fcd643c..8ebc7e1909 100644 --- a/openair2/LAYER2/nr_rlc/tests/LOG/log.h +++ b/openair2/LAYER2/nr_rlc/tests/LOG/log.h @@ -1,5 +1,5 @@ -#ifndef _LOG_H_ -#define _LOG_H_ +#ifndef _NR_RLC_TESTS_LOG_H_ +#define _NR_RLC_TESTS_LOG_H_ #include @@ -7,4 +7,4 @@ #define LOG_D(x, ...) printf(__VA_ARGS__) #define LOG_W(x, ...) printf(__VA_ARGS__) -#endif /* _LOG_H_ */ +#endif /* _NR_RLC_TESTS_LOG_H_ */ diff --git a/openair2/LAYER2/rlc_v2/asn1_utils.h b/openair2/LAYER2/rlc_v2/asn1_utils.h index 61394c9c69..fadaf16f0a 100644 --- a/openair2/LAYER2/rlc_v2/asn1_utils.h +++ b/openair2/LAYER2/rlc_v2/asn1_utils.h @@ -19,8 +19,8 @@ * contact@openairinterface.org */ -#ifndef _ASN1_UTILS_H_ -#define _ASN1_UTILS_H_ +#ifndef _OPENAIR2_LAYER2_RLC_V2_ASN1_UTILS_H_ +#define _OPENAIR2_LAYER2_RLC_V2_ASN1_UTILS_H_ int decode_t_reordering(int v); int decode_t_status_prohibit(int v); @@ -30,4 +30,4 @@ int decode_poll_byte(int v); int decode_max_retx_threshold(int v); int decode_sn_field_length(int v); -#endif /* _ASN1_UTILS_H_ */ +#endif /* _OPENAIR2_LAYER2_RLC_V2_ASN1_UTILS_H_ */ diff --git a/openair2/LAYER2/rlc_v2/tests/LOG/log.h b/openair2/LAYER2/rlc_v2/tests/LOG/log.h index 5c9fcd643c..89d85090b1 100644 --- a/openair2/LAYER2/rlc_v2/tests/LOG/log.h +++ b/openair2/LAYER2/rlc_v2/tests/LOG/log.h @@ -1,5 +1,5 @@ -#ifndef _LOG_H_ -#define _LOG_H_ +#ifndef _RLC_V2_TESTS_LOG_H_ +#define _RLC_V2_TESTS_LOG_H_ #include @@ -7,4 +7,4 @@ #define LOG_D(x, ...) printf(__VA_ARGS__) #define LOG_W(x, ...) printf(__VA_ARGS__) -#endif /* _LOG_H_ */ +#endif /* _RLC_V2_TESTS_LOG_H_ */ diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index 6c38ce03c3..cc04493400 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -78,127 +78,9 @@ void handle_nr_rach(NR_UL_IND_t *UL_info) { } -void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, int target_snrx10) { - // TODO - int max_harq_rounds = 4; // TODO define macro - int num_ucis = UL_info->uci_ind.num_ucis; - nfapi_nr_uci_t *uci_list = UL_info->uci_ind.uci_list; - for (int i = 0; i < num_ucis; i++) { - switch (uci_list[i].pdu_type) { - case NFAPI_NR_UCI_PUSCH_PDU_TYPE: - break; - case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: { - nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &uci_list[i].pucch_pdu_format_0_1; - // handle harq - int harq_idx_s = 0; - // tpc (power control) - sched_ctrl->tpc1 = nr_get_tpc(target_snrx10,uci_pdu->ul_cqi,30); - // iterate over received harq bits - for (int harq_bit = 0; harq_bit < uci_pdu->harq->num_harq; harq_bit++) { - // search for the right harq process - for (int harq_idx = harq_idx_s; harq_idx < NR_MAX_NB_HARQ_PROCESSES-1; harq_idx++) { - // if the gNB received ack with a good confidence or if the max harq rounds was reached - if ((UL_info->slot-1) == sched_ctrl->harq_processes[harq_idx].feedback_slot) { - if (((uci_pdu->harq->harq_list[harq_bit].harq_value == 1) && - (uci_pdu->harq->harq_confidence_level == 0)) || - (sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds)) { - // toggle NDI and reset round - sched_ctrl->harq_processes[harq_idx].ndi ^= 1; - sched_ctrl->harq_processes[harq_idx].round = 0; - } - else - sched_ctrl->harq_processes[harq_idx].round++; - sched_ctrl->harq_processes[harq_idx].is_waiting = 0; - harq_idx_s = harq_idx + 1; - break; - } - // if gNB fails to receive a ACK/NACK - else if (((UL_info->slot-1) > sched_ctrl->harq_processes[harq_idx].feedback_slot) && - (sched_ctrl->harq_processes[harq_idx].is_waiting)) { - sched_ctrl->harq_processes[harq_idx].round++; - if (sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds) { - sched_ctrl->harq_processes[harq_idx].ndi ^= 1; - sched_ctrl->harq_processes[harq_idx].round = 0; - } - sched_ctrl->harq_processes[harq_idx].is_waiting = 0; - } - } - } - break; - } - case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: { - nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu = &uci_list[i].pucch_pdu_format_2_3_4; - int harq_idx_s = 0; - int acknack; - // tpc (power control) - sched_ctrl->tpc1 = nr_get_tpc(target_snrx10,uci_pdu->ul_cqi,30); - // iterate over received harq bits - for (int harq_bit = 0; harq_bit < uci_pdu->harq.harq_bit_len; harq_bit++) { - acknack = ((uci_pdu->harq.harq_payload[harq_bit>>3])>>harq_bit)&0x01; - for (int harq_idx = harq_idx_s; harq_idx < NR_MAX_NB_HARQ_PROCESSES-1; harq_idx++) { - // if the gNB received ack with a good confidence or if the max harq rounds was reached - if ((UL_info->slot-1) == sched_ctrl->harq_processes[harq_idx].feedback_slot) { - // TODO add some confidence level for when there is no CRC - if (((uci_pdu->harq.harq_crc != 1) && acknack) || - (sched_ctrl->harq_processes[harq_idx].round == max_harq_rounds)) { - // toggle NDI and reset round - sched_ctrl->harq_processes[harq_idx].ndi ^= 1; - sched_ctrl->harq_processes[harq_idx].round = 0; - } - else - sched_ctrl->harq_processes[harq_idx].round++; - sched_ctrl->harq_processes[harq_idx].is_waiting = 0; - harq_idx_s = harq_idx + 1; - break; - } - } - } - break; - } - } - } +void handle_nr_ulsch(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_stats_t *stats) { - UL_info->uci_ind.num_ucis = 0; -} - -void handle_nr_ul_harq(uint16_t slot, NR_UE_sched_ctrl_t *sched_ctrl, uint8_t crc_status) { - - int max_harq_rounds = 4; // TODO define macro - for (uint8_t hrq_id = 0; hrq_id < NR_MAX_NB_HARQ_PROCESSES; hrq_id++) { - NR_UE_ul_harq_t *cur_harq = &sched_ctrl->ul_harq_processes[hrq_id]; - if ((cur_harq->last_tx_slot == slot-1) && cur_harq->state==ACTIVE_SCHED) { - if (!crc_status) { - cur_harq->ndi ^= 1; - cur_harq->round = 0; - cur_harq->state = INACTIVE; // passed -> make inactive. can be used by scheduder for next grant -#ifdef UL_HARQ_PRINT - printf("[HARQ HANDLER] Ulharq id %d crc passed, freeing it for scheduler\n",hrq_id); -#endif - } else { - cur_harq->round++; - cur_harq->state = ACTIVE_NOT_SCHED; -#ifdef UL_HARQ_PRINT - printf("[HARQ HANDLER] Ulharq id %d crc failed, requesting retransmission\n",hrq_id); -#endif - } - - if (!(cur_harq->roundndi ^= 1; - cur_harq->state = INACTIVE; // failed after 4 rounds -> make inactive - cur_harq->round = 0; -#ifdef UL_HARQ_PRINT - printf("[HARQ HANDLER] Ulharq id %d crc failed in all round, freeing it for scheduler\n",hrq_id); -#endif - } - return; - } - } - -} - - -void handle_nr_ulsch(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl) { if(nfapi_mode == 1) { if (UL_info->crc_ind.number_crcs>0) { //LOG_D(PHY,"UL_info->crc_ind.crc_indication_body.number_of_crcs:%d CRC_IND:SFN/SF:%d\n", UL_info->crc_ind.crc_indication_body.number_of_crcs, NFAPI_SFNSF2DEC(UL_info->crc_ind.sfn_sf)); @@ -225,7 +107,7 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl) { UL_info->rx_ind.pdu_list[i].rnti) { LOG_D(PHY, "UL_info->crc_ind.crc_indication_body.crc_pdu_list[%d].crc_indication_rel8.crc_flag:%d\n", j, UL_info->crc_ind.crc_list[j].tb_crc_status); - handle_nr_ul_harq(UL_info->slot, sched_ctrl, UL_info->crc_ind.crc_list[j].tb_crc_status); + handle_nr_ul_harq(UL_info->slot, sched_ctrl, stats, UL_info->crc_ind.crc_list[j]); if (UL_info->crc_ind.crc_list[j].tb_crc_status == 1) { // CRC error indication LOG_D(MAC,"Frame %d, Slot %d Calling rx_sdu (CRC error) \n",UL_info->frame,UL_info->slot); @@ -279,7 +161,6 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) { NR_Sched_Rsp_t *sched_info = &Sched_INFO[module_id][CC_id]; NR_IF_Module_t *ifi = if_inst[module_id]; gNB_MAC_INST *mac = RC.nrmac[module_id]; - LOG_D(PHY,"SFN/SF:%d%d module_id:%d CC_id:%d UL_info[rach_pdus:%d rx_ind:%d crcs:%d]\n", UL_info->frame,UL_info->slot, module_id,CC_id, UL_info->rach_ind.number_of_pdus, @@ -300,10 +181,11 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) { // clear DL/UL info for new scheduling round clear_nr_nfapi_information(mac,CC_id,UL_info->frame,UL_info->slot); handle_nr_rach(UL_info); - handle_nr_uci(UL_info,&mac->UE_list.UE_sched_ctrl[0],mac->pucch_target_snrx10); + + handle_nr_uci(UL_info,&mac->UE_list.UE_sched_ctrl[0],&mac->UE_list.mac_stats[0],mac->pucch_target_snrx10); // clear HI prior to handling ULSCH mac->UL_dci_req[CC_id].numPdus = 0; - handle_nr_ulsch(UL_info, &mac->UE_list.UE_sched_ctrl[0]); + handle_nr_ulsch(UL_info, &mac->UE_list.UE_sched_ctrl[0],&mac->UE_list.mac_stats[0]); if (nfapi_mode != 1) { if (ifi->CC_mask == ((1<dci_ind->number_of_dcis; ++i){ LOG_D(MAC,">>>NR_IF_Module i=%d, dl_info->dci_ind->number_of_dcis=%d\n",i,dl_info->dci_ind->number_of_dcis); - ret_mask |= (handle_dci(dl_info->module_id, + int8_t ret = handle_dci(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index, - dl_info->dci_ind->dci_list+i)<< FAPI_NR_DCI_IND); + dl_info->dci_ind->dci_list+i); - AssertFatal( nr_ue_if_module_inst[module_id] != NULL, "IF module is void!\n" ); - nr_ue_if_module_inst[module_id]->scheduled_response(&mac->scheduled_response); + ret_mask |= (ret << FAPI_NR_DCI_IND); + if (ret >= 0) { + AssertFatal( nr_ue_if_module_inst[module_id] != NULL, "IF module is void!\n" ); + nr_ue_if_module_inst[module_id]->scheduled_response(&mac->scheduled_response); + } } } diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index b6062df2c4..a6775bbf8a 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -155,7 +155,6 @@ init_SI( LOG_D(RRC,"%s()\n\n\n\n",__FUNCTION__); if(configuration->radioresourceconfig[CC_id].mbms_dedicated_serving_cell == TRUE) { - LOG_I(RRC, "Configuring MIB FeMBMS (N_RB_DL %d)\n", (int)configuration->N_RB_DL[CC_id]); RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MIB_FeMBMS = (uint8_t *) malloc16(4); @@ -500,13 +499,17 @@ init_SI( RC.rrc[ctxt_pP->module_id]->carrier[CC_id].FeMBMS_flag, (carrier->sib1_MBMS==NULL?(LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL:(LTE_BCCH_DL_SCH_Message_MBMS_t *)carrier->sib1_MBMS),//(LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, (LTE_SchedulingInfo_MBMS_r14_t *) NULL, - (carrier->sib1_MBMS==NULL?(struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL:(struct LTE_NonMBSFN_SubframeConfig_r14 *)carrier->sib1_MBMS->nonMBSFN_SubframeConfig_r14),//(struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, - (carrier->sib1_MBMS==NULL?(LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL:(LTE_SystemInformationBlockType1_MBMS_r14_t *)carrier->sib1_MBMS->systemInformationBlockType13_r14),//(LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, - (carrier->sib1_MBMS==NULL?(LTE_MBSFN_AreaInfoList_r9_t *) NULL:(LTE_MBSFN_AreaInfoList_r9_t *)&carrier->sib1_MBMS->systemInformationBlockType13_r14->mbsfn_AreaInfoList_r9)//(LTE_MBSFN_AreaInfoList_r9_t *) NULL - - ,(LTE_MBSFNAreaConfiguration_r9_t*) NULL - - ); + (carrier->sib1_MBMS==NULL + ? (struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL + : (struct LTE_NonMBSFN_SubframeConfig_r14 *)carrier->sib1_MBMS->nonMBSFN_SubframeConfig_r14),//(struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, + (carrier->sib1_MBMS==NULL + ? (LTE_SystemInformationBlockType1_MBMS_r14_t *)NULL + : (LTE_SystemInformationBlockType1_MBMS_r14_t *)carrier->sib1_MBMS->systemInformationBlockType13_r14),//(LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, + (carrier->sib1_MBMS==NULL + ? (LTE_MBSFN_AreaInfoList_r9_t *)NULL + : (LTE_MBSFN_AreaInfoList_r9_t *)&carrier->sib1_MBMS->systemInformationBlockType13_r14->mbsfn_AreaInfoList_r9),//(LTE_MBSFN_AreaInfoList_r9_t *) NULL, + (LTE_MBSFNAreaConfiguration_r9_t *)NULL + ); } /* set flag to indicate that cell information is configured. This is required @@ -590,7 +593,7 @@ init_MCCH( (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, - (LTE_MBSFNAreaConfiguration_r9_t*) NULL + (LTE_MBSFNAreaConfiguration_r9_t *) NULL ); } @@ -1040,59 +1043,59 @@ void release_UE_in_freeList(module_id_t mod_id) { for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { eNB_PHY = RC.eNB[mod_id][CC_id]; + int id; + // clean ULSCH entries for rnti + id = find_ulsch(rnti,eNB_PHY,SEARCH_EXIST); - int id; - - // clean ULSCH entries for rnti - id = find_ulsch(rnti,eNB_PHY,SEARCH_EXIST); if (id>=0) clean_eNb_ulsch(eNB_PHY->ulsch[id]); - // clean DLSCH entries for rnti - id = find_dlsch(rnti,eNB_PHY,SEARCH_EXIST); + // clean DLSCH entries for rnti + id = find_dlsch(rnti,eNB_PHY,SEARCH_EXIST); + if (id>=0) clean_eNb_dlsch(eNB_PHY->dlsch[id][0]); - // clean UCI entries for rnti + // clean UCI entries for rnti for (i=0; iuci_vars[i].rnti == rnti) { LOG_I(MAC, "clean eNb uci_vars[%d] UE %x \n",i, rnti); memset(&eNB_PHY->uci_vars[i],0,sizeof(LTE_eNB_UCI)); } } - - /* - for (i=0; iulsch[i]; - if((ulsch != NULL) && (ulsch->rnti == rnti)) { - void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch); - LOG_I(RRC, "clean_eNb_ulsch ulsch[%d] UE %x\n", i, rnti); - clean_eNb_ulsch(ulsch); - } + /* + for (i=0; iulsch[i]; - dlsch = eNB_PHY->dlsch[i][0]; + if((ulsch != NULL) && (ulsch->rnti == rnti)) { + void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch); + LOG_I(RRC, "clean_eNb_ulsch ulsch[%d] UE %x\n", i, rnti); + clean_eNb_ulsch(ulsch); + } - if((dlsch != NULL) && (dlsch->rnti == rnti)) { - void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch); - LOG_I(RRC, "clean_eNb_dlsch dlsch[%d] UE %x \n", i, rnti); - clean_eNb_dlsch(dlsch); - } - } + dlsch = eNB_PHY->dlsch[i][0]; - ulsch = eNB_PHY->ulsch[i]; + if((dlsch != NULL) && (dlsch->rnti == rnti)) { + void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch); + LOG_I(RRC, "clean_eNb_dlsch dlsch[%d] UE %x \n", i, rnti); + clean_eNb_dlsch(dlsch); + } + } - if((ulsch != NULL) && (ulsch->rnti == rnti)) { - void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch); - LOG_I(RRC, "clean_eNb_ulsch ulsch[%d] UE %x\n", i, rnti); - clean_eNb_ulsch(ulsch); - } + ulsch = eNB_PHY->ulsch[i]; - for (i=0; iuci_vars[i].rnti == rnti) { - LOG_I(MAC, "clean eNb uci_vars[%d] UE %x \n",i, rnti); - memset(&eNB_PHY->uci_vars[i],0,sizeof(LTE_eNB_UCI)); - } - } - */ + if((ulsch != NULL) && (ulsch->rnti == rnti)) { + void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch); + LOG_I(RRC, "clean_eNb_ulsch ulsch[%d] UE %x\n", i, rnti); + clean_eNb_ulsch(ulsch); + } + + for (i=0; iuci_vars[i].rnti == rnti) { + LOG_I(MAC, "clean eNb uci_vars[%d] UE %x \n",i, rnti); + memset(&eNB_PHY->uci_vars[i],0,sizeof(LTE_eNB_UCI)); + } + } + */ if (flexran_agent_get_rrc_xface(mod_id)) { flexran_agent_get_rrc_xface(mod_id)->flexran_agent_notify_ue_state_change( @@ -1488,7 +1491,7 @@ rrc_eNB_generate_RRCConnectionReestablishment( (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, - (LTE_MBSFNAreaConfiguration_r9_t*) NULL + (LTE_MBSFNAreaConfiguration_r9_t *) NULL ); break; } @@ -2190,7 +2193,6 @@ rrc_eNB_generate_RRCConnectionRelease( uint8_t buffer[RRC_BUF_SIZE]; uint16_t size = 0; int release_num; - memset(buffer, 0, RRC_BUF_SIZE); T(T_ENB_RRC_CONNECTION_RELEASE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); @@ -3281,7 +3283,8 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t MeasObj2->measObjectId = 2; MeasObj2->measObject.present = LTE_MeasObjectToAddMod__measObject_PR_measObjectNR_r15; - MeasObj2->measObject.choice.measObjectNR_r15.carrierFreq_r15 =641272; //634000; //(634000 = 3.51GHz) (640000 = 3.6GHz) (641272 = 3619.08MHz = 3600 + 30/1000*106*12/2) (642256 is for 3.6GHz and absoluteFrequencySSB = 642016) + MeasObj2->measObject.choice.measObjectNR_r15.carrierFreq_r15 = 641272; + //634000; //(634000 = 3.51GHz) (640000 = 3.6GHz) (641272 = 3619.08MHz = 3600 + 30/1000*106*12/2) (642256 is for 3.6GHz and absoluteFrequencySSB = 642016) MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.measTimingConfig_r15.periodicityAndOffset_r15.present = LTE_MTC_SSB_NR_r15__periodicityAndOffset_r15_PR_sf20_r15; MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.measTimingConfig_r15.periodicityAndOffset_r15.choice.sf20_r15 = 0; MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.measTimingConfig_r15.ssb_Duration_r15 = LTE_MTC_SSB_NR_r15__ssb_Duration_r15_sf4; @@ -3593,20 +3596,19 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t size, buffer, PDCP_TRANSMISSION_MODE_CONTROL); - /* Refresh SRBs/DRBs */ rrc_pdcp_config_asn1_req(ctxt_pP, - *SRB_configList2, // NULL, - *DRB_configList, - NULL, - 0xff, // already configured during the securitymodecommand - NULL, - NULL, - NULL + *SRB_configList2, // NULL, + *DRB_configList, + NULL, + 0xff, // already configured during the securitymodecommand + NULL, + NULL, + NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , (LTE_PMCH_InfoList_r9_t *) NULL + , (LTE_PMCH_InfoList_r9_t *) NULL #endif - , NULL); + , NULL); /* Refresh SRBs/DRBs */ if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { @@ -3619,7 +3621,7 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t 0, 0 #endif - ); + ); } free(Sparams); @@ -4666,7 +4668,7 @@ rrc_eNB_process_MeasurementReport( for (int e_rab=0; e_rab < X2AP_ENDC_SGNB_ADDITION_REQ(msg).nb_e_rabs_tobeadded; e_rab++) { X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[e_rab].e_rab_id = ue_context_pP->ue_context.e_rab[e_rab].param.e_rab_id; X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[e_rab].gtp_teid = ue_context_pP->ue_context.e_rab[e_rab].param.gtp_teid; - X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[e_rab].drb_ID = ue_context_pP->ue_context.DRB_configList->list.array[e_rab]->drb_Identity; + X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[e_rab].drb_ID = ue_context_pP->ue_context.DRB_configList->list.array[e_rab]->drb_Identity; memcpy(&X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[e_rab].sgw_addr, &ue_context_pP->ue_context.e_rab[e_rab].param.sgw_addr, sizeof(transport_layer_addr_t)); @@ -5789,7 +5791,7 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, - (LTE_MBSFNAreaConfiguration_r9_t*) NULL + (LTE_MBSFNAreaConfiguration_r9_t *) NULL ); // Configure target eNB SRB2 /// SRB2 @@ -6341,20 +6343,19 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct ue_context_pP->ue_context.rnti, rrc_eNB_mui, size); - /* Refresh SRBs/DRBs */ rrc_pdcp_config_asn1_req(ctxt_pP, - *SRB_configList2, // NULL, - *DRB_configList, - NULL, - 0xff, // already configured during the securitymodecommand - NULL, - NULL, - NULL + *SRB_configList2, // NULL, + *DRB_configList, + NULL, + 0xff, // already configured during the securitymodecommand + NULL, + NULL, + NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , (LTE_PMCH_InfoList_r9_t *) NULL + , (LTE_PMCH_InfoList_r9_t *) NULL #endif - , NULL); + , NULL); /* Refresh SRBs/DRBs */ if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { @@ -6367,7 +6368,7 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct 0, 0 #endif - ); + ); } free(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ); @@ -6413,6 +6414,7 @@ rrc_eNB_configure_rbs_handover(struct rrc_eNB_ue_context_s *ue_context_p, protoc NULL, NULL, (LTE_PMCH_InfoList_r9_t *) NULL, NULL); + if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { rrc_rlc_config_asn1_req(ctxt_pP, ue_context_p->ue_context.SRB_configList, @@ -6470,7 +6472,7 @@ rrc_eNB_configure_rbs_handover(struct rrc_eNB_ue_context_s *ue_context_p, protoc (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, - (LTE_MBSFNAreaConfiguration_r9_t*) NULL + (LTE_MBSFNAreaConfiguration_r9_t *) NULL ); } @@ -6553,6 +6555,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( kUPenc, (LTE_PMCH_InfoList_r9_t *) NULL, NULL); + /* Refresh SRBs/DRBs */ if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { rrc_rlc_config_asn1_req(ctxt_pP, @@ -6562,7 +6565,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( (LTE_PMCH_InfoList_r9_t *) NULL, 0, 0 - ); + ); } /* Set the SRB active in UE context */ @@ -6687,7 +6690,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, - (LTE_MBSFNAreaConfiguration_r9_t*) NULL + (LTE_MBSFNAreaConfiguration_r9_t *) NULL ); } } else { // remove LCHAN from MAC/PHY @@ -6747,7 +6750,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, - (LTE_MBSFNAreaConfiguration_r9_t*) NULL + (LTE_MBSFNAreaConfiguration_r9_t *) NULL ); } } // end else of if (ue_context_pP->ue_context.DRB_active[drb_id] == 0) @@ -6910,7 +6913,7 @@ rrc_eNB_generate_RRCConnectionSetup( (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, - (LTE_MBSFNAreaConfiguration_r9_t*) NULL + (LTE_MBSFNAreaConfiguration_r9_t *) NULL ); break; } @@ -7044,6 +7047,16 @@ char openair_rrc_eNB_configuration( return 0; } +static +void rrc_eNB_generate_RRCConnectionReestablishmentReject_unknown_UE(protocol_ctxt_t *const ctxt_pP, + const int CC_id) { + struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_next_free_ue_context(ctxt_pP, ctxt_pP->rnti); + rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, + ue_context_p, + CC_id); + ue_context_p->ue_context.ul_failure_timer = 500; // 500 milliseconds to send the message and remove temporary entry +} + /*------------------------------------------------------------------------------*/ int rrc_eNB_decode_ccch( @@ -7122,12 +7135,14 @@ rrc_eNB_decode_ccch( uint16_t c_rnti = 0; if (rrcConnectionReestablishmentRequest->ue_Identity.physCellId != RC.rrc[ctxt_pP->module_id]->carrier[CC_id].physCellId) { + /* UE was moving from previous cell so quickly that RRCConnectionReestablishment for previous cell was recieved in this cell */ LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentRequest ue_Identity.physCellId(%ld) is not equal to current physCellId(%d), let's reject the UE\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), rrcConnectionReestablishmentRequest->ue_Identity.physCellId, RC.rrc[ctxt_pP->module_id]->carrier[CC_id].physCellId); - rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id); + rrc_eNB_generate_RRCConnectionReestablishmentReject_unknown_UE(ctxt_pP, + CC_id); break; } @@ -7140,10 +7155,12 @@ rrc_eNB_decode_ccch( if (rrcConnectionReestablishmentRequest->ue_Identity.c_RNTI.size == 0 || rrcConnectionReestablishmentRequest->ue_Identity.c_RNTI.size > 2) { + /* c_RNTI range error should not happen */ LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentRequest c_RNTI range error, let's reject the UE\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); - rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id); + rrc_eNB_generate_RRCConnectionReestablishmentReject_unknown_UE(ctxt_pP, + CC_id); break; } @@ -7155,7 +7172,8 @@ rrc_eNB_decode_ccch( LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentRequest without UE context, let's reject the UE\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); - rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id); + rrc_eNB_generate_RRCConnectionReestablishmentReject_unknown_UE(ctxt_pP, + CC_id); break; } @@ -7222,8 +7240,10 @@ rrc_eNB_decode_ccch( if(ue_context_p->ue_context.ue_reestablishment_timer > 0) { LOG_E(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" RRRCConnectionReconfigurationComplete(Previous) don't receive, delete the Previous UE\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); + PROTOCOL_RRC_CTXT_UE_FMT" RRRCConnectionReconfigurationComplete(Previous) don't receive, delete the Previous UE,\nprevious Status %d, new Status RRC_RECONFIGURED\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + ue_context_p->ue_context.Status + ); ue_context_p->ue_context.Status = RRC_RECONFIGURED; protocol_ctxt_t ctxt_old_p; PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt_old_p, @@ -7808,8 +7828,7 @@ rrc_eNB_decode_dcch( LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_HO_EXECUTION (xid %ld)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); - } - else if(ue_context_p->ue_context.Status == RRC_NR_NSA){ + } else if(ue_context_p->ue_context.Status == RRC_NR_NSA) { //Looking for a condition to trigger S1AP E-RAB-Modification-indication, based on the reception of RRCConnectionReconfigurationComplete //including NR specific elements. if(ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8. @@ -7837,8 +7856,7 @@ rrc_eNB_decode_dcch( } } } - } - else { + } else { dedicated_DRB = 0; ue_context_p->ue_context.Status = RRC_RECONFIGURED; LOG_I(RRC, @@ -7847,7 +7865,6 @@ rrc_eNB_decode_dcch( } ue_context_p->ue_context.reestablishment_xid = -1; - } else { dedicated_DRB = 1; ue_context_p->ue_context.Status = RRC_RECONFIGURED; @@ -8383,8 +8400,7 @@ rrc_eNB_decode_dcch( case LTE_UL_DCCH_MessageType__c1_PR_mbmsCountingResponse_r10: T(T_ENB_RRC_MBMS_COUNTING_RESPONSE_R10, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - LOG_E(RRC, "THINH [LTE_UL_DCCH_MessageType__c1_PR_mbmsCountingResponse_r10]\n"); - + LOG_E(RRC, "THINH [LTE_UL_DCCH_MessageType__c1_PR_mbmsCountingResponse_r10]\n"); break; case LTE_UL_DCCH_MessageType__c1_PR_interFreqRSTDMeasurementIndication_r10: @@ -8412,46 +8428,46 @@ rrc_eNB_decode_dcch( case LTE_UL_DCCH_MessageType__messageClassExtension_PR_c2: //SidelinkUEInformation if(ul_dcch_msg->message.choice.messageClassExtension.choice.c2.present == - LTE_UL_DCCH_MessageType__messageClassExtension__c2_PR_scgFailureInformationNR_r15){ + LTE_UL_DCCH_MessageType__messageClassExtension__c2_PR_scgFailureInformationNR_r15) { if (ul_dcch_msg->message.choice.messageClassExtension.choice.c2.choice.scgFailureInformationNR_r15. - criticalExtensions.present == LTE_SCGFailureInformationNR_r15__criticalExtensions_PR_c1){ + criticalExtensions.present == LTE_SCGFailureInformationNR_r15__criticalExtensions_PR_c1) { if (ul_dcch_msg->message.choice.messageClassExtension.choice.c2.choice.scgFailureInformationNR_r15.criticalExtensions. - choice.c1.present == LTE_SCGFailureInformationNR_r15__criticalExtensions__c1_PR_scgFailureInformationNR_r15){ + choice.c1.present == LTE_SCGFailureInformationNR_r15__criticalExtensions__c1_PR_scgFailureInformationNR_r15) { if (ul_dcch_msg->message.choice.messageClassExtension.choice.c2.choice.scgFailureInformationNR_r15.criticalExtensions. - choice.c1.choice.scgFailureInformationNR_r15.failureReportSCG_NR_r15!=NULL) { + choice.c1.choice.scgFailureInformationNR_r15.failureReportSCG_NR_r15!=NULL) { LOG_E(RRC, "Received NR scgFailureInformation from UE, failure type: %ld \n", - ul_dcch_msg->message.choice.messageClassExtension.choice.c2.choice.scgFailureInformationNR_r15.criticalExtensions. - choice.c1.choice.scgFailureInformationNR_r15.failureReportSCG_NR_r15->failureType_r15); + ul_dcch_msg->message.choice.messageClassExtension.choice.c2.choice.scgFailureInformationNR_r15.criticalExtensions. + choice.c1.choice.scgFailureInformationNR_r15.failureReportSCG_NR_r15->failureType_r15); xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)ul_dcch_msg); } } } - } - else if(ul_dcch_msg->message.choice.messageClassExtension.choice.c2.present == LTE_UL_DCCH_MessageType__messageClassExtension__c2_PR_sidelinkUEInformation_r12){ + } else if(ul_dcch_msg->message.choice.messageClassExtension.choice.c2.present == LTE_UL_DCCH_MessageType__messageClassExtension__c2_PR_sidelinkUEInformation_r12) { //case UL_DCCH_MessageType__messageClassExtension__c2_PR_sidelinkUEInformation_r12: //SidelinkUEInformation LOG_I(RRC,"THINH [LTE_UL_DCCH_MessageType__messageClassExtension_PR_c2]\n"); LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, - "[MSG] RRC SidelinkUEInformation \n"); + "[MSG] RRC SidelinkUEInformation \n"); MSC_LOG_RX_MESSAGE( - MSC_RRC_ENB, - MSC_RRC_UE, - Rx_sdu, - sdu_sizeP, - MSC_AS_TIME_FMT" SidelinkUEInformation UE %x size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_p->ue_context.rnti, - sdu_sizeP); - LOG_I(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " - "(SidelinkUEInformation) ---> RRC_eNB\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - DCCH, + MSC_RRC_ENB, + MSC_RRC_UE, + Rx_sdu, + sdu_sizeP, + MSC_AS_TIME_FMT" SidelinkUEInformation UE %x size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->ue_context.rnti, sdu_sizeP); + LOG_I(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " + "(SidelinkUEInformation) ---> RRC_eNB\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + DCCH, + sdu_sizeP); rrc_eNB_process_SidelinkUEInformation( ctxt_pP, ue_context_p, &ul_dcch_msg->message.choice.messageClassExtension.choice.c2.choice.sidelinkUEInformation_r12); - } + } + break; default: @@ -8618,17 +8634,14 @@ void rrc_enb_init(void) { //----------------------------------------------------------------------------- void process_successful_rlc_sdu_indication(int instance, - int rnti, - int message_id) -{ + int rnti, + int message_id) { int release_num; int release_total; RRC_release_ctrl_t *release_ctrl; - /* Check if the message sent was RRC Connection Release. * If yes then continue the release process. */ - pthread_mutex_lock(&rrc_release_freelist); if (rrc_release_info.num_UEs > 0) { @@ -8670,14 +8683,11 @@ void process_successful_rlc_sdu_indication(int instance, } //----------------------------------------------------------------------------- -void process_unsuccessful_rlc_sdu_indication(int instance, int rnti) -{ +void process_unsuccessful_rlc_sdu_indication(int instance, int rnti) { int release_num; int release_total; RRC_release_ctrl_t *release_ctrl; - /* radio link failure detected by RLC layer, remove UE properly */ - pthread_mutex_lock(&rrc_release_freelist); /* first, check if the rnti is in the list rrc_release_info.RRC_release_ctrl */ @@ -8745,8 +8755,7 @@ void process_rlc_sdu_indication(int instance, int rnti, int is_successful, int srb_id, - int message_id) -{ + int message_id) { if (is_successful) process_successful_rlc_sdu_indication(instance, rnti, message_id); else @@ -9094,42 +9103,46 @@ void rrc_eNB_process_AdditionResponseInformation(const module_id_t enb_mod_idP, unsigned char buffer[8192]; int size; ue_context = rrc_eNB_get_ue_context(RC.rrc[enb_mod_idP], m->rnti); - ue_context->ue_context.nb_of_modify_endc_e_rabs = m->nb_e_rabs_admitted_tobeadded; - int j=0; - while(j < m->nb_e_rabs_admitted_tobeadded) { - for (int e_rab_idx=0; e_rab_idxue_context.setup_e_rabs; e_rab_idx++) { - //Update ue_context information with gNB's address and new GTP tunnel ID - if( ue_context->ue_context.e_rab[e_rab_idx].param.e_rab_id == m->e_rabs_admitted_tobeadded[j].e_rab_id) { - memcpy(ue_context->ue_context.gnb_gtp_endc_addrs[e_rab_idx].buffer, - m->e_rabs_admitted_tobeadded[j].gnb_addr.buffer, - m->e_rabs_admitted_tobeadded[j].gnb_addr.length); - ue_context->ue_context.gnb_gtp_endc_addrs[e_rab_idx].length = m->e_rabs_admitted_tobeadded[j].gnb_addr.length; - ue_context->ue_context.gnb_gtp_endc_teid[e_rab_idx] = m->e_rabs_admitted_tobeadded[j].gtp_teid; - ue_context->ue_context.e_rab[e_rab_idx].status = E_RAB_STATUS_TOMODIFY; - break; + if (ue_context) { + ue_context->ue_context.nb_of_modify_endc_e_rabs = m->nb_e_rabs_admitted_tobeadded; + int j=0; + + while(j < m->nb_e_rabs_admitted_tobeadded) { + for (int e_rab_idx=0; e_rab_idxue_context.setup_e_rabs; e_rab_idx++) { + //Update ue_context information with gNB's address and new GTP tunnel ID + if( ue_context->ue_context.e_rab[e_rab_idx].param.e_rab_id == m->e_rabs_admitted_tobeadded[j].e_rab_id) { + memcpy(ue_context->ue_context.gnb_gtp_endc_addrs[e_rab_idx].buffer, + m->e_rabs_admitted_tobeadded[j].gnb_addr.buffer, + m->e_rabs_admitted_tobeadded[j].gnb_addr.length); + ue_context->ue_context.gnb_gtp_endc_addrs[e_rab_idx].length = m->e_rabs_admitted_tobeadded[j].gnb_addr.length; + ue_context->ue_context.gnb_gtp_endc_teid[e_rab_idx] = m->e_rabs_admitted_tobeadded[j].gtp_teid; + ue_context->ue_context.e_rab[e_rab_idx].status = E_RAB_STATUS_TOMODIFY; + break; + } } + + j++; } - j++; + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, + 0, + ENB_FLAG_YES, + m->rnti, + 0, 0); + size = rrc_eNB_generate_RRCConnectionReconfiguration_endc(&ctxt, ue_context, buffer, 8192, scg_CellGroupConfig, nr1_conf); + rrc_data_req(&ctxt, + DCCH, + rrc_eNB_mui++, + SDU_CONFIRM_NO, + size, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); + } else { + LOG_E(F1AP, "no ue_context for RNTI %x, acknowledging release\n", m->rnti); } - - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, - 0, - ENB_FLAG_YES, - m->rnti, - 0, 0); - size = rrc_eNB_generate_RRCConnectionReconfiguration_endc(&ctxt, ue_context, buffer, 8192, scg_CellGroupConfig, nr1_conf); - rrc_data_req(&ctxt, - DCCH, - rrc_eNB_mui++, - SDU_CONFIRM_NO, - size, - buffer, - PDCP_TRANSMISSION_MODE_CONTROL); } - //----------------------------------------------------------------------------- void *rrc_enb_process_itti_msg(void *notUsed) { MessageDef *msg_p; @@ -9464,8 +9477,8 @@ void *rrc_enb_process_itti_msg(void *notUsed) { break; case M2AP_MCE_CONFIGURATION_UPDATE: - rrc_eNB_process_M2AP_MCE_CONFIGURATION_UPDATE(&ctxt,&M2AP_MCE_CONFIGURATION_UPDATE(msg_p)); - break; + rrc_eNB_process_M2AP_MCE_CONFIGURATION_UPDATE(&ctxt,&M2AP_MCE_CONFIGURATION_UPDATE(msg_p)); + break; case RLC_SDU_INDICATION: process_rlc_sdu_indication(instance, @@ -9509,7 +9522,7 @@ rrc_enb_task( //if (go_nr) rrc_go_nr(); } } - } +} /*------------------------------------------------------------------------------*/ void diff --git a/openair3/GTPV1-U/nw-gtpv1u/test-app/nw-helloworld/NwMiniLogMgrEntity.h b/openair3/GTPV1-U/nw-gtpv1u/test-app/nw-helloworld/NwMiniLogMgrEntity.h index 8f2908e52a..18b60aa611 100644 --- a/openair3/GTPV1-U/nw-gtpv1u/test-app/nw-helloworld/NwMiniLogMgrEntity.h +++ b/openair3/GTPV1-U/nw-gtpv1u/test-app/nw-helloworld/NwMiniLogMgrEntity.h @@ -16,13 +16,13 @@ #include "NwEvt.h" #include "NwLog.h" +#ifndef __NW_MINI_LOG_MGR_H__ +#define __NW_MINI_LOG_MGR_H__ + #ifndef NW_ASSERT #define NW_ASSERT assert #endif -#ifndef __NW_MINI_LOG_MGR_H__ -#define __NW_MINI_LOG_MGR_H__ - extern uint32_t g_log_level; diff --git a/openair3/GTPV1-U/nw-gtpv1u/test-app/nw-helloworld/NwMiniTmrMgrEntity.h b/openair3/GTPV1-U/nw-gtpv1u/test-app/nw-helloworld/NwMiniTmrMgrEntity.h index b17228c9cf..a1f16ff89b 100644 --- a/openair3/GTPV1-U/nw-gtpv1u/test-app/nw-helloworld/NwMiniTmrMgrEntity.h +++ b/openair3/GTPV1-U/nw-gtpv1u/test-app/nw-helloworld/NwMiniTmrMgrEntity.h @@ -17,13 +17,13 @@ #include "NwEvt.h" #include "NwLog.h" +#ifndef __NW_MINI_TMR_MGR_H__ +#define __NW_MINI_TMR_MGR_H__ + #ifndef NW_ASSERT #define NW_ASSERT assert #endif -#ifndef __NW_MINI_TMR_MGR_H__ -#define __NW_MINI_TMR_MGR_H__ - typedef struct { NwEventT ev; void* timeoutArg; diff --git a/openair3/GTPV1-U/nw-gtpv1u/test-app/nw-helloworld/NwMiniUdpEntity.h b/openair3/GTPV1-U/nw-gtpv1u/test-app/nw-helloworld/NwMiniUdpEntity.h index 2e19ebbb8e..568c5b0796 100644 --- a/openair3/GTPV1-U/nw-gtpv1u/test-app/nw-helloworld/NwMiniUdpEntity.h +++ b/openair3/GTPV1-U/nw-gtpv1u/test-app/nw-helloworld/NwMiniUdpEntity.h @@ -17,13 +17,13 @@ #include "NwEvt.h" #include "NwLog.h" +#ifndef __NW_MINI_UDP_ENTITY_H__ +#define __NW_MINI_UDP_ENTITY_H__ + #ifndef NW_ASSERT #define NW_ASSERT assert #endif -#ifndef __NW_MINI_UDP_ENTITY_H__ -#define __NW_MINI_UDP_ENTITY_H__ - typedef struct { uint32_t hSocket; NwEventT ev; diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index d086c0e13a..778c8165eb 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -90,6 +90,8 @@ typedef enum { USRP_B200_DEV, /*!\brief device is USRP X300/X310*/ USRP_X300_DEV, + /*!\brief device is USRP N300/N310*/ + USRP_N300_DEV, /*!\brief device is BLADE RF*/ BLADERF_DEV, /*!\brief device is LMSSDR (SoDeRa)*/ @@ -104,7 +106,7 @@ typedef enum { UEDv2_DEV, MAX_RF_DEV_TYPE } dev_type_t; -#define DEVTYPE_NAMES {"","EXMIMO","USRP B200","USRP X300","BLADERF","LMSSDR","IRIS","No HW","ADRV9371_ZC706","UEDv2"} +#define DEVTYPE_NAMES {"","EXMIMO","USRP B200","USRP X300","USRP N300","BLADERF","LMSSDR","IRIS","No HW","ADRV9371_ZC706","UEDv2"} /*!\brief transport protocol types */ typedef enum { @@ -434,6 +436,11 @@ struct openair0_device_t { * \param arg pointer to capabilities or configuration */ int (*trx_write_init)(openair0_device *device); + /* \brief Get internal parameter + * \param id parameter to get + * \return a pointer to the parameter + */ + void *(*get_internal_parameter)(char *id); }; /* type of device init function, implemented in shared lib */ diff --git a/targets/ARCH/ETHERNET/benetel/4g/benetel.c b/targets/ARCH/ETHERNET/benetel/4g/benetel.c new file mode 100644 index 0000000000..37f55c689f --- /dev/null +++ b/targets/ARCH/ETHERNET/benetel/4g/benetel.c @@ -0,0 +1,386 @@ +/* + * 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 "common_lib.h" +#include "ethernet_lib.h" +#include "shared_buffers.h" +#include "low.h" +#include "common/utils/LOG/log.h" +#include "common/utils/LOG/vcd_signal_dumper.h" + +typedef struct { + eth_state_t e; + shared_buffers buffers; + rru_config_msg_type_t last_msg; + int capabilities_sent; + void *benetel_priv; + char *dpdk_main_command_line; +} benetel_eth_state_t; + +int trx_benetel_start(openair0_device *device) +{ + printf("BENETEL: %s\n", __FUNCTION__); + return 0; +} + + +void trx_benetel_end(openair0_device *device) +{ + printf("BENETEL: %s\n", __FUNCTION__); +} + + +int trx_benetel_stop(openair0_device *device) +{ + printf("BENETEL: %s\n", __FUNCTION__); + return(0); +} + + +int trx_benetel_set_freq(openair0_device* device, + openair0_config_t *openair0_cfg, + int exmimo_dump_config) +{ + printf("BENETEL: %s\n", __FUNCTION__); + return(0); +} + + +int trx_benetel_set_gains(openair0_device* device, + openair0_config_t *openair0_cfg) +{ + printf("BENETEL: %s\n", __FUNCTION__); + return(0); +} + + +int trx_benetel_get_stats(openair0_device* device) +{ + printf("BENETEL: %s\n", __FUNCTION__); + return(0); +} + + +int trx_benetel_reset_stats(openair0_device* device) +{ + printf("BENETEL: %s\n", __FUNCTION__); + return(0); +} + + +int ethernet_tune(openair0_device *device, + unsigned int option, + int value) +{ + printf("BENETEL: %s\n", __FUNCTION__); + return 0; +} + +int trx_benetel_write_raw(openair0_device *device, + openair0_timestamp timestamp, + void **buff, int nsamps, int cc, int flags) +{ + printf("BENETEL: %s\n", __FUNCTION__); + return nsamps*4; +} + +int trx_benetel_read_raw(openair0_device *device, + openair0_timestamp *timestamp, + void **buff, int nsamps, int cc) +{ + printf("BENETEL: %s\n", __FUNCTION__); + return nsamps*4; +} + +char *msg_type(int t) +{ + static char *s[12] = { + "RAU_tick", + "RRU_capabilities", + "RRU_config", + "RRU_config_ok", + "RRU_start", + "RRU_stop", + "RRU_sync_ok", + "RRU_frame_resynch", + "RRU_MSG_max_num", + "RRU_check_sync", + "RRU_config_update", + "RRU_config_update_ok", + }; + + if (t < 0 || t > 11) return "UNKNOWN"; + return s[t]; +} + +int trx_benetel_ctlsend(openair0_device *device, void *msg, ssize_t msg_len) +{ + RRU_CONFIG_msg_t *rru_config_msg = msg; + benetel_eth_state_t *s = device->priv; + + printf("BENETEL: %s\n", __FUNCTION__); + + printf(" rru_config_msg->type %d [%s]\n", rru_config_msg->type, + msg_type(rru_config_msg->type)); + + s->last_msg = rru_config_msg->type; + + return msg_len; +} + +int trx_benetel_ctlrecv(openair0_device *device, void *msg, ssize_t msg_len) +{ + RRU_CONFIG_msg_t *rru_config_msg = msg; + benetel_eth_state_t *s = device->priv; + + printf("BENETEL: %s\n", __FUNCTION__); + + if (s->last_msg == RAU_tick && s->capabilities_sent == 0) { + RRU_capabilities_t *cap; + rru_config_msg->type = RRU_capabilities; + rru_config_msg->len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE+sizeof(RRU_capabilities_t); + cap = (RRU_capabilities_t*)&rru_config_msg->msg[0]; + cap->FH_fmt = OAI_IF4p5_only; + cap->num_bands = 1; + cap->band_list[0] = 7; + cap->nb_rx[0] = 1; + cap->nb_tx[0] = 1; + cap->max_pdschReferenceSignalPower[0] = -27; + cap->max_rxgain[0] = 90; + + s->capabilities_sent = 1; + + return rru_config_msg->len; + } + if (s->last_msg == RRU_config) { + rru_config_msg->type = RRU_config_ok; + return 0; + } + if (s->last_msg == RRU_start) { + s->benetel_priv = benetel_start(s->e.if_name, &s->buffers, s->dpdk_main_command_line); + } + /* correct? */ + while (1) pause(); + + return 0; +} + +void benetel_fh_if4p5_south_in(RU_t *ru, + int *frame, + int *subframe) +{ + benetel_eth_state_t *s = ru->ifdevice.priv; + PHY_VARS_eNB **eNB_list = ru->eNB_list, *eNB; + LTE_DL_FRAME_PARMS *fp; + int symbol; + int32_t *rxdata; + int antenna = 0; + + lock_ul_buffer(&s->buffers, *subframe); +next: + while (!(s->buffers.ul_busy[*subframe] == 0x3fff || + s->buffers.prach_busy[*subframe] == 1)) + wait_ul_buffer(&s->buffers, *subframe); + if (s->buffers.prach_busy[*subframe] == 1) { + int i; + int antenna = 0; + uint16_t *in; + uint16_t *out; + in = (uint16_t *)s->buffers.prach[*subframe]; + out = (uint16_t *)ru->prach_rxsigF[antenna]; + for (i = 0; i < 840*2; i++) + out[i] = ntohs(in[i]); + s->buffers.prach_busy[*subframe] = 0; + ru->wakeup_prach_eNB(ru->eNB_list[0], ru, *frame, *subframe); + goto next; + } + + eNB = eNB_list[0]; + fp = &eNB->frame_parms; + for (symbol = 0; symbol < 14; symbol++) { + int i; + uint16_t *p = (uint16_t *)(&s->buffers.ul[*subframe][symbol*1200*4]); + for (i = 0; i < 1200*2; i++) { + p[i] = htons(p[i]); + } + rxdata = &ru->common.rxdataF[antenna][symbol * fp->ofdm_symbol_size]; +#if 1 + memcpy(rxdata + 2048 - 600, + &s->buffers.ul[*subframe][symbol*1200*4], + 600 * 4); + memcpy(rxdata, + &s->buffers.ul[*subframe][symbol*1200*4] + 600*4, + 600 * 4); +#endif + } + + s->buffers.ul_busy[*subframe] = 0; + signal_ul_buffer(&s->buffers, *subframe); + unlock_ul_buffer(&s->buffers, *subframe); + + //printf("BENETEL: %s (f.sf %d.%d)\n", __FUNCTION__, *frame, *subframe); + + RU_proc_t *proc = &ru->proc; + extern uint16_t sf_ahead; + int f = *frame; + int sf = *subframe; + + //calculate timestamp_rx, timestamp_tx based on frame and subframe + proc->tti_rx = sf; + proc->frame_rx = f; + proc->timestamp_rx = ((proc->frame_rx * 10) + proc->tti_rx ) * fp->samples_per_tti ; + + if (get_nprocs()<=4) { + proc->tti_tx = (sf+sf_ahead)%10; + proc->frame_tx = (sf>(9-sf_ahead)) ? (f+1)&1023 : f; + } + + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_IF4P5_SOUTH_IN_RU+ru->idx,f); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_IF4P5_SOUTH_IN_RU+ru->idx,sf); + proc->symbol_mask[sf] = 0; + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff); + +} + +void benetel_fh_if4p5_south_out(RU_t *ru, + int frame, + int subframe, + uint64_t timestamp) +{ + benetel_eth_state_t *s = ru->ifdevice.priv; + PHY_VARS_eNB **eNB_list = ru->eNB_list, *eNB; + LTE_DL_FRAME_PARMS *fp; + int symbol; + int32_t *txdata; + int aa = 0; + + //printf("BENETEL: %s (f.sf %d.%d ts %ld)\n", __FUNCTION__, frame, subframe, timestamp); + + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff ); + + lock_dl_buffer(&s->buffers, subframe); + if (s->buffers.dl_busy[subframe]) { + printf("%s: fatal: DL buffer busy for subframe %d\n", __FUNCTION__, subframe); + unlock_dl_buffer(&s->buffers, subframe); + return; + } + eNB = eNB_list[0]; + fp = &eNB->frame_parms; + if (ru->num_eNB != 1 || ru->nb_tx != 1 || fp->ofdm_symbol_size != 2048 || + fp->Ncp != NORMAL || fp->symbols_per_tti != 14) { + printf("%s:%d:%s: unsupported configuration\n", + __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + for (symbol = 0; symbol < 14; symbol++) { + txdata = &ru->common.txdataF_BF[aa][symbol * fp->ofdm_symbol_size]; +#if 1 + memcpy(&s->buffers.dl[subframe][symbol*1200*4], + txdata + 2048 - 600, + 600 * 4); + memcpy(&s->buffers.dl[subframe][symbol*1200*4] + 600*4, + txdata + 1, + 600 * 4); +#endif + int i; + uint16_t *p = (uint16_t *)(&s->buffers.dl[subframe][symbol*1200*4]); + for (i = 0; i < 1200*2; i++) { + p[i] = htons(p[i]); + } + } + + s->buffers.dl_busy[subframe] = 0x3fff; + unlock_dl_buffer(&s->buffers, subframe); + + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_IF4P5_SOUTH_OUT_RU+ru->idx, ru->proc.frame_tx); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_IF4P5_SOUTH_OUT_RU+ru->idx, ru->proc.tti_tx); + +} + +void *get_internal_parameter(char *name) +{ + printf("BENETEL: %s\n", __FUNCTION__); + + if (!strcmp(name, "fh_if4p5_south_in")) + return benetel_fh_if4p5_south_in; + if (!strcmp(name, "fh_if4p5_south_out")) + return benetel_fh_if4p5_south_out; + + return NULL; +} + +__attribute__((__visibility__("default"))) +int transport_init(openair0_device *device, + openair0_config_t *openair0_cfg, + eth_params_t * eth_params ) +{ + benetel_eth_state_t *eth; + + printf("BENETEL: %s\n", __FUNCTION__); + + device->Mod_id = 0; + device->transp_type = ETHERNET_TP; + device->trx_start_func = trx_benetel_start; + device->trx_get_stats_func = trx_benetel_get_stats; + device->trx_reset_stats_func = trx_benetel_reset_stats; + device->trx_end_func = trx_benetel_end; + device->trx_stop_func = trx_benetel_stop; + device->trx_set_freq_func = trx_benetel_set_freq; + device->trx_set_gains_func = trx_benetel_set_gains; + + device->trx_write_func = trx_benetel_write_raw; + device->trx_read_func = trx_benetel_read_raw; + + device->trx_ctlsend_func = trx_benetel_ctlsend; + device->trx_ctlrecv_func = trx_benetel_ctlrecv; + + device->get_internal_parameter = get_internal_parameter; + + eth = calloc(1, sizeof(benetel_eth_state_t)); + if (eth == NULL) { + AssertFatal(0==1, "out of memory\n"); + } + + eth->e.flags = ETH_RAW_IF4p5_MODE; + eth->e.compression = NO_COMPRESS; + eth->e.if_name = eth_params->local_if_name; + device->priv = eth; + device->openair0_cfg=&openair0_cfg[0]; + + if (openair0_cfg->sdr_addrs == NULL) { + printf("benetel: fatal: sdr_addrs not set in configuration file\n"); + exit(1); + } + + eth->dpdk_main_command_line = strdup(openair0_cfg->sdr_addrs); + if (eth->dpdk_main_command_line == NULL) { + AssertFatal(0==1, "out of memory\n"); + } + + eth->last_msg = -1; + + init_buffers(ð->buffers); + + return 0; +} diff --git a/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c b/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c new file mode 100644 index 0000000000..9b64f01d44 --- /dev/null +++ b/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c @@ -0,0 +1,787 @@ +/* license: to be defined */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "low.h" + +// HEADER DEFINITION +#define ANT_NUM buf[23] +#define PAYLOAD_1 buf[20] +#define PAYLOAD_2 buf[21] +#define ETH_TYPE buf[17] +#define SYMBOL buf[29] +#define SUBFRAME buf[28] +#define FRAME buf[27] + +static volatile bool force_quit; + +unsigned short iq[33600]; +unsigned char iq_swap[67200]; + +unsigned short *iq_ptr[14]; +unsigned int dl_start = 0; + +/* MAC updating enabled by default */ +static int mac_updating = 1; +#define RTE_LOGTYPE_L2FWD RTE_LOGTYPE_USER1 +#define MAX_PKT_BURST 32 +#define BURST_TX_DRAIN_US 5 /* TX drain every ~100us */ +#define MEMPOOL_CACHE_SIZE 256 +/* + * Configurable number of RX/TX ring descriptors + */ +#define RTE_TEST_RX_DESC_DEFAULT 1024 +#define RTE_TEST_TX_DESC_DEFAULT 1024 +static uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; +static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; +/* ethernet addresses of ports */ +static struct ether_addr l2fwd_ports_eth_addr[RTE_MAX_ETHPORTS]; +/* mask of enabled ports */ +static uint32_t l2fwd_enabled_port_mask = 0; +/* list of enabled ports */ +static uint32_t l2fwd_dst_ports[RTE_MAX_ETHPORTS]; +static unsigned int l2fwd_rx_queue_per_lcore = 1; +#define MAX_RX_QUEUE_PER_LCORE 16 +#define MAX_TX_QUEUE_PER_PORT 16 +struct lcore_queue_conf { + unsigned n_rx_port; + unsigned rx_port_list[MAX_RX_QUEUE_PER_LCORE]; +} __rte_cache_aligned; +struct lcore_queue_conf lcore_queue_conf[RTE_MAX_LCORE]; +static struct rte_eth_dev_tx_buffer *tx_buffer[RTE_MAX_ETHPORTS]; +static struct rte_eth_conf port_conf = { + .rxmode = { + .split_hdr_size = 0, + .offloads = DEV_RX_OFFLOAD_CRC_STRIP, + .offloads = DEV_RX_OFFLOAD_JUMBO_FRAME, + .split_hdr_size = 0, + .max_rx_pkt_len = 9500, + }, + .txmode = { + .mq_mode = ETH_MQ_TX_NONE, + }, +}; +struct rte_mempool * l2fwd_pktmbuf_pool = NULL; +/* Per-port statistics struct */ +struct l2fwd_port_statistics { + uint64_t tx; + uint64_t rx; + uint64_t dropped; +} __rte_cache_aligned; +struct l2fwd_port_statistics port_statistics[RTE_MAX_ETHPORTS]; +#define MAX_TIMER_PERIOD 86400 /* 1 day max */ +/* A tsc-based timer responsible for triggering statistics printout */ +static uint64_t timer_period = 10; /* default period is 10 seconds */ +/* Print out statistics on packets dropped */ +static void +print_stats(void) +{ + uint64_t total_packets_dropped, total_packets_tx, total_packets_rx; + unsigned portid; + total_packets_dropped = 0; + total_packets_tx = 0; + total_packets_rx = 0; + const char clr[] = { 27, '[', '2', 'J', '\0' }; + const char topLeft[] = { 27, '[', '1', ';', '1', 'H','\0' }; + /* Clear screen and move to top left */ + printf("%s%s", clr, topLeft); + printf("\nPort statistics ===================================="); + for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) { + /* skip disabled ports */ + if ((l2fwd_enabled_port_mask & (1 << portid)) == 0) + continue; + printf("\nStatistics for port %u ------------------------------" + "\nPackets sent: %24"PRIu64 + "\nPackets received: %20"PRIu64 + "\nPackets dropped: %21"PRIu64, + portid, + port_statistics[portid].tx, + port_statistics[portid].rx, + port_statistics[portid].dropped); + total_packets_dropped += port_statistics[portid].dropped; + total_packets_tx += port_statistics[portid].tx; + total_packets_rx += port_statistics[portid].rx; + } + printf("\nAggregate statistics ===============================" + "\nTotal packets sent: %18"PRIu64 + "\nTotal packets received: %14"PRIu64 + "\nTotal packets dropped: %15"PRIu64, + total_packets_tx, + total_packets_rx, + total_packets_dropped); + printf("\n====================================================\n"); +} +static void +l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) +{ + unsigned char *buf, *buf_tx; + unsigned int len; + struct ether_hdr *eth; + + unsigned dst_port; + int sent, prach_ctrl = 0; + struct rte_eth_dev_tx_buffer *buffer; + + unsigned char * IQ_ptr; + + ul_packet_t p; + + buf = rte_pktmbuf_mtod(m, unsigned char *); + //rte_memdump(stdout, "Rx Packet",buf ,34); + eth = rte_pktmbuf_mtod(m, struct ether_hdr *); + len = rte_pktmbuf_data_len(m); + + IQ_ptr = &buf[34]; + + //destination mac address (RRU MAC) + eth->d_addr.addr_bytes[0] = 0x02; + eth->d_addr.addr_bytes[1] = 0x00; + eth->d_addr.addr_bytes[2] = 0x5e; + eth->d_addr.addr_bytes[3] = 0x01; + eth->d_addr.addr_bytes[4] = 0x01; + eth->d_addr.addr_bytes[5] = 0x01; + + //source mac address (DU MAC) + eth->s_addr.addr_bytes[0] = 0xdd; + eth->s_addr.addr_bytes[1] = 0xdd; + eth->s_addr.addr_bytes[2] = 0xdd; + eth->s_addr.addr_bytes[3] = 0xdd; + eth->s_addr.addr_bytes[4] = 0xdd; + eth->s_addr.addr_bytes[5] = 0xdd; + + dst_port = l2fwd_dst_ports[portid]; + #if 1 + + if (buf[18] == 0xAA) //msg1 check + { + printf("\nHandshake MSG 1 Received\n"); + printf("\n====================================================\n"); + + buf[18] = 0xBB;//change to msg2 after receive msg1 + + printf("Handshake MSG 2 Sent\n"); + printf("\n====================================================\n"); + } + + #else + // Handshake Condition + if (buf[18] == 0x01 || buf[18] == 0x03) // ORAN handshake msgs. + { + if (buf[18] == 0x01) //msg1 check + { + printf("\nHandshake MSG 1 Received\n"); + printf("\n====================================================\n"); + + buf[18] = 0x02;//change to msg2 after receive msg1 + + printf("Handshake MSG 2 Sent\n"); + printf("\n====================================================\n"); + } + + else if(buf[18] == 0x03) //msg3 check + { + printf("Handshake MSG 3 Sent\n"); + printf("\n====================================================\n"); + + buf[18] = 0x04; + + printf("Handshake MSG 4 Sent\n"); + printf("\n====================================================\n"); + } + } + #endif + // Trigger start send DL packets + if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && SYMBOL == 0x09 && ANT_NUM == 0x00 && dl_start == 0){ + + printf("\nU-Plane Started\n"); + printf("\n====================================================\n"); + + dl_start = 1; + } + + + if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && ANT_NUM == 0x00) { + p.frame = FRAME; + p.subframe = SUBFRAME >> 4; + p.slot = 0; /* unused */ + p.symbol = SYMBOL; + p.antenna = 0; + memcpy(p.iq, IQ_ptr, 4800); + store_ul(bs, &p); + } + + // U-PLANE UL ANT_0 PROCESSING + if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && ANT_NUM == 0x00 && dl_start == 1) + { + int tx_frame = FRAME; + int tx_subframe = SUBFRAME >> 4; + int tx_symbol = SYMBOL + 5; + if (tx_symbol > 13) { + tx_symbol -= 14; + tx_subframe++; + if (tx_subframe == 10) { + tx_subframe = 0; + tx_frame = (tx_frame + 1) & 255; + } + } + +// ANT_NUM = 0x00; +// SYMBOL = (SYMBOL + 5) % 14; + PAYLOAD_2 = 0xc8; + + FRAME = tx_frame; + SUBFRAME = tx_subframe << 4; + SYMBOL = tx_symbol; + + /* antenna 0 - send actual DL data (if available) */ + lock_dl_buffer(bs->buffers, tx_subframe); + if (!(bs->buffers->dl_busy[tx_subframe] & (1 << tx_symbol))) { + printf("%s: warning, DL underflow (sf.symbol %d.%d)\n", __FUNCTION__, + tx_subframe, tx_symbol); + memset(IQ_ptr, 0, 1200 * 4); + } else { + memcpy(IQ_ptr, bs->buffers->dl[tx_subframe] + tx_symbol * 1200*4, + 1200*4); + } + bs->buffers->dl_busy[tx_subframe] &= ~(1 << tx_symbol); + unlock_dl_buffer(bs->buffers, tx_subframe); + + // fill DL Data for ant 0 with 0 value +// memset(IQ_ptr, 0, 4800); + } + + // U-PLANE UL ANT_1 PROCESSING + else if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && ANT_NUM == 0x01 && dl_start == 1) + { + +// ANT_NUM = 0x01; + SYMBOL = (SYMBOL + 5) % 14; + PAYLOAD_2 = 0xc8; + + // fill DL Data for ant 1 with 0 value + memset(IQ_ptr, 0, 4800); + } + + // U-PLANE PRACH PROCESSING + else if(PAYLOAD_1 == 0x0d && PAYLOAD_2 == 0x28){ + if (ANT_NUM == 0) { + store_prach(bs, FRAME, SUBFRAME>>4, IQ_ptr); + } + + rte_pktmbuf_free(m); + return; + } + + // Send Packets + buffer = tx_buffer[dst_port]; + + sent = rte_eth_tx_buffer(dst_port, 0, buffer, m); + + if (sent) + port_statistics[dst_port].tx += sent; + +} +/* main processing loop */ +static void +l2fwd_main_loop(benetel_t *bs) +{ + struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; + struct rte_mbuf *m; + int sent; + unsigned lcore_id; + uint64_t prev_tsc, diff_tsc, cur_tsc, timer_tsc; + unsigned i, j, portid, nb_rx; + struct lcore_queue_conf *qconf; + const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) / US_PER_S * + BURST_TX_DRAIN_US; + struct rte_eth_dev_tx_buffer *buffer; + prev_tsc = 0; + timer_tsc = 0; + lcore_id = rte_lcore_id(); + qconf = &lcore_queue_conf[lcore_id]; + if (qconf->n_rx_port == 0) { + RTE_LOG(INFO, L2FWD, "lcore %u has nothing to do\n", lcore_id); + return; + } + RTE_LOG(INFO, L2FWD, "entering main loop on lcore %u\n", lcore_id); + for (i = 0; i < qconf->n_rx_port; i++) { + portid = qconf->rx_port_list[i]; + RTE_LOG(INFO, L2FWD, " -- lcoreid=%u portid=%u\n", lcore_id, + portid); + } + while (!force_quit) { + cur_tsc = rte_rdtsc(); + /* + * TX burst queue drain + */ + diff_tsc = cur_tsc - prev_tsc; + if (unlikely(diff_tsc > drain_tsc)) { + for (i = 0; i < qconf->n_rx_port; i++) { + portid = l2fwd_dst_ports[qconf->rx_port_list[i]]; + buffer = tx_buffer[portid]; + sent = rte_eth_tx_buffer_flush(portid, 0, buffer); + if (sent) + port_statistics[portid].tx += sent; + } + /* if timer is enabled */ + if (timer_period > 0) { + /* advance the timer */ + timer_tsc += diff_tsc; + /* if timer has reached its timeout */ + if (unlikely(timer_tsc >= timer_period)) { + /* do this only on master core */ + if (lcore_id == rte_get_master_lcore()) { + //print_stats(); + /* reset the timer */ + timer_tsc = 0; + } + } + } + prev_tsc = cur_tsc; + } + /* + * Read packet from RX queues + */ + for (i = 0; i < qconf->n_rx_port; i++) { + portid = qconf->rx_port_list[i]; + nb_rx = rte_eth_rx_burst(portid, 0, + pkts_burst, MAX_PKT_BURST); + port_statistics[portid].rx += nb_rx; + for (j = 0; j < nb_rx; j++) { + m = pkts_burst[j]; + rte_prefetch0(rte_pktmbuf_mtod(m, void *)); + l2fwd_simple_forward(m, portid, bs); + } + } + } +} +static int +l2fwd_launch_one_lcore(void *bs) +{ + l2fwd_main_loop(bs); + return 0; +} +/* display usage */ +static void +l2fwd_usage(const char *prgname) +{ + printf("%s [EAL options] -- -p PORTMASK [-q NQ]\n" + " -p PORTMASK: hexadecimal bitmask of ports to configure\n" + " -q NQ: number of queue (=ports) per lcore (default is 1)\n" + " -T PERIOD: statistics will be refreshed each PERIOD seconds (0 to disable, 10 default, 86400 maximum)\n" + " --[no-]mac-updating: Enable or disable MAC addresses updating (enabled by default)\n" + " When enabled:\n" + " - The source MAC address is replaced by the TX port MAC address\n" + " - The destination MAC address is replaced by 02:00:00:00:00:TX_PORT_ID\n", + prgname); +} +static int +l2fwd_parse_portmask(const char *portmask) +{ + char *end = NULL; + unsigned long pm; + /* parse hexadecimal string */ + pm = strtoul(portmask, &end, 16); + if ((portmask[0] == '\0') || (end == NULL) || (*end != '\0')) + return -1; + if (pm == 0) + return -1; + return pm; +} +static unsigned int +l2fwd_parse_nqueue(const char *q_arg) +{ + char *end = NULL; + unsigned long n; + /* parse hexadecimal string */ + n = strtoul(q_arg, &end, 10); + if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0')) + return 0; + if (n == 0) + return 0; + if (n >= MAX_RX_QUEUE_PER_LCORE) + return 0; + return n; +} +static int +l2fwd_parse_timer_period(const char *q_arg) +{ + char *end = NULL; + int n; + /* parse number string */ + n = strtol(q_arg, &end, 10); + if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0')) + return -1; + if (n >= MAX_TIMER_PERIOD) + return -1; + return n; +} +static const char short_options[] = + "p:" /* portmask */ + "q:" /* number of queues */ + "T:" /* timer period */ + ; +#define CMD_LINE_OPT_MAC_UPDATING "mac-updating" +#define CMD_LINE_OPT_NO_MAC_UPDATING "no-mac-updating" +enum { + /* long options mapped to a short option */ + /* first long only option value must be >= 256, so that we won't + * conflict with short options */ + CMD_LINE_OPT_MIN_NUM = 256, +}; +static const struct option lgopts[] = { + { CMD_LINE_OPT_MAC_UPDATING, no_argument, &mac_updating, 1}, + { CMD_LINE_OPT_NO_MAC_UPDATING, no_argument, &mac_updating, 0}, + {NULL, 0, 0, 0} +}; +/* Parse the argument given in the command line of the application */ +static int +l2fwd_parse_args(int argc, char **argv) +{ + int opt, ret, timer_secs; + char **argvopt; + int option_index; + char *prgname = argv[0]; + argvopt = argv; + while ((opt = getopt_long(argc, argvopt, short_options, + lgopts, &option_index)) != EOF) { + switch (opt) { + /* portmask */ + case 'p': + l2fwd_enabled_port_mask = l2fwd_parse_portmask(optarg); + if (l2fwd_enabled_port_mask == 0) { + printf("invalid portmask\n"); + l2fwd_usage(prgname); + return -1; + } + break; + /* nqueue */ + case 'q': + l2fwd_rx_queue_per_lcore = l2fwd_parse_nqueue(optarg); + if (l2fwd_rx_queue_per_lcore == 0) { + printf("invalid queue number\n"); + l2fwd_usage(prgname); + return -1; + } + break; + /* timer period */ + case 'T': + timer_secs = l2fwd_parse_timer_period(optarg); + if (timer_secs < 0) { + printf("invalid timer period\n"); + l2fwd_usage(prgname); + return -1; + } + timer_period = timer_secs; + break; + /* long options */ + case 0: + break; + default: + l2fwd_usage(prgname); + return -1; + } + } + if (optind >= 0) + argv[optind-1] = prgname; + ret = optind-1; + optind = 1; /* reset getopt lib */ + return ret; +} +/* Check the link status of all ports in up to 9s, and print them finally */ +static void +check_all_ports_link_status(uint32_t port_mask) +{ +#define CHECK_INTERVAL 100 /* 100ms */ +#define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */ + uint16_t portid; + uint8_t count, all_ports_up, print_flag = 0; + struct rte_eth_link link; + printf("\nChecking link status"); + fflush(stdout); + for (count = 0; count <= MAX_CHECK_TIME; count++) { + if (force_quit) + return; + all_ports_up = 1; + RTE_ETH_FOREACH_DEV(portid) { + if (force_quit) + return; + if ((port_mask & (1 << portid)) == 0) + continue; + memset(&link, 0, sizeof(link)); + rte_eth_link_get_nowait(portid, &link); + /* print link status if flag set */ + if (print_flag == 1) { + if (link.link_status) + printf( + "Port%d Link Up. Speed %u Mbps - %s\n", + portid, link.link_speed, + (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? + ("full-duplex") : ("half-duplex\n")); + else + printf("Port %d Link Down\n", portid); + continue; + } + /* clear all_ports_up flag if any link down */ + if (link.link_status == ETH_LINK_DOWN) { + all_ports_up = 0; + break; + } + } + /* after finally printing all link status, get out */ + if (print_flag == 1) + break; + if (all_ports_up == 0) { + printf("."); + fflush(stdout); + rte_delay_ms(CHECK_INTERVAL); + } + /* set the print_flag if all ports up or timeout */ + if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) { + print_flag = 1; + printf("done\n"); + } + } +} +static void +signal_handler(int signum) +{ + if (signum == SIGINT || signum == SIGTERM) { + printf("\n\nSignal %d received, preparing to exit...\n", + signum); + force_quit = true; + } +} +int +dpdk_main(int argc, char **argv, benetel_t *bs) +{ + struct lcore_queue_conf *qconf; + int ret; + uint16_t nb_ports; + uint16_t nb_ports_available = 0; + uint16_t portid, last_port; + unsigned lcore_id, rx_lcore_id; + unsigned nb_ports_in_mask = 0; + unsigned int nb_lcores = 0; + unsigned int nb_mbufs; + /* init EAL */ + ret = rte_eal_init(argc, argv); + if (ret < 0) + rte_exit(EXIT_FAILURE, "Invalid EAL arguments\n"); + argc -= ret; + argv += ret; + force_quit = false; + signal(SIGINT, signal_handler); + signal(SIGTERM, signal_handler); + /* parse application arguments (after the EAL ones) */ + ret = l2fwd_parse_args(argc, argv); + if (ret < 0) + rte_exit(EXIT_FAILURE, "Invalid L2FWD arguments\n"); + printf("MAC updating %s\n", mac_updating ? "enabled" : "disabled"); + /* convert to number of cycles */ + timer_period *= rte_get_timer_hz(); + nb_ports = rte_eth_dev_count_avail(); + if (nb_ports == 0) + rte_exit(EXIT_FAILURE, "No Ethernet ports - bye\n"); + /* check port mask to possible port mask */ + if (l2fwd_enabled_port_mask & ~((1 << nb_ports) - 1)) + rte_exit(EXIT_FAILURE, "Invalid portmask; possible (0x%x)\n", + (1 << nb_ports) - 1); + /* reset l2fwd_dst_ports */ + for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) + l2fwd_dst_ports[portid] = 0; + last_port = 0; + /* + * Each logical core is assigned a dedicated TX queue on each port. + */ + RTE_ETH_FOREACH_DEV(portid) { + /* skip ports that are not enabled */ + if ((l2fwd_enabled_port_mask & (1 << portid)) == 0) + continue; + if (nb_ports_in_mask % 2) { + l2fwd_dst_ports[portid] = last_port; + l2fwd_dst_ports[last_port] = portid; + } + else + last_port = portid; + nb_ports_in_mask++; + } + if (nb_ports_in_mask % 2) { + printf("Notice: odd number of ports in portmask.\n"); + l2fwd_dst_ports[last_port] = last_port; + } + rx_lcore_id = 0; + qconf = NULL; + /* Initialize the port/queue configuration of each logical core */ + RTE_ETH_FOREACH_DEV(portid) { + /* skip ports that are not enabled */ + if ((l2fwd_enabled_port_mask & (1 << portid)) == 0) + continue; + /* get the lcore_id for this port */ + while (rte_lcore_is_enabled(rx_lcore_id) == 0 || + lcore_queue_conf[rx_lcore_id].n_rx_port == + l2fwd_rx_queue_per_lcore) { + rx_lcore_id++; + if (rx_lcore_id >= RTE_MAX_LCORE) + rte_exit(EXIT_FAILURE, "Not enough cores\n"); + } + if (qconf != &lcore_queue_conf[rx_lcore_id]) { + /* Assigned a new logical core in the loop above. */ + qconf = &lcore_queue_conf[rx_lcore_id]; + nb_lcores++; + } + qconf->rx_port_list[qconf->n_rx_port] = portid; + qconf->n_rx_port++; + printf("Lcore %u: RX port %u\n", rx_lcore_id, portid); + } + nb_mbufs = RTE_MAX(nb_ports * (nb_rxd + nb_txd + MAX_PKT_BURST + + nb_lcores * MEMPOOL_CACHE_SIZE), 8192U); + /* create the mbuf pool */ + l2fwd_pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", nb_mbufs, + MEMPOOL_CACHE_SIZE, 0, 9680, + rte_socket_id()); + if (l2fwd_pktmbuf_pool == NULL) + rte_exit(EXIT_FAILURE, "Cannot init mbuf pool\n"); + /* Initialise each port */ + RTE_ETH_FOREACH_DEV(portid) { + struct rte_eth_rxconf rxq_conf; + struct rte_eth_txconf txq_conf; + struct rte_eth_conf local_port_conf = port_conf; + struct rte_eth_dev_info dev_info; + /* skip ports that are not enabled */ + if ((l2fwd_enabled_port_mask & (1 << portid)) == 0) { + printf("Skipping disabled port %u\n", portid); + continue; + } + nb_ports_available++; + /* init port */ + printf("Initializing port %u... ", portid); + fflush(stdout); + rte_eth_dev_info_get(portid, &dev_info); + if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE) + local_port_conf.txmode.offloads |= + DEV_TX_OFFLOAD_MBUF_FAST_FREE; + ret = rte_eth_dev_configure(portid, 1, 1, &local_port_conf); + if (ret < 0) + rte_exit(EXIT_FAILURE, "Cannot configure device: err=%d, port=%u\n", + ret, portid); + ret = rte_eth_dev_adjust_nb_rx_tx_desc(portid, &nb_rxd, + &nb_txd); + if (ret < 0) + rte_exit(EXIT_FAILURE, + "Cannot adjust number of descriptors: err=%d, port=%u\n", + ret, portid); + rte_eth_macaddr_get(portid,&l2fwd_ports_eth_addr[portid]); + /* init one RX queue */ + fflush(stdout); + rxq_conf = dev_info.default_rxconf; + rxq_conf.offloads = local_port_conf.rxmode.offloads; + ret = rte_eth_rx_queue_setup(portid, 0, nb_rxd, + rte_eth_dev_socket_id(portid), + &rxq_conf, + l2fwd_pktmbuf_pool); + if (ret < 0) + rte_exit(EXIT_FAILURE, "rte_eth_rx_queue_setup:err=%d, port=%u\n", + ret, portid); + /* init one TX queue on each port */ + fflush(stdout); + txq_conf = dev_info.default_txconf; + txq_conf.offloads = local_port_conf.txmode.offloads; + ret = rte_eth_tx_queue_setup(portid, 0, nb_txd, + rte_eth_dev_socket_id(portid), + &txq_conf); + if (ret < 0) + rte_exit(EXIT_FAILURE, "rte_eth_tx_queue_setup:err=%d, port=%u\n", + ret, portid); + /* Initialize TX buffers */ + tx_buffer[portid] = rte_zmalloc_socket("tx_buffer", + RTE_ETH_TX_BUFFER_SIZE(MAX_PKT_BURST), 0, + rte_eth_dev_socket_id(portid)); + if (tx_buffer[portid] == NULL) + rte_exit(EXIT_FAILURE, "Cannot allocate buffer for tx on port %u\n", + portid); + rte_eth_tx_buffer_init(tx_buffer[portid], MAX_PKT_BURST); + ret = rte_eth_tx_buffer_set_err_callback(tx_buffer[portid], + rte_eth_tx_buffer_count_callback, + &port_statistics[portid].dropped); + if (ret < 0) + rte_exit(EXIT_FAILURE, + "Cannot set error callback for tx buffer on port %u\n", + portid); + /* Start device */ + ret = rte_eth_dev_start(portid); + if (ret < 0) + rte_exit(EXIT_FAILURE, "rte_eth_dev_start:err=%d, port=%u\n", + ret, portid); + printf("done: \n"); + rte_eth_promiscuous_enable(portid); + printf("Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n\n", + portid, + l2fwd_ports_eth_addr[portid].addr_bytes[0], + l2fwd_ports_eth_addr[portid].addr_bytes[1], + l2fwd_ports_eth_addr[portid].addr_bytes[2], + l2fwd_ports_eth_addr[portid].addr_bytes[3], + l2fwd_ports_eth_addr[portid].addr_bytes[4], + l2fwd_ports_eth_addr[portid].addr_bytes[5]); + /* initialize port stats */ + memset(&port_statistics, 0, sizeof(port_statistics)); + } + if (!nb_ports_available) { + rte_exit(EXIT_FAILURE, + "All available ports are disabled. Please set portmask.\n"); + } + check_all_ports_link_status(l2fwd_enabled_port_mask); + ret = 0; + /* launch per-lcore init on every lcore */ + rte_eal_mp_remote_launch(l2fwd_launch_one_lcore, bs, CALL_MASTER); + RTE_LCORE_FOREACH_SLAVE(lcore_id) { + if (rte_eal_wait_lcore(lcore_id) < 0) { + ret = -1; + break; + } + } + RTE_ETH_FOREACH_DEV(portid) { + if ((l2fwd_enabled_port_mask & (1 << portid)) == 0) + continue; + printf("Closing port %d...", portid); + rte_eth_dev_stop(portid); + rte_eth_dev_close(portid); + printf(" Done\n"); + } + printf("Bye...\n"); + return ret; +} diff --git a/targets/ARCH/ETHERNET/benetel/4g/low.c b/targets/ARCH/ETHERNET/benetel/4g/low.c new file mode 100644 index 0000000000..038592d596 --- /dev/null +++ b/targets/ARCH/ETHERNET/benetel/4g/low.c @@ -0,0 +1,95 @@ +/* + * 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 "low.h" + +#include +#include +#include + +void store_ul(benetel_t *bs, ul_packet_t *ul) +{ + /* only antenna 0 for the moment */ + if (ul->antenna != 0) + return; + + if (ul->subframe != bs->next_subframe || + ul->symbol != bs->next_symbol) { + printf("%s: fatal, expected frame.sf.symbol %d.%d.%d, got %d.%d.%d\n", + __FUNCTION__, + bs->expected_benetel_frame, bs->next_subframe, bs->next_symbol, + ul->frame, ul->subframe, ul->symbol); + exit(1); + } + + lock_ul_buffer(bs->buffers, bs->next_subframe); + if (bs->buffers->ul_busy[bs->next_subframe] & (1 << bs->next_symbol)) { + printf("%s: warning, UL overflow (sf.symbol %d.%d)\n", __FUNCTION__, + bs->next_subframe, bs->next_symbol); + } + memcpy(bs->buffers->ul[bs->next_subframe] + bs->next_symbol * 1200*4, + ul->iq, 1200*4); + bs->buffers->ul_busy[bs->next_subframe] |= (1 << bs->next_symbol); + signal_ul_buffer(bs->buffers, bs->next_subframe); + unlock_ul_buffer(bs->buffers, bs->next_subframe); + + bs->next_symbol++; + if (bs->next_symbol == 14) { + bs->next_symbol = 0; + bs->next_subframe = (bs->next_subframe + 1) % 10; + if (bs->next_subframe == 0) { + bs->expected_benetel_frame++; + bs->expected_benetel_frame &= 255; + } + } +} + +void store_prach(benetel_t *bs, int frame, int subframe, void *data) +{ + static int last_frame = -1; + static int last_subframe = -1; + /* hack: antenna number is always 0, discard second packet with same f/sf */ + if (frame == last_frame && subframe == last_subframe) return; + last_frame = frame; + last_subframe = subframe; + + lock_ul_buffer(bs->buffers, subframe); + if (bs->buffers->prach_busy[subframe]) { + printf("store_prach: fatal: previous prach buffer not processed\n"); + unlock_ul_buffer(bs->buffers, subframe); + return; + } + bs->buffers->prach_busy[subframe] = 1; + memcpy(bs->buffers->prach[subframe], data, 849*4); + signal_ul_buffer(bs->buffers, subframe); + unlock_ul_buffer(bs->buffers, subframe); + +} + +void *benetel_start_dpdk(char *ifname, shared_buffers *buffers, char *dpdk_main_command_line); + +void *benetel_start(char *ifname, shared_buffers *buffers, char *dpdk_main_command_line) +{ + if (!strcmp(ifname, "dpdk")) + return benetel_start_dpdk(ifname, buffers, dpdk_main_command_line); + printf("benetel: fatal: interface %s not supported, only dpdpk is supported\n", ifname); + exit(1); +} diff --git a/targets/ARCH/ETHERNET/benetel/4g/low.h b/targets/ARCH/ETHERNET/benetel/4g/low.h new file mode 100644 index 0000000000..5e75d9181e --- /dev/null +++ b/targets/ARCH/ETHERNET/benetel/4g/low.h @@ -0,0 +1,49 @@ +/* + * 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 + */ + +#ifndef _BENETEL_4G_LOW_H_ +#define _BENETEL_4G_LOW_H_ + +#include "shared_buffers.h" + +typedef struct { + shared_buffers *buffers; + int next_subframe; + int next_symbol; + int expected_benetel_frame; + char *dpdk_main_command_line; +} benetel_t; + +typedef struct { + int frame; + int subframe; + int slot; + int symbol; + int antenna; + unsigned char iq[4800]; +} ul_packet_t; + +void *benetel_start(char *ifname, shared_buffers *buffers, char *dpdk_main_command_line); + +void store_ul(benetel_t *bs, ul_packet_t *ul); +void store_prach(benetel_t *bs, int frame, int subframe, void *data); + +#endif /* _BENETEL_4G_LOW_H_ */ diff --git a/targets/ARCH/ETHERNET/benetel/4g/low_dpdk.c b/targets/ARCH/ETHERNET/benetel/4g/low_dpdk.c new file mode 100644 index 0000000000..ecff473010 --- /dev/null +++ b/targets/ARCH/ETHERNET/benetel/4g/low_dpdk.c @@ -0,0 +1,118 @@ +/* + * 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 + */ + +/* those 2 lines for CPU_SET */ +#define _GNU_SOURCE +#include + +#include +#include +#include +#include + +#include "low.h" + +int dpdk_main(int argc, char **argv, benetel_t *); + +void *dpdk_thread(void *_bs) +{ + benetel_t *bs = _bs; + int n = 0; + char **v = NULL; // { "softmodem", "-n", "2", "-l", "8", "--", "-p", "0x2" }; + char *s = bs->dpdk_main_command_line; + char *tok; + + while ((tok = strtok(s, " ")) != NULL) { + n++; + v = realloc(v, n * sizeof(char *)); + if (v == NULL) { + printf("%s: out of memory\n", __FUNCTION__); + exit(1); + } + v[n-1] = tok; + s = NULL; + } + + dpdk_main(n, v, bs); + exit(1); + return 0; +} + +void *benetel_start_dpdk(char *ifname, shared_buffers *buffers, char *dpdk_main_command_line) +{ + benetel_t *bs; + + bs = calloc(1, sizeof(benetel_t)); + if (bs == NULL) { + printf("%s: out of memory\n", __FUNCTION__); + exit(1); + } + + bs->buffers = buffers; + + bs->expected_benetel_frame = 255; + + bs->dpdk_main_command_line = dpdk_main_command_line; + + pthread_attr_t attr; + + if (pthread_attr_init(&attr) != 0) { + printf("pthread_attr_init failed\n"); + exit(1); + } + + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + CPU_SET(12,&cpuset); + if (pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t), &cpuset) != 0) { + printf("pthread_attr_setaffinity_np failed\n"); + exit(1); + } + + if (pthread_attr_setschedpolicy(&attr, SCHED_FIFO) != 0) { + printf("pthread_attr_setschedpolicy failed\n"); + exit(1); + } + + struct sched_param params; + params.sched_priority = sched_get_priority_max(SCHED_FIFO); + if (sched_get_priority_max(SCHED_FIFO) == -1) { + printf("sched_get_priority_max failed\n"); + exit(1); + } + if (pthread_attr_setschedparam(&attr, ¶ms) != 0) { + printf("pthread_setschedparam failed\n"); + exit(1); + } + + pthread_t t; + if (pthread_create(&t, &attr, dpdk_thread, bs) != 0) { + printf("%s: thread creation failed\n", __FUNCTION__); + exit(1); + } + + if (pthread_attr_destroy(&attr) != 0) { + printf("pthread_attr_init failed\n"); + exit(1); + } + + return bs; +} diff --git a/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.c b/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.c new file mode 100644 index 0000000000..492a15dfc3 --- /dev/null +++ b/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.c @@ -0,0 +1,114 @@ +/* + * 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 "shared_buffers.h" + +#include +#include +#include + +void init_buffers(shared_buffers *s) +{ + int subframe; + + memset(s, 0, sizeof(*s)); + + for (subframe = 0; subframe < 10; subframe++) { + if (pthread_mutex_init(&s->m_dl[subframe], NULL) != 0 || + pthread_cond_init(&s->c_dl[subframe], NULL) != 0 || + pthread_mutex_init(&s->m_ul[subframe], NULL) != 0 || + pthread_cond_init(&s->c_ul[subframe], NULL) != 0) { + printf("%s: error initializing mutex/cond\n", __FUNCTION__); + exit(1); + } + } + + /* in FDD the eNB's first transmitted DL subframe is 4 but the device + * needs to have subframes 1, 2 and 3 ready. Let's pretend there are ready. + */ + s->dl_busy[1] = 0x3fff; + s->dl_busy[2] = 0x3fff; + s->dl_busy[3] = 0x3fff; +} + +void lock_dl_buffer(shared_buffers *s, int subframe) +{ + if (pthread_mutex_lock(&s->m_dl[subframe]) != 0) { + printf("%s: fatal: lock fails\n", __FUNCTION__); + exit(1); + } +} + +void unlock_dl_buffer(shared_buffers *s, int subframe) +{ + if (pthread_mutex_unlock(&s->m_dl[subframe]) != 0) { + printf("%s: fatal: unlock fails\n", __FUNCTION__); + exit(1); + } +} + +void wait_dl_buffer(shared_buffers *s, int subframe) +{ + if (pthread_cond_wait(&s->c_dl[subframe], &s->m_dl[subframe]) != 0) { + printf("%s: fatal: cond_wait fails\n", __FUNCTION__); + exit(1); + } +} + +void signal_dl_buffer(shared_buffers *s, int subframe) +{ + if (pthread_cond_broadcast(&s->c_dl[subframe]) != 0) { + printf("%s: fatal: cond_broadcast fails\n", __FUNCTION__); + exit(1); + } +} + +void lock_ul_buffer(shared_buffers *s, int subframe) +{ + if (pthread_mutex_lock(&s->m_ul[subframe]) != 0) { + printf("%s: fatal: lock fails\n", __FUNCTION__); + exit(1); + } +} + +void unlock_ul_buffer(shared_buffers *s, int subframe) +{ + if (pthread_mutex_unlock(&s->m_ul[subframe]) != 0) { + printf("%s: fatal: unlock fails\n", __FUNCTION__); + exit(1); + } +} + +void wait_ul_buffer(shared_buffers *s, int subframe) +{ + if (pthread_cond_wait(&s->c_ul[subframe], &s->m_ul[subframe]) != 0) { + printf("%s: fatal: cond_wait fails\n", __FUNCTION__); + exit(1); + } +} + +void signal_ul_buffer(shared_buffers *s, int subframe) +{ + if (pthread_cond_broadcast(&s->c_ul[subframe]) != 0) { + printf("%s: fatal: cond_broadcast fails\n", __FUNCTION__); + exit(1); + } +} diff --git a/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.h b/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.h new file mode 100644 index 0000000000..1d5040b95b --- /dev/null +++ b/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.h @@ -0,0 +1,60 @@ +/* + * 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 + */ + +#ifndef _BENETEL_4G_SHARED_BUFFERS_H_ +#define _BENETEL_4G_SHARED_BUFFERS_H_ + +#include +#include + +typedef struct { + unsigned char dl[10][14*1200*4]; + unsigned char ul[10][14*1200*4]; + uint16_t dl_busy[10]; + uint16_t ul_busy[10]; + + pthread_mutex_t m_ul[10]; + pthread_cond_t c_ul[10]; + + pthread_mutex_t m_dl[10]; + pthread_cond_t c_dl[10]; + + unsigned char prach[10][849*4]; + unsigned char prach_busy[10]; + + /* statistics/error counting */ + int ul_overflow; + int dl_underflow; +} shared_buffers; + +void init_buffers(shared_buffers *s); + +void lock_dl_buffer(shared_buffers *s, int subframe); +void unlock_dl_buffer(shared_buffers *s, int subframe); +void wait_dl_buffer(shared_buffers *s, int subframe); +void signal_dl_buffer(shared_buffers *s, int subframe); + +void lock_ul_buffer(shared_buffers *s, int subframe); +void unlock_ul_buffer(shared_buffers *s, int subframe); +void wait_ul_buffer(shared_buffers *s, int subframe); +void signal_ul_buffer(shared_buffers *s, int subframe); + +#endif /* _BENETEL_4G_SHARED_BUFFERS_H_ */ diff --git a/targets/ARCH/ETHERNET/benetel/5g/benetel.c b/targets/ARCH/ETHERNET/benetel/5g/benetel.c new file mode 100644 index 0000000000..c1ae1afcc7 --- /dev/null +++ b/targets/ARCH/ETHERNET/benetel/5g/benetel.c @@ -0,0 +1,388 @@ +/* + * 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 "common_lib.h" +#include "ethernet_lib.h" +#include "shared_buffers.h" +#include "low.h" +#include "openair1/PHY/defs_gNB.h" + +typedef struct { + eth_state_t e; + shared_buffers buffers; + rru_config_msg_type_t last_msg; + int capabilities_sent; + void *benetel_priv; + char *dpdk_main_command_line; +} benetel_eth_state_t; + +int trx_benetel_start(openair0_device *device) +{ + printf("BENETEL: %s\n", __FUNCTION__); + return 0; +} + + +void trx_benetel_end(openair0_device *device) +{ + printf("BENETEL: %s\n", __FUNCTION__); +} + + +int trx_benetel_stop(openair0_device *device) +{ + printf("BENETEL: %s\n", __FUNCTION__); + return(0); +} + + +int trx_benetel_set_freq(openair0_device* device, + openair0_config_t *openair0_cfg, + int exmimo_dump_config) +{ + printf("BENETEL: %s\n", __FUNCTION__); + return(0); +} + + +int trx_benetel_set_gains(openair0_device* device, + openair0_config_t *openair0_cfg) +{ + printf("BENETEL: %s\n", __FUNCTION__); + return(0); +} + + +int trx_benetel_get_stats(openair0_device* device) +{ + printf("BENETEL: %s\n", __FUNCTION__); + return(0); +} + + +int trx_benetel_reset_stats(openair0_device* device) +{ + printf("BENETEL: %s\n", __FUNCTION__); + return(0); +} + + +int ethernet_tune(openair0_device *device, + unsigned int option, + int value) +{ + printf("BENETEL: %s\n", __FUNCTION__); + return 0; +} + +int trx_benetel_write_raw(openair0_device *device, + openair0_timestamp timestamp, + void **buff, int nsamps, int cc, int flags) +{ + printf("BENETEL: %s\n", __FUNCTION__); + return nsamps*4; +} + +int trx_benetel_read_raw(openair0_device *device, + openair0_timestamp *timestamp, + void **buff, int nsamps, int cc) +{ + printf("BENETEL: %s\n", __FUNCTION__); + return nsamps*4; +} + +char *msg_type(int t) +{ + static char *s[12] = { + "RAU_tick", + "RRU_capabilities", + "RRU_config", + "RRU_config_ok", + "RRU_start", + "RRU_stop", + "RRU_sync_ok", + "RRU_frame_resynch", + "RRU_MSG_max_num", + "RRU_check_sync", + "RRU_config_update", + "RRU_config_update_ok", + }; + + if (t < 0 || t > 11) return "UNKNOWN"; + return s[t]; +} + +int trx_benetel_ctlsend(openair0_device *device, void *msg, ssize_t msg_len) +{ + RRU_CONFIG_msg_t *rru_config_msg = msg; + benetel_eth_state_t *s = device->priv; + + printf("BENETEL: %s\n", __FUNCTION__); + + printf(" rru_config_msg->type %d [%s]\n", rru_config_msg->type, + msg_type(rru_config_msg->type)); + + s->last_msg = rru_config_msg->type; + + return msg_len; +} + +int trx_benetel_ctlrecv(openair0_device *device, void *msg, ssize_t msg_len) +{ + RRU_CONFIG_msg_t *rru_config_msg = msg; + benetel_eth_state_t *s = device->priv; + + printf("BENETEL: %s\n", __FUNCTION__); + + if (s->last_msg == RAU_tick && s->capabilities_sent == 0) { + RRU_capabilities_t *cap; + rru_config_msg->type = RRU_capabilities; + rru_config_msg->len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE+sizeof(RRU_capabilities_t); + cap = (RRU_capabilities_t*)&rru_config_msg->msg[0]; + cap->FH_fmt = OAI_IF4p5_only; + cap->num_bands = 1; + cap->band_list[0] = 78; + cap->nb_rx[0] = 1; + cap->nb_tx[0] = 1; + cap->max_pdschReferenceSignalPower[0] = -27; + cap->max_rxgain[0] = 90; + + s->capabilities_sent = 1; + + return rru_config_msg->len; + } +#if 0 + if (s->last_msg == RRU_config) { + rru_config_msg->type = RRU_config_ok; + return 0; + } + if (s->last_msg == RRU_start) { +printf("***************** benetel start\n"); + s->benetel_priv = benetel_start(s->e.if_name, &s->buffers, s->dpdk_main_command_line); + } +#endif + if (s->last_msg == RRU_config) { + rru_config_msg->type = RRU_config_ok; + s->benetel_priv = benetel_start(s->e.if_name, &s->buffers, s->dpdk_main_command_line); + } + /* correct? */ +//printf("***************** benetel pause\n"); +// while (1) pause(); + + return 0; +} + +void benetel_fh_if4p5_south_in(RU_t *ru, + int *frame, + int *slot) +{ +//printf("XXX benetel_fh_if4p5_south_in %d %d\n", *frame, *slot); + benetel_eth_state_t *s = ru->ifdevice.priv; + NR_DL_FRAME_PARMS *fp; + int symbol; + int32_t *rxdata; + int antenna = 0; + + lock_ul_buffer(&s->buffers, *slot); +#if 1 +next: + while (!(s->buffers.ul_busy[*slot] == 0x3fff || + s->buffers.prach_busy[*slot] == 1)) + wait_ul_buffer(&s->buffers, *slot); + if (s->buffers.prach_busy[*slot] == 1) { + int i; + int antenna = 0; + uint16_t *in; + uint16_t *out; + in = (uint16_t *)s->buffers.prach[*slot]; + out = (uint16_t *)ru->prach_rxsigF[antenna]; + for (i = 0; i < 839*2; i++) + out[i] = ntohs(in[i]); + s->buffers.prach_busy[*slot] = 0; + //printf("prach for f.sl %d.%d\n", *frame, *slot); + //ru->wakeup_prach_gNB(ru->gNB_list[0], ru, *frame, *slot); + goto next; + } +#endif + + fp = ru->nr_frame_parms; + for (symbol = 0; symbol < 14; symbol++) { + int i; + uint16_t *p = (uint16_t *)(&s->buffers.ul[*slot][symbol*1272*4]); + for (i = 0; i < 1272*2; i++) { + p[i] = htons(p[i]); + } + rxdata = &ru->common.rxdataF[antenna][symbol * fp->ofdm_symbol_size]; +#if 1 + memcpy(rxdata + 2048 - 1272/2, + &s->buffers.ul[*slot][symbol*1272*4], + (1272/2) * 4); + memcpy(rxdata, + &s->buffers.ul[*slot][symbol*1272*4] + (1272/2)*4, + (1272/2) * 4); +#endif + } + + s->buffers.ul_busy[*slot] = 0; + signal_ul_buffer(&s->buffers, *slot); + unlock_ul_buffer(&s->buffers, *slot); + + //printf("BENETEL: %s (f.sf %d.%d)\n", __FUNCTION__, *frame, *slot); + + RU_proc_t *proc = &ru->proc; + extern uint16_t sl_ahead; + int f = *frame; + int sl = *slot; + + //calculate timestamp_rx, timestamp_tx based on frame and slot + proc->tti_rx = sl; + proc->frame_rx = f; + /* TODO: be sure of samples_per_slot0 + FK: should use get_samples_per_slot(slot) + but for mu=1 its ok + */ + proc->timestamp_rx = ((proc->frame_rx * 20) + proc->tti_rx ) * fp->samples_per_slot0; + + if (get_nprocs()<=4) { + // why? what if there are more? + proc->tti_tx = (sl+sl_ahead)%20; + proc->frame_tx = (sl>(19-sl_ahead)) ? (f+1)&1023 : f; + } +} + +void benetel_fh_if4p5_south_out(RU_t *ru, + int frame, + int slot, + uint64_t timestamp) +{ +//printf("XXX benetel_fh_if4p5_south_out %d %d %ld\n", frame, slot, timestamp); + benetel_eth_state_t *s = ru->ifdevice.priv; + NR_DL_FRAME_PARMS *fp; + int symbol; + int32_t *txdata; + int aa = 0; + + //printf("BENETEL: %s (f.sf %d.%d ts %ld)\n", __FUNCTION__, frame, slot, timestamp); + + lock_dl_buffer(&s->buffers, slot); + if (s->buffers.dl_busy[slot]) { + printf("%s: fatal: DL buffer busy for subframe %d\n", __FUNCTION__, slot); + unlock_dl_buffer(&s->buffers, slot); + return; + } + + fp = ru->nr_frame_parms; + if (ru->num_gNB != 1 || ru->nb_tx != 1 || fp->ofdm_symbol_size != 2048 || + fp->Ncp != NORMAL || fp->symbols_per_slot != 14) { + printf("%s:%d:%s: unsupported configuration\n", + __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + for (symbol = 0; symbol < 14; symbol++) { + txdata = &ru->common.txdataF_BF[aa][symbol * fp->ofdm_symbol_size]; +#if 1 + memcpy(&s->buffers.dl[slot][symbol*1272*4], + txdata + 2048 - (1272/2), + (1272/2) * 4); + memcpy(&s->buffers.dl[slot][symbol*1272*4] + (1272/2)*4, + txdata, + (1272/2) * 4); +#endif + int i; + uint16_t *p = (uint16_t *)(&s->buffers.dl[slot][symbol*1272*4]); + for (i = 0; i < 1272*2; i++) { + p[i] = htons(p[i]); + } + } + + s->buffers.dl_busy[slot] = 0x3fff; + unlock_dl_buffer(&s->buffers, slot); +} + +void *get_internal_parameter(char *name) +{ + printf("BENETEL: %s\n", __FUNCTION__); + + if (!strcmp(name, "fh_if4p5_south_in")) + return benetel_fh_if4p5_south_in; + if (!strcmp(name, "fh_if4p5_south_out")) + return benetel_fh_if4p5_south_out; + + return NULL; +} + +__attribute__((__visibility__("default"))) +int transport_init(openair0_device *device, + openair0_config_t *openair0_cfg, + eth_params_t * eth_params ) +{ + benetel_eth_state_t *eth; + + printf("BENETEL: %s\n", __FUNCTION__); + + device->Mod_id = 0; + device->transp_type = ETHERNET_TP; + device->trx_start_func = trx_benetel_start; + device->trx_get_stats_func = trx_benetel_get_stats; + device->trx_reset_stats_func = trx_benetel_reset_stats; + device->trx_end_func = trx_benetel_end; + device->trx_stop_func = trx_benetel_stop; + device->trx_set_freq_func = trx_benetel_set_freq; + device->trx_set_gains_func = trx_benetel_set_gains; + + device->trx_write_func = trx_benetel_write_raw; + device->trx_read_func = trx_benetel_read_raw; + + device->trx_ctlsend_func = trx_benetel_ctlsend; + device->trx_ctlrecv_func = trx_benetel_ctlrecv; + + device->get_internal_parameter = get_internal_parameter; + + eth = calloc(1, sizeof(benetel_eth_state_t)); + if (eth == NULL) { + AssertFatal(0==1, "out of memory\n"); + } + + eth->e.flags = ETH_RAW_IF4p5_MODE; + eth->e.compression = NO_COMPRESS; + eth->e.if_name = eth_params->local_if_name; + device->priv = eth; + device->openair0_cfg=&openair0_cfg[0]; + + if (openair0_cfg->sdr_addrs == NULL) { + printf("benetel: fatal: sdr_addrs not set in configuration file\n"); + exit(1); + } + + eth->dpdk_main_command_line = strdup(openair0_cfg->sdr_addrs); + if (eth->dpdk_main_command_line == NULL) { + AssertFatal(0==1, "out of memory\n"); + } + + eth->last_msg = -1; + + init_buffers(ð->buffers); + + return 0; +} diff --git a/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c b/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c new file mode 100644 index 0000000000..b90702d331 --- /dev/null +++ b/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c @@ -0,0 +1,856 @@ +/* license: to be defined */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "low.h" + +// HEADER DEFINITION +#define ANT_NUM buf[23] +#define PAYLOAD_1 buf[20] +#define PAYLOAD_2 buf[21] +#define ETH_TYPE buf[17] +#define SYMBOL buf[29] +#define SUBFRAME buf[28] +#define FRAME buf[27] + +static volatile bool force_quit; + +unsigned short iq[712320]; +unsigned char iq_swap[1424640]; + +unsigned short *iq_ptr[14]; +unsigned int dl_start = 0, slot_id_ctrl = 0, count_symbol = 0, sf = 0x10; + +/* MAC updating enabled by default */ +static int mac_updating = 1; +#define RTE_LOGTYPE_L2FWD RTE_LOGTYPE_USER1 +#define MAX_PKT_BURST 32 +#define BURST_TX_DRAIN_US 5 /* TX drain every ~100us */ +#define MEMPOOL_CACHE_SIZE 256 +/* + * Configurable number of RX/TX ring descriptors + */ +#define RTE_TEST_RX_DESC_DEFAULT 1024 +#define RTE_TEST_TX_DESC_DEFAULT 1024 +static uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; +static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; +/* ethernet addresses of ports */ +static struct ether_addr l2fwd_ports_eth_addr[RTE_MAX_ETHPORTS]; +/* mask of enabled ports */ +static uint32_t l2fwd_enabled_port_mask = 0; +/* list of enabled ports */ +static uint32_t l2fwd_dst_ports[RTE_MAX_ETHPORTS]; +static unsigned int l2fwd_rx_queue_per_lcore = 1; +#define MAX_RX_QUEUE_PER_LCORE 16 +#define MAX_TX_QUEUE_PER_PORT 16 +struct lcore_queue_conf { + unsigned n_rx_port; + unsigned rx_port_list[MAX_RX_QUEUE_PER_LCORE]; +} __rte_cache_aligned; +struct lcore_queue_conf lcore_queue_conf[RTE_MAX_LCORE]; +static struct rte_eth_dev_tx_buffer *tx_buffer[RTE_MAX_ETHPORTS]; +static struct rte_eth_conf port_conf = { + .rxmode = { + .split_hdr_size = 0, + .offloads = DEV_RX_OFFLOAD_CRC_STRIP, + .offloads = DEV_RX_OFFLOAD_JUMBO_FRAME, + .split_hdr_size = 0, + .max_rx_pkt_len = 9500, + }, + .txmode = { + .mq_mode = ETH_MQ_TX_NONE, + }, +}; +struct rte_mempool * l2fwd_pktmbuf_pool = NULL; +/* Per-port statistics struct */ +struct l2fwd_port_statistics { + uint64_t tx; + uint64_t rx; + uint64_t dropped; +} __rte_cache_aligned; +struct l2fwd_port_statistics port_statistics[RTE_MAX_ETHPORTS]; +#define MAX_TIMER_PERIOD 86400 /* 1 day max */ +/* A tsc-based timer responsible for triggering statistics printout */ +static uint64_t timer_period = 10; /* default period is 10 seconds */ +/* Print out statistics on packets dropped */ +static void +print_stats(void) +{ + uint64_t total_packets_dropped, total_packets_tx, total_packets_rx; + unsigned portid; + total_packets_dropped = 0; + total_packets_tx = 0; + total_packets_rx = 0; + const char clr[] = { 27, '[', '2', 'J', '\0' }; + const char topLeft[] = { 27, '[', '1', ';', '1', 'H','\0' }; + /* Clear screen and move to top left */ + printf("%s%s", clr, topLeft); + printf("\nPort statistics ===================================="); + for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) { + /* skip disabled ports */ + if ((l2fwd_enabled_port_mask & (1 << portid)) == 0) + continue; + printf("\nStatistics for port %u ------------------------------" + "\nPackets sent: %24"PRIu64 + "\nPackets received: %20"PRIu64 + "\nPackets dropped: %21"PRIu64, + portid, + port_statistics[portid].tx, + port_statistics[portid].rx, + port_statistics[portid].dropped); + total_packets_dropped += port_statistics[portid].dropped; + total_packets_tx += port_statistics[portid].tx; + total_packets_rx += port_statistics[portid].rx; + } + printf("\nAggregate statistics ===============================" + "\nTotal packets sent: %18"PRIu64 + "\nTotal packets received: %14"PRIu64 + "\nTotal packets dropped: %15"PRIu64, + total_packets_tx, + total_packets_rx, + total_packets_dropped); + printf("\n====================================================\n"); +} +static void +l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) +{ + unsigned char *buf, *buf_tx; + unsigned int len; + struct ether_hdr *eth; + + unsigned dst_port; + int sent, prach_ctrl = 0; + struct rte_eth_dev_tx_buffer *buffer; + + unsigned char * IQ_ptr; + + ul_packet_t p; + + buf = rte_pktmbuf_mtod(m, unsigned char *); + //DD Debug + //rte_memdump(stdout, "Rx Packet",buf ,34); + eth = rte_pktmbuf_mtod(m, struct ether_hdr *); + len = rte_pktmbuf_data_len(m); + + IQ_ptr = &buf[34]; + if (portid == 0) + { + //destination mac address (RRU MAC) + /*eth->d_addr.addr_bytes[0] = 0x02; + eth->d_addr.addr_bytes[1] = 0x00; + eth->d_addr.addr_bytes[2] = 0x5e; + eth->d_addr.addr_bytes[3] = 0x01; + eth->d_addr.addr_bytes[4] = 0x01; + eth->d_addr.addr_bytes[5] = 0x01;*/ + + eth->d_addr.addr_bytes[0] = buf[6]; + eth->d_addr.addr_bytes[1] = buf[7]; + eth->d_addr.addr_bytes[2] = buf[8]; + eth->d_addr.addr_bytes[3] = buf[9]; + eth->d_addr.addr_bytes[4] = buf[10]; + eth->d_addr.addr_bytes[5] = buf[11]; + + //source mac address (DU MAC) + eth->s_addr.addr_bytes[0] = 0xdd; + eth->s_addr.addr_bytes[1] = 0xdd; + eth->s_addr.addr_bytes[2] = 0xdd; + eth->s_addr.addr_bytes[3] = 0xdd; + eth->s_addr.addr_bytes[4] = 0xdd; + eth->s_addr.addr_bytes[5] = 0xdd; + } + else + { + //destination mac address (RRU MAC) + /*eth->d_addr.addr_bytes[0] = 0x02; + eth->d_addr.addr_bytes[1] = 0x00; + eth->d_addr.addr_bytes[2] = 0x5e; + eth->d_addr.addr_bytes[3] = 0x01; + eth->d_addr.addr_bytes[4] = 0x01; + eth->d_addr.addr_bytes[5] = 0x01;*/ + + eth->d_addr.addr_bytes[0] = buf[6]; + eth->d_addr.addr_bytes[1] = buf[7]; + eth->d_addr.addr_bytes[2] = buf[8]; + eth->d_addr.addr_bytes[3] = buf[9]; + eth->d_addr.addr_bytes[4] = buf[10]; + eth->d_addr.addr_bytes[5] = buf[11]; + //source mac address (DU MAC) + eth->s_addr.addr_bytes[0] = 0xdd; + eth->s_addr.addr_bytes[1] = 0xdd; + eth->s_addr.addr_bytes[2] = 0xdd; + eth->s_addr.addr_bytes[3] = 0xdd; + eth->s_addr.addr_bytes[4] = 0xdd; + eth->s_addr.addr_bytes[5] = 0xde; + + } + dst_port = l2fwd_dst_ports[portid]; + //DD Debug + //printf("dstPort =%d\n", dst_port); + // Handshake Condition + if (buf[18] == 0xAA ) // ORAN handshake msgs. + { + printf("\n Start UP Request Received\n"); + printf("\n====================================================\n"); + + buf[18] = 0xBB;//change to msg2 after receive msg1 + + printf(" Start Up Response Sent\n"); + printf("\n====================================================\n"); + + } + + // Trigger start send DL packets + if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4 && SYMBOL == 0x46 && ANT_NUM == 0x00 && SUBFRAME == 0x00 && dl_start == 0){ + + printf("\nU-Plane Started\n"); + printf("\n====================================================\n"); + + dl_start = 1; + count_symbol = 28; + } + + + if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4 && ANT_NUM == 0x00) { + int subframe = SUBFRAME >> 4; + int slot = ((SUBFRAME & 0x0f) << 2) | ((SYMBOL >> 6) & 0x03); + p.frame = FRAME; + p.slot = subframe * 2 + slot; + p.symbol = SYMBOL & 0x3f; + p.antenna = 0; + memcpy(p.iq, IQ_ptr, 5088); + store_ul(bs, &p); + //if (p.symbol==0) printf("store ul f.sl.sy %d.%d.%d\n", p.frame, p.slot, p.symbol); + } + + // U-PLANE UL ANT_0 PROCESSING + if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4 && ANT_NUM == 0x00 && dl_start == 1) + { + int frame = FRAME; + int subframe = SUBFRAME >> 4; + int slot = ((SUBFRAME & 0x0f) << 2) | ((SYMBOL >> 6) & 0x03); + int symbol = SYMBOL & 0x3f; + int oai_slot; + + int tx_frame = frame; + int tx_subframe = subframe; + int tx_slot = slot; + int tx_symbol = symbol + 8; + + if (tx_symbol > 13) { + tx_symbol -= 14; + tx_slot++; + if (tx_slot == 2) { + tx_slot = 0; + tx_subframe++; + if (tx_subframe == 10) { + tx_subframe = 0; + tx_frame = (tx_frame + 1) & 255; + } + } + } + + ANT_NUM = 0x00; + + // Mask the symbol bits from UL packet received and apply the shift. + SYMBOL = ((SYMBOL & 0b00111111) + 8) % 14; + + ANT_NUM = 0x00; + SUBFRAME = sf; + + // Slot id control for DL + if(slot_id_ctrl > 13){ + SYMBOL = SYMBOL | 0b01000000; + } + + /* antenna 0 - send actual DL data (if available) */ + oai_slot = tx_subframe * 2 + tx_slot; + lock_dl_buffer(bs->buffers, oai_slot); + if (!(bs->buffers->dl_busy[oai_slot] & (1 << tx_symbol))) { + printf("%s: warning, DL underflow (sl.symbol %d.%d)\n", __FUNCTION__, + oai_slot, tx_symbol); + memset(IQ_ptr, 0, 1272 * 4); + } else { + memcpy(IQ_ptr, bs->buffers->dl[oai_slot] + tx_symbol * 1272*4, + 1272*4); + } + bs->buffers->dl_busy[oai_slot] &= ~(1 << tx_symbol); + unlock_dl_buffer(bs->buffers, oai_slot); + + // fill DL Data for ant 0 with 0 value +// memset(IQ_ptr, 0, 5088); + } + + // U-PLANE UL ANT_1 PROCESSING + if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4 && ANT_NUM == 0x01 && dl_start == 1) + { + + // Mask the symbol bits from UL packet received and apply the shift. + SYMBOL = ((SYMBOL & 0b00111111) + 8) % 14; + + ANT_NUM = 0x01; + SUBFRAME = sf; + + slot_id_ctrl++; + + // Slot id control for DL + if(slot_id_ctrl > 13){ + SYMBOL = SYMBOL | 0b01000000; + + if(slot_id_ctrl > 27){ + slot_id_ctrl = 0; + sf = sf + 0x10; + + if (sf >0x90){ + sf = 0; + } + } + } + + // fill DL Data for ant 1 with 0 value + memset(IQ_ptr, 0, 5088); + } + + // U-PLANE PRACH PROCESSING + else if(PAYLOAD_1 == 0x0d && PAYLOAD_2 == 0x28){ + if (ANT_NUM == 0) { + int subframe = SUBFRAME >> 4; + int slot = ((SUBFRAME & 0x0f) << 2) | ((SYMBOL >> 6) & 0x03); + if (subframe==9) { + //printf("store prach f.sf.sl %d.%d.%d %d\n", FRAME, subframe, slot, subframe * 2 + slot); + store_prach(bs, FRAME, slot /*subframe * 2 + slot*/, IQ_ptr); + } + } + rte_pktmbuf_free(m); + return; + } + + // Send Packets + buffer = tx_buffer[dst_port]; + + sent = rte_eth_tx_buffer(dst_port, 0, buffer, m); + + if (sent) + port_statistics[dst_port].tx += sent; + +} +/* main processing loop */ +static void +l2fwd_main_loop(benetel_t *bs) +{ + struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; + struct rte_mbuf *m; + int sent; + unsigned lcore_id; + uint64_t prev_tsc, diff_tsc, cur_tsc, timer_tsc; + unsigned i, j, portid, nb_rx; + struct lcore_queue_conf *qconf; + const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) / US_PER_S * + BURST_TX_DRAIN_US; + struct rte_eth_dev_tx_buffer *buffer; + prev_tsc = 0; + timer_tsc = 0; + lcore_id = rte_lcore_id(); + qconf = &lcore_queue_conf[lcore_id]; + if (qconf->n_rx_port == 0) { + RTE_LOG(INFO, L2FWD, "lcore %u has nothing to do\n", lcore_id); + return; + } + RTE_LOG(INFO, L2FWD, "entering main loop on lcore %u\n", lcore_id); + for (i = 0; i < qconf->n_rx_port; i++) { + portid = qconf->rx_port_list[i]; + RTE_LOG(INFO, L2FWD, " -- lcoreid=%u portid=%u\n", lcore_id, + portid); + } + while (!force_quit) { + cur_tsc = rte_rdtsc(); + /* + * TX burst queue drain + */ + diff_tsc = cur_tsc - prev_tsc; + if (unlikely(diff_tsc > drain_tsc)) { + for (i = 0; i < qconf->n_rx_port; i++) { + portid = l2fwd_dst_ports[qconf->rx_port_list[i]]; + buffer = tx_buffer[portid]; + sent = rte_eth_tx_buffer_flush(portid, 0, buffer); + if (sent) + port_statistics[portid].tx += sent; + } + /* if timer is enabled */ + if (timer_period > 0) { + /* advance the timer */ + timer_tsc += diff_tsc; + /* if timer has reached its timeout */ + if (unlikely(timer_tsc >= timer_period)) { + /* do this only on master core */ + if (lcore_id == rte_get_master_lcore()) { + print_stats(); + /* reset the timer */ + timer_tsc = 0; + } + } + } + prev_tsc = cur_tsc; + } + /* + * Read packet from RX queues + */ + for (i = 0; i < qconf->n_rx_port; i++) { + portid = qconf->rx_port_list[i]; + nb_rx = rte_eth_rx_burst(portid, 0, + pkts_burst, MAX_PKT_BURST); + port_statistics[portid].rx += nb_rx; + for (j = 0; j < nb_rx; j++) { + m = pkts_burst[j]; + rte_prefetch0(rte_pktmbuf_mtod(m, void *)); + l2fwd_simple_forward(m, portid, bs); + } + } + } +} +static int +l2fwd_launch_one_lcore(void *bs) +{ + l2fwd_main_loop(bs); + return 0; +} +/* display usage */ +static void +l2fwd_usage(const char *prgname) +{ + printf("%s [EAL options] -- -p PORTMASK [-q NQ]\n" + " -p PORTMASK: hexadecimal bitmask of ports to configure\n" + " -q NQ: number of queue (=ports) per lcore (default is 1)\n" + " -T PERIOD: statistics will be refreshed each PERIOD seconds (0 to disable, 10 default, 86400 maximum)\n" + " --[no-]mac-updating: Enable or disable MAC addresses updating (enabled by default)\n" + " When enabled:\n" + " - The source MAC address is replaced by the TX port MAC address\n" + " - The destination MAC address is replaced by 02:00:00:00:00:TX_PORT_ID\n", + prgname); +} +static int +l2fwd_parse_portmask(const char *portmask) +{ + char *end = NULL; + unsigned long pm; + /* parse hexadecimal string */ + pm = strtoul(portmask, &end, 16); + if ((portmask[0] == '\0') || (end == NULL) || (*end != '\0')) + return -1; + if (pm == 0) + return -1; + return pm; +} +static unsigned int +l2fwd_parse_nqueue(const char *q_arg) +{ + char *end = NULL; + unsigned long n; + /* parse hexadecimal string */ + n = strtoul(q_arg, &end, 10); + if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0')) + return 0; + if (n == 0) + return 0; + if (n >= MAX_RX_QUEUE_PER_LCORE) + return 0; + return n; +} +static int +l2fwd_parse_timer_period(const char *q_arg) +{ + char *end = NULL; + int n; + /* parse number string */ + n = strtol(q_arg, &end, 10); + if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0')) + return -1; + if (n >= MAX_TIMER_PERIOD) + return -1; + return n; +} +static const char short_options[] = + "p:" /* portmask */ + "q:" /* number of queues */ + "T:" /* timer period */ + ; +#define CMD_LINE_OPT_MAC_UPDATING "mac-updating" +#define CMD_LINE_OPT_NO_MAC_UPDATING "no-mac-updating" +enum { + /* long options mapped to a short option */ + /* first long only option value must be >= 256, so that we won't + * conflict with short options */ + CMD_LINE_OPT_MIN_NUM = 256, +}; +static const struct option lgopts[] = { + { CMD_LINE_OPT_MAC_UPDATING, no_argument, &mac_updating, 1}, + { CMD_LINE_OPT_NO_MAC_UPDATING, no_argument, &mac_updating, 0}, + {NULL, 0, 0, 0} +}; +/* Parse the argument given in the command line of the application */ +static int +l2fwd_parse_args(int argc, char **argv) +{ + int opt, ret, timer_secs; + char **argvopt; + int option_index; + char *prgname = argv[0]; + argvopt = argv; + while ((opt = getopt_long(argc, argvopt, short_options, + lgopts, &option_index)) != EOF) { + switch (opt) { + /* portmask */ + case 'p': + l2fwd_enabled_port_mask = l2fwd_parse_portmask(optarg); + if (l2fwd_enabled_port_mask == 0) { + printf("invalid portmask\n"); + l2fwd_usage(prgname); + return -1; + } + break; + /* nqueue */ + case 'q': + l2fwd_rx_queue_per_lcore = l2fwd_parse_nqueue(optarg); + if (l2fwd_rx_queue_per_lcore == 0) { + printf("invalid queue number\n"); + l2fwd_usage(prgname); + return -1; + } + break; + /* timer period */ + case 'T': + timer_secs = l2fwd_parse_timer_period(optarg); + if (timer_secs < 0) { + printf("invalid timer period\n"); + l2fwd_usage(prgname); + return -1; + } + timer_period = timer_secs; + break; + /* long options */ + case 0: + break; + case 'proc-type': + break; + case 'socket-mem': + break; + case 'file-prefix': + l2fwd_rx_queue_per_lcore = l2fwd_parse_nqueue(optarg); + if (l2fwd_rx_queue_per_lcore == 0) { + printf("invalid queue number\n"); + l2fwd_usage(prgname); + return -1; + } + break; + /* timer period */ + /* timer period */ + /* timer period */ + default: + l2fwd_usage(prgname); + return -1; + } + } + if (optind >= 0) + argv[optind-1] = prgname; + ret = optind-1; + optind = 1; /* reset getopt lib */ + return ret; +} +/* Check the link status of all ports in up to 9s, and print them finally */ +static void +check_all_ports_link_status(uint32_t port_mask) +{ +#define CHECK_INTERVAL 100 /* 100ms */ +#define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */ + uint16_t portid; + uint8_t count, all_ports_up, print_flag = 0; + struct rte_eth_link link; + printf("\nChecking link status"); + fflush(stdout); + for (count = 0; count <= MAX_CHECK_TIME; count++) { + if (force_quit) + return; + all_ports_up = 1; + RTE_ETH_FOREACH_DEV(portid) { + if (force_quit) + return; + if ((port_mask & (1 << portid)) == 0) + continue; + memset(&link, 0, sizeof(link)); + rte_eth_link_get_nowait(portid, &link); + /* print link status if flag set */ + if (print_flag == 1) { + if (link.link_status) + printf( + "Port%d Link Up. Speed %u Mbps - %s\n", + portid, link.link_speed, + (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? + ("full-duplex") : ("half-duplex\n")); + else + printf("Port %d Link Down\n", portid); + continue; + } + /* clear all_ports_up flag if any link down */ + if (link.link_status == ETH_LINK_DOWN) { + all_ports_up = 0; + break; + } + } + /* after finally printing all link status, get out */ + if (print_flag == 1) + break; + if (all_ports_up == 0) { + printf("."); + fflush(stdout); + rte_delay_ms(CHECK_INTERVAL); + } + /* set the print_flag if all ports up or timeout */ + if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) { + print_flag = 1; + printf("done\n"); + } + } +} +static void +signal_handler(int signum) +{ + if (signum == SIGINT || signum == SIGTERM) { + printf("\n\nSignal %d received, preparing to exit...\n", + signum); + force_quit = true; + } +} +int +dpdk_main(int argc, char **argv, benetel_t *bs) +{ + struct lcore_queue_conf *qconf; + int ret; + uint16_t nb_ports; + uint16_t nb_ports_available = 0; + uint16_t portid, last_port; + unsigned lcore_id, rx_lcore_id; + unsigned nb_ports_in_mask = 0; + unsigned int nb_lcores = 0; + unsigned int nb_mbufs; + /* init EAL */ + ret = rte_eal_init(argc, argv); + if (ret < 0) + rte_exit(EXIT_FAILURE, "Invalid EAL arguments\n"); + argc -= ret; + argv += ret; + force_quit = false; + signal(SIGINT, signal_handler); + signal(SIGTERM, signal_handler); + /* parse application arguments (after the EAL ones) */ + ret = l2fwd_parse_args(argc, argv); + if (ret < 0) + rte_exit(EXIT_FAILURE, "Invalid L2FWD arguments\n"); + printf("MAC updating %s\n", mac_updating ? "enabled" : "disabled"); + /* convert to number of cycles */ + timer_period *= rte_get_timer_hz(); + nb_ports = rte_eth_dev_count_avail(); + if (nb_ports == 0) + rte_exit(EXIT_FAILURE, "No Ethernet ports - bye\n"); + /* check port mask to possible port mask */ + if (l2fwd_enabled_port_mask & ~((1 << nb_ports) - 1)) + rte_exit(EXIT_FAILURE, "Invalid portmask; possible (0x%x)\n", + (1 << nb_ports) - 1); + /* reset l2fwd_dst_ports */ + for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) + l2fwd_dst_ports[portid] = 0; + last_port = 0; + /* + * Each logical core is assigned a dedicated TX queue on each port. + */ + RTE_ETH_FOREACH_DEV(portid) { + /* skip ports that are not enabled */ + if ((l2fwd_enabled_port_mask & (1 << portid)) == 0) + continue; + if (nb_ports_in_mask % 2) { + l2fwd_dst_ports[portid] = last_port; + l2fwd_dst_ports[last_port] = portid; + } + else + last_port = portid; + nb_ports_in_mask++; + } + if (nb_ports_in_mask % 2) { + printf("Notice: odd number of ports in portmask.\n"); + l2fwd_dst_ports[last_port] = last_port; + } + rx_lcore_id = 0; + qconf = NULL; + /* Initialize the port/queue configuration of each logical core */ + RTE_ETH_FOREACH_DEV(portid) { + /* skip ports that are not enabled */ + if ((l2fwd_enabled_port_mask & (1 << portid)) == 0) + continue; + /* get the lcore_id for this port */ + while (rte_lcore_is_enabled(rx_lcore_id) == 0 || + lcore_queue_conf[rx_lcore_id].n_rx_port == + l2fwd_rx_queue_per_lcore) { + rx_lcore_id++; + if (rx_lcore_id >= RTE_MAX_LCORE) + rte_exit(EXIT_FAILURE, "Not enough cores\n"); + } + if (qconf != &lcore_queue_conf[rx_lcore_id]) { + /* Assigned a new logical core in the loop above. */ + qconf = &lcore_queue_conf[rx_lcore_id]; + nb_lcores++; + } + qconf->rx_port_list[qconf->n_rx_port] = portid; + qconf->n_rx_port++; + printf("Lcore %u: RX port %u\n", rx_lcore_id, portid); + } + nb_mbufs = RTE_MAX(nb_ports * (nb_rxd + nb_txd + MAX_PKT_BURST + + nb_lcores * MEMPOOL_CACHE_SIZE), 8192U); + /* create the mbuf pool */ + //DD Debug + //printf ("Proc Type %d \n", rte_eal_process_type()); + l2fwd_pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", nb_mbufs, + MEMPOOL_CACHE_SIZE, 0, 9680, + rte_socket_id()); + if (l2fwd_pktmbuf_pool == NULL) + rte_exit(EXIT_FAILURE, "Cannot init mbuf pool\n"); + /* Initialise each port */ + RTE_ETH_FOREACH_DEV(portid) { + struct rte_eth_rxconf rxq_conf; + struct rte_eth_txconf txq_conf; + struct rte_eth_conf local_port_conf = port_conf; + struct rte_eth_dev_info dev_info; + /* skip ports that are not enabled */ + if ((l2fwd_enabled_port_mask & (1 << portid)) == 0) { + printf("Skipping disabled port %u\n", portid); + continue; + } + nb_ports_available++; + /* init port */ + printf("Initializing port %u... ", portid); + fflush(stdout); + rte_eth_dev_info_get(portid, &dev_info); + if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE) + local_port_conf.txmode.offloads |= + DEV_TX_OFFLOAD_MBUF_FAST_FREE; + ret = rte_eth_dev_configure(portid, 1, 1, &local_port_conf); + if (ret < 0) + rte_exit(EXIT_FAILURE, "Cannot configure device: err=%d, port=%u\n", + ret, portid); + ret = rte_eth_dev_adjust_nb_rx_tx_desc(portid, &nb_rxd, + &nb_txd); + if (ret < 0) + rte_exit(EXIT_FAILURE, + "Cannot adjust number of descriptors: err=%d, port=%u\n", + ret, portid); + rte_eth_macaddr_get(portid,&l2fwd_ports_eth_addr[portid]); + /* init one RX queue */ + fflush(stdout); + rxq_conf = dev_info.default_rxconf; + rxq_conf.offloads = local_port_conf.rxmode.offloads; + ret = rte_eth_rx_queue_setup(portid, 0, nb_rxd, + rte_eth_dev_socket_id(portid), + &rxq_conf, + l2fwd_pktmbuf_pool); + if (ret < 0) + rte_exit(EXIT_FAILURE, "rte_eth_rx_queue_setup:err=%d, port=%u\n", + ret, portid); + /* init one TX queue on each port */ + fflush(stdout); + txq_conf = dev_info.default_txconf; + txq_conf.offloads = local_port_conf.txmode.offloads; + ret = rte_eth_tx_queue_setup(portid, 0, nb_txd, + rte_eth_dev_socket_id(portid), + &txq_conf); + if (ret < 0) + rte_exit(EXIT_FAILURE, "rte_eth_tx_queue_setup:err=%d, port=%u\n", + ret, portid); + /* Initialize TX buffers */ + tx_buffer[portid] = rte_zmalloc_socket("tx_buffer", + RTE_ETH_TX_BUFFER_SIZE(MAX_PKT_BURST), 0, + rte_eth_dev_socket_id(portid)); + if (tx_buffer[portid] == NULL) + rte_exit(EXIT_FAILURE, "Cannot allocate buffer for tx on port %u\n", + portid); + rte_eth_tx_buffer_init(tx_buffer[portid], MAX_PKT_BURST); + ret = rte_eth_tx_buffer_set_err_callback(tx_buffer[portid], + rte_eth_tx_buffer_count_callback, + &port_statistics[portid].dropped); + if (ret < 0) + rte_exit(EXIT_FAILURE, + "Cannot set error callback for tx buffer on port %u\n", + portid); + /* Start device */ + ret = rte_eth_dev_start(portid); + if (ret < 0) + rte_exit(EXIT_FAILURE, "rte_eth_dev_start:err=%d, port=%u\n", + ret, portid); + printf("done: \n"); + rte_eth_promiscuous_enable(portid); + printf("Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n\n", + portid, + l2fwd_ports_eth_addr[portid].addr_bytes[0], + l2fwd_ports_eth_addr[portid].addr_bytes[1], + l2fwd_ports_eth_addr[portid].addr_bytes[2], + l2fwd_ports_eth_addr[portid].addr_bytes[3], + l2fwd_ports_eth_addr[portid].addr_bytes[4], + l2fwd_ports_eth_addr[portid].addr_bytes[5]); + /* initialize port stats */ + memset(&port_statistics, 0, sizeof(port_statistics)); + } + if (!nb_ports_available) { + rte_exit(EXIT_FAILURE, + "All available ports are disabled. Please set portmask.\n"); + } + check_all_ports_link_status(l2fwd_enabled_port_mask); + ret = 0; + /* launch per-lcore init on every lcore */ + rte_eal_mp_remote_launch(l2fwd_launch_one_lcore, bs, CALL_MASTER); + RTE_LCORE_FOREACH_SLAVE(lcore_id) { + if (rte_eal_wait_lcore(lcore_id) < 0) { + ret = -1; + break; + } + } + RTE_ETH_FOREACH_DEV(portid) { + if ((l2fwd_enabled_port_mask & (1 << portid)) == 0) + continue; + printf("Closing port %d...", portid); + rte_eth_dev_stop(portid); + rte_eth_dev_close(portid); + printf(" Done\n"); + } + printf("Bye...\n"); + return ret; +} diff --git a/targets/ARCH/ETHERNET/benetel/5g/low.c b/targets/ARCH/ETHERNET/benetel/5g/low.c new file mode 100644 index 0000000000..984e401421 --- /dev/null +++ b/targets/ARCH/ETHERNET/benetel/5g/low.c @@ -0,0 +1,97 @@ +/* + * 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 "low.h" + +#include +#include +#include + +void store_ul(benetel_t *bs, ul_packet_t *ul) +{ + /* only antenna 0 for the moment */ + if (ul->antenna != 0) + return; + + if (ul->slot != bs->next_slot || + ul->symbol != bs->next_symbol) { + printf("%s: fatal, expected frame.sl.symbol %d.%d.%d, got %d.%d.%d\n", + __FUNCTION__, + bs->expected_benetel_frame, bs->next_slot, bs->next_symbol, + ul->frame, ul->slot, ul->symbol); + exit(1); + } + + lock_ul_buffer(bs->buffers, bs->next_slot); + if (bs->buffers->ul_busy[bs->next_slot] & (1 << bs->next_symbol)) { + printf("%s: warning, UL overflow (sl.symbol %d.%d)\n", __FUNCTION__, + bs->next_slot, bs->next_symbol); + } + + memcpy(bs->buffers->ul[bs->next_slot] + bs->next_symbol * 1272*4, + ul->iq, 1272*4); + bs->buffers->ul_busy[bs->next_slot] |= (1 << bs->next_symbol); + signal_ul_buffer(bs->buffers, bs->next_slot); + unlock_ul_buffer(bs->buffers, bs->next_slot); + + bs->next_symbol++; + if (bs->next_symbol == 14) { + bs->next_symbol = 0; + bs->next_slot = (bs->next_slot + 1) % 20; + if (bs->next_slot == 0) { + bs->expected_benetel_frame++; + bs->expected_benetel_frame &= 255; + } + } +} + +void store_prach(benetel_t *bs, int frame, int slot, void *data) +{ + static int last_frame = -1; + static int last_slot = -1; + /* hack: antenna number is always 0, discard second packet with same f/sf */ + //if (frame == last_frame && slot == last_slot) return; + if (frame == last_frame && slot == last_slot) { printf("got f.sl %d.%d twice\n", frame, slot); return; } + last_frame = frame; + last_slot = slot; + + lock_ul_buffer(bs->buffers, slot); + if (bs->buffers->prach_busy[slot]) { + printf("store_prach: fatal: previous prach buffer not processed\n"); + unlock_ul_buffer(bs->buffers, slot); + return; + } + bs->buffers->prach_busy[slot] = 1; + memcpy(bs->buffers->prach[slot], data, 839*4); + signal_ul_buffer(bs->buffers, slot); + unlock_ul_buffer(bs->buffers, slot); + +} + +void *benetel_start_dpdk(char *ifname, shared_buffers *buffers, char *dpdk_main_command_line); + +void *benetel_start(char *ifname, shared_buffers *buffers, char *dpdk_main_command_line) +{ + if (!strcmp(ifname, "dpdk")) + return benetel_start_dpdk(ifname, buffers, dpdk_main_command_line); + printf("benetel: fatal: interface %s not supported, only dpdpk is supported\n", ifname); + exit(1); +} diff --git a/targets/ARCH/ETHERNET/benetel/5g/low.h b/targets/ARCH/ETHERNET/benetel/5g/low.h new file mode 100644 index 0000000000..5e1daee9d1 --- /dev/null +++ b/targets/ARCH/ETHERNET/benetel/5g/low.h @@ -0,0 +1,48 @@ +/* + * 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 + */ + +#ifndef _BENETEL_5G_LOW_H_ +#define _BENETEL_5G_LOW_H_ + +#include "shared_buffers.h" + +typedef struct { + shared_buffers *buffers; + int next_slot; + int next_symbol; + int expected_benetel_frame; + char *dpdk_main_command_line; +} benetel_t; + +typedef struct { + int frame; + int slot; + int symbol; + int antenna; + unsigned char iq[5088]; +} ul_packet_t; + +void *benetel_start(char *ifname, shared_buffers *buffers, char *dpdk_main_command_line); + +void store_ul(benetel_t *bs, ul_packet_t *ul); +void store_prach(benetel_t *bs, int frame, int slot, void *data); + +#endif /* _BENETEL_5G_LOW_H_ */ diff --git a/targets/ARCH/ETHERNET/benetel/5g/low_dpdk.c b/targets/ARCH/ETHERNET/benetel/5g/low_dpdk.c new file mode 100644 index 0000000000..5e26f6782e --- /dev/null +++ b/targets/ARCH/ETHERNET/benetel/5g/low_dpdk.c @@ -0,0 +1,118 @@ +/* + * 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 + */ + +/* those 2 lines for CPU_SET */ +#define _GNU_SOURCE +#include + +#include +#include +#include +#include + +#include "low.h" + +int dpdk_main(int argc, char **argv, benetel_t *); + +void *dpdk_thread(void *_bs) +{ + benetel_t *bs = _bs; + int n = 0; + char **v = NULL; // = { "softmodem", "-n", "2", "--file-prefix", "pg2", "-l", "6", "--", "-p", "0x1" }; + char *s = bs->dpdk_main_command_line; + char *tok; + + while ((tok = strtok(s, " ")) != NULL) { + n++; + v = realloc(v, n * sizeof(char *)); + if (v == NULL) { + printf("%s: out of memory\n", __FUNCTION__); + exit(1); + } + v[n-1] = tok; + s = NULL; + } + + dpdk_main(n, v, bs); + exit(1); + return 0; +} + +void *benetel_start_dpdk(char *ifname, shared_buffers *buffers, char *dpdk_main_command_line) +{ + benetel_t *bs; + + bs = calloc(1, sizeof(benetel_t)); + if (bs == NULL) { + printf("%s: out of memory\n", __FUNCTION__); + exit(1); + } + + bs->buffers = buffers; + + bs->expected_benetel_frame = 255; + + bs->dpdk_main_command_line = dpdk_main_command_line; + + pthread_attr_t attr; + + if (pthread_attr_init(&attr) != 0) { + printf("pthread_attr_init failed\n"); + exit(1); + } + + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + CPU_SET(10,&cpuset); + if (pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t), &cpuset) != 0) { + printf("pthread_attr_setaffinity_np failed\n"); + exit(1); + } + + if (pthread_attr_setschedpolicy(&attr, SCHED_FIFO) != 0) { + printf("pthread_attr_setschedpolicy failed\n"); + exit(1); + } + + struct sched_param params; + params.sched_priority = sched_get_priority_max(SCHED_FIFO); + if (sched_get_priority_max(SCHED_FIFO) == -1) { + printf("sched_get_priority_max failed\n"); + exit(1); + } + if (pthread_attr_setschedparam(&attr, ¶ms) != 0) { + printf("pthread_setschedparam failed\n"); + exit(1); + } + + pthread_t t; + if (pthread_create(&t, &attr, dpdk_thread, bs) != 0) { + printf("%s: thread creation failed\n", __FUNCTION__); + exit(1); + } + + if (pthread_attr_destroy(&attr) != 0) { + printf("pthread_attr_init failed\n"); + exit(1); + } + + return bs; +} diff --git a/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.c b/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.c new file mode 100644 index 0000000000..b9da10b380 --- /dev/null +++ b/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.c @@ -0,0 +1,118 @@ +/* + * 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 "shared_buffers.h" + +#include +#include +#include + +void init_buffers(shared_buffers *s) +{ + int slot; + + memset(s, 0, sizeof(*s)); + + for (slot = 0; slot < 20; slot++) { + if (pthread_mutex_init(&s->m_dl[slot], NULL) != 0 || + pthread_cond_init(&s->c_dl[slot], NULL) != 0 || + pthread_mutex_init(&s->m_ul[slot], NULL) != 0 || + pthread_cond_init(&s->c_ul[slot], NULL) != 0) { + printf("%s: error initializing mutex/cond\n", __FUNCTION__); + exit(1); + } + } + + /* the gNB's first transmitted DL slot is 6 but the device + * needs to have slots 1, 2 and 3, 4 and 5 ready. Let's pretend + * they are ready. + */ + s->dl_busy[1] = 0x3fff; + s->dl_busy[2] = 0x3fff; + s->dl_busy[3] = 0x3fff; + s->dl_busy[4] = 0x3fff; + s->dl_busy[5] = 0x3fff; +} + +void lock_dl_buffer(shared_buffers *s, int slot) +{ + if (pthread_mutex_lock(&s->m_dl[slot]) != 0) { + printf("%s: fatal: lock fails\n", __FUNCTION__); + exit(1); + } +} + +void unlock_dl_buffer(shared_buffers *s, int slot) +{ + if (pthread_mutex_unlock(&s->m_dl[slot]) != 0) { + printf("%s: fatal: unlock fails\n", __FUNCTION__); + exit(1); + } +} + +void wait_dl_buffer(shared_buffers *s, int slot) +{ + if (pthread_cond_wait(&s->c_dl[slot], &s->m_dl[slot]) != 0) { + printf("%s: fatal: cond_wait fails\n", __FUNCTION__); + exit(1); + } +} + +void signal_dl_buffer(shared_buffers *s, int slot) +{ + if (pthread_cond_broadcast(&s->c_dl[slot]) != 0) { + printf("%s: fatal: cond_broadcast fails\n", __FUNCTION__); + exit(1); + } +} + +void lock_ul_buffer(shared_buffers *s, int slot) +{ + if (pthread_mutex_lock(&s->m_ul[slot]) != 0) { + printf("%s: fatal: lock fails\n", __FUNCTION__); + printf("%s: fatal: lock fails slot %d\n", __FUNCTION__, slot); + exit(1); + } +} + +void unlock_ul_buffer(shared_buffers *s, int slot) +{ + if (pthread_mutex_unlock(&s->m_ul[slot]) != 0) { + printf("%s: fatal: unlock fails\n", __FUNCTION__); + exit(1); + } +} + +void wait_ul_buffer(shared_buffers *s, int slot) +{ + if (pthread_cond_wait(&s->c_ul[slot], &s->m_ul[slot]) != 0) { + printf("%s: fatal: cond_wait fails\n", __FUNCTION__); + exit(1); + } +} + +void signal_ul_buffer(shared_buffers *s, int slot) +{ + if (pthread_cond_broadcast(&s->c_ul[slot]) != 0) { + printf("%s: fatal: cond_broadcast fails\n", __FUNCTION__); + exit(1); + } +} diff --git a/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.h b/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.h new file mode 100644 index 0000000000..ca7dbd9c8f --- /dev/null +++ b/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.h @@ -0,0 +1,60 @@ +/* + * 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 + */ + +#ifndef _BENETEL_5G_SHARED_BUFFERS_H_ +#define _BENETEL_5G_SHARED_BUFFERS_H_ + +#include +#include + +typedef struct { + unsigned char dl[20][14*1272*4]; + unsigned char ul[20][14*1272*4]; + uint16_t dl_busy[20]; + uint16_t ul_busy[20]; + + pthread_mutex_t m_ul[20]; + pthread_cond_t c_ul[20]; + + pthread_mutex_t m_dl[20]; + pthread_cond_t c_dl[20]; + + unsigned char prach[20][849*4]; + unsigned char prach_busy[20]; + + /* statistics/error counting */ + int ul_overflow; + int dl_underflow; +} shared_buffers; + +void init_buffers(shared_buffers *s); + +void lock_dl_buffer(shared_buffers *s, int slot); +void unlock_dl_buffer(shared_buffers *s, int slot); +void wait_dl_buffer(shared_buffers *s, int slot); +void signal_dl_buffer(shared_buffers *s, int slot); + +void lock_ul_buffer(shared_buffers *s, int slot); +void unlock_ul_buffer(shared_buffers *s, int slot); +void wait_ul_buffer(shared_buffers *s, int slot); +void signal_ul_buffer(shared_buffers *s, int slot); + +#endif /* _BENETEL_5G_SHARED_BUFFERS_H_ */ diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 6e94717a6f..0c89a68dd5 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -108,7 +108,8 @@ typedef struct { int64_t rx_count; int wait_for_first_pps; int use_gps; - int first_tx; + //int first_tx; + //int first_rx; //! timestamp of RX packet openair0_timestamp rx_timestamp; } usrp_state_t; @@ -282,31 +283,28 @@ static int trx_usrp_start(openair0_device *device) { // set pin 5 (Shutdown LNA) to 1 when the radio is transmitting and receiveing (ATR_XX) // (we use full duplex here, because our RX is on all the time - this might need to change later) s->usrp->set_gpio_attr("FP0", "ATR_XX", (1<<5), 0x7f); - // set the output pins to 0 + // set the output pins to 1 s->usrp->set_gpio_attr("FP0", "OUT", 7<<7, 0xf80); - // init recv and send streaming - uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); - LOG_I(HW,"Time in secs now: %llu \n", s->usrp->get_time_now().to_ticks(s->sample_rate)); - LOG_I(HW,"Time in secs last pps: %llu \n", s->usrp->get_time_last_pps().to_ticks(s->sample_rate)); - - if (s->use_gps == 1 || device->openair0_cfg[0].time_source == external) { - s->wait_for_first_pps = 1; - cmd.time_spec = s->usrp->get_time_last_pps() + uhd::time_spec_t(1.0); - } else { - s->wait_for_first_pps = 0; - cmd.time_spec = s->usrp->get_time_now() + uhd::time_spec_t(0.005); - } - - cmd.stream_now = false; // start at constant delay - s->rx_stream->issue_stream_cmd(cmd); - /*s->tx_md.time_spec = cmd.time_spec + uhd::time_spec_t(1-(double)s->tx_forward_nsamps/s->sample_rate); - s->tx_md.has_time_spec = true; - s->tx_md.start_of_burst = true; - s->tx_md.end_of_burst = false;*/ + s->wait_for_first_pps = 1; s->rx_count = 0; s->tx_count = 0; + //s->first_tx = 1; + //s->first_rx = 1; s->rx_timestamp = 0; + + s->usrp->set_time_next_pps(uhd::time_spec_t(0.0)); + // wait for the pps to change + uhd::time_spec_t time_last_pps = s->usrp->get_time_last_pps(); + while (time_last_pps == s->usrp->get_time_last_pps()) { + boost::this_thread::sleep(boost::posix_time::milliseconds(1)); + } + + uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); + cmd.time_spec = uhd::time_spec_t(1.0); + cmd.stream_now = false; // start at constant delay + s->rx_stream->issue_stream_cmd(cmd); + return 0; } /*! \brief Terminate operation of the USRP transceiver -- free all associated resources @@ -635,7 +633,6 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp int16x8_t buff_tmp[2][nsamps2]; #endif - if (device->type == USRP_B200_DEV) { if (cc>1) { // receive multiple channels (e.g. RF A and RF B) std::vector buff_ptrs; @@ -648,7 +645,7 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp samples_received=0; while (samples_received != nsamps) { - samples_received += s->rx_stream->recv(buff_tmp[0]+samples_received, + samples_received += s->rx_stream->recv((void*)((int32_t*)buff_tmp[0]+samples_received), nsamps-samples_received, s->rx_md); if ((s->wait_for_first_pps == 0) && (s->rx_md.error_code!=uhd::rx_metadata_t::ERROR_CODE_NONE)) @@ -658,7 +655,6 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp printf("sleep...\n"); //usleep(100); } } - if (samples_received == nsamps) s->wait_for_first_pps=0; } @@ -684,22 +680,10 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp #endif } } - } else if (device->type == USRP_X300_DEV) { - if (cc>1) { - // receive multiple channels (e.g. RF A and RF B) - std::vector buff_ptrs; - for (int i=0; irx_stream->recv(buff_ptrs, nsamps, s->rx_md,1.0); - } else { - // receive a single channel (e.g. from connector RF A) - samples_received = s->rx_stream->recv(buff[0], nsamps, s->rx_md,1.0); + if (samples_received < nsamps) { + LOG_E(HW,"[recv] received %d samples out of %d\n",samples_received,nsamps); } - } - - if (samples_received < nsamps) - LOG_E(HW,"[recv] received %d samples out of %d\n",samples_received,nsamps); if ( s->rx_md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) LOG_E(HW, "%s\n", s->rx_md.to_pp_string(true).c_str()); @@ -835,6 +819,17 @@ rx_gain_calib_table_t calib_table_x310[] = { {-1,0} }; +/*! \brief USRPB210 RX calibration table */ +rx_gain_calib_table_t calib_table_n310[] = { + {3500000000.0,0.0}, + {2660000000.0,0.0}, + {2300000000.0,0.0}, + {1880000000.0,0.0}, + {816000000.0, 0.0}, + {-1,0} +}; + + /*! \brief Set RX gain offset * \param openair0_cfg RF frontend parameters set by application * \param chain_index RF chain to apply settings to @@ -984,7 +979,7 @@ extern "C" { if (device_adds[0].get("type") == "n3xx") { printf("Found USRP n300\n"); - device->type=USRP_X300_DEV; //treat it as X300 for now + device->type=USRP_N300_DEV; usrp_master_clock = 122.88e6; args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock); //args += ", send_buff_size=33554432"; @@ -1070,9 +1065,18 @@ extern "C" { if (device->type==USRP_X300_DEV) { openair0_cfg[0].rx_gain_calib_table = calib_table_x310; - std::cerr << "-- Using calibration table: calib_table_x310" << std::endl; // Bell Labs info + std::cerr << "-- Using calibration table: calib_table_x310" << std::endl; + } + + if (device->type==USRP_N300_DEV) { + openair0_cfg[0].rx_gain_calib_table = calib_table_n310; + std::cerr << "-- Using calibration table: calib_table_n310" << std::endl; + } + + + if (device->type==USRP_N300_DEV || device->type==USRP_X300_DEV) { LOG_I(HW,"%s() sample_rate:%u\n", __FUNCTION__, (int)openair0_cfg[0].sample_rate); - + switch ((int)openair0_cfg[0].sample_rate) { case 122880000: // from usrp_time_offset diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c index b330e219ba..93c07a575f 100644 --- a/targets/ARCH/rfsimulator/simulator.c +++ b/targets/ARCH/rfsimulator/simulator.c @@ -459,7 +459,7 @@ int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, voi static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initial) { // Process all incoming events on sockets // store the data in lists - struct epoll_event events[FD_SETSIZE]= {0}; + struct epoll_event events[FD_SETSIZE]= {{0}}; int nfds = epoll_wait(t->epollfd, events, FD_SETSIZE, timeout); if ( nfds==-1 ) { diff --git a/targets/COMMON/threads_t.h b/targets/COMMON/threads_t.h index 0671f40988..5fb1645444 100644 --- a/targets/COMMON/threads_t.h +++ b/targets/COMMON/threads_t.h @@ -1,5 +1,5 @@ -#ifndef _THREADS_T_H_ -#define _THREADS_T_H_ +#ifndef _TARGETS_COMMON_THREADS_T_H_ +#define _TARGETS_COMMON_THREADS_T_H_ typedef struct threads_s { int main; @@ -18,4 +18,4 @@ typedef struct threads_s { //int dlsch_td1_three; } threads_t; -#endif /* _THREADS_T_H_ */ +#endif /* _TARGETS_COMMON_THREADS_T_H_ */ diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf new file mode 100644 index 0000000000..716bfd3b6b --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf @@ -0,0 +1,281 @@ +Active_eNBs = ( "eNB-Eurecom-LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + # real_time choice in {hard, rt-preempt, no} + real_time = "no"; + + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB-Eurecom-LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ( { mcc = 222; mnc = 01; mnc_length = 2; } ); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "NGFI_RCC_IF4p5"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2655000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 100; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + pbch_repetition = "FALSE"; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 90; + pucch_delta_shift = 1; + pucch_nRB_CQI = 0; + pucch_nCS_AN = 0; + pucch_n1_AN = 0; + pdsch_referenceSignalPower = -10; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + + //Parameters for SIB18 + rxPool_sc_CP_Len = "normal"; + rxPool_sc_Period = "sf40"; + rxPool_data_CP_Len = "normal"; + rxPool_ResourceConfig_prb_Num = 20; + rxPool_ResourceConfig_prb_Start = 5; + rxPool_ResourceConfig_prb_End = 44; + rxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + rxPool_ResourceConfig_offsetIndicator_choice = 0; + rxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; +/* rxPool_dataHoppingConfig_hoppingParameter = 0; + rxPool_dataHoppingConfig_numSubbands = "ns1"; + rxPool_dataHoppingConfig_rbOffset = 0; + rxPool_commTxResourceUC-ReqAllowed = "TRUE"; +*/ + // Parameters for SIB19 + discRxPool_cp_Len = "normal" + discRxPool_discPeriod = "rf32" + discRxPool_numRetx = 1; + discRxPool_numRepetition = 2; + discRxPool_ResourceConfig_prb_Num = 5; + discRxPool_ResourceConfig_prb_Start = 3; + discRxPool_ResourceConfig_prb_End = 21; + discRxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + discRxPool_ResourceConfig_offsetIndicator_choice = 0; + discRxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.61.195"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + enable_measurement_reports = "no"; + + ///X2 + enable_x2 = "yes"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.160.46"; + ENB_INTERFACE_NAME_FOR_S1U = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.160.46"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + ENB_IPV4_ADDRESS_FOR_X2C = "127.0.0.1"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + phy_test_mode = 0; + puSch10xSnr = 160; + puCch10xSnr = 160; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + prach_dtx_threshold = 150; + } +); + +RUs = ( + { + //local_if_name = "enp129s0f0"; + local_if_name = "dpdk"; + sdr_addrs = "softmodem -m 2048 -l 8 -n 2 -b 0000:3b:00.0 --proc-type auto --file-prefix ggg -- -p 0x1"; + #sdr_addrs = "softmodem -l 8 -n 2 -- -p 0x2"; + remote_address = "127.0.0.2"; + local_address = "127.0.0.1"; + local_portc = 50000; + remote_portc = 50000; + local_portd = 50001; + remote_portd = 50001; + local_rf = "no" + tr_preference = "raw_if4p5" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + eNB_instances = [0]; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + #parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + parallel_config = "PARALLEL_SINGLE_THREAD"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + +NETWORK_CONTROLLER : +{ + FLEXRAN_ENABLED = "no"; + FLEXRAN_INTERFACE_NAME = "lo"; + FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_PORT = 2210; + FLEXRAN_CACHE = "/mnt/oai_agent_cache"; + FLEXRAN_AWAIT_RECONF = "no"; +}; + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf new file mode 100644 index 0000000000..27fc90e5e3 --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf @@ -0,0 +1,307 @@ +Active_gNBs = ( "gNB-Eurecom-5GNRBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + + cell_type = "CELL_MACRO_GNB"; + + gNB_name = "gNB-Eurecom-5GNRBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + + plmn_list = ({mcc = 222; mnc = 01; mnc_length = 2;}); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + ssb_SubcarrierOffset = 31; //0; + pdsch_AntennaPorts = 1; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is is the central frequency of SSB + absoluteFrequencySSB = 640000; //641272 + dl_frequencyBand = 78; + # the carrier frequency is assumed to be in the middle of the carrier, i.e. dl_absoluteFrequencyPointA_kHz + dl_carrierBandwidth*12*SCS_kHz/2 + dl_absoluteFrequencyPointA = 638728; //640000; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 106; + #initialDownlinkBWP + #genericParameters + # this is RBstart=84,L=13 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 6366; //28875; //6366; #6407; #3384; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 0; + initialDLBWPsearchSpaceZero = 0; + #pdsch-ConfigCommon + #pdschTimeDomainAllocationList (up to 16 entries) + initialDLBWPk0_0 = 0; + #initialULBWPmappingType + #0=typeA,1=typeB + initialDLBWPmappingType_0 = 0; + #this is SS=1,L=13 + initialDLBWPstartSymbolAndLength_0 = 40; + + initialDLBWPk0_1 = 0; + initialDLBWPmappingType_1 = 0; + #this is SS=2,L=12 + initialDLBWPstartSymbolAndLength_1 = 53; + + initialDLBWPk0_2 = 0; + initialDLBWPmappingType_2 = 0; + #this is SS=1,L=12 + initialDLBWPstartSymbolAndLength_2 = 54; + + initialDLBWPk0_3 = 0; + initialDLBWPmappingType_3 = 0; + #this is SS=1,L=4 //5 (4 is for 43, 5 is for 57) + initialDLBWPstartSymbolAndLength_3 = 57; //43; //57; + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 106; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 6366; //28875; //6366; #6407; #3384; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 4; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 74; + zeroCorrelationZoneConfig = 13; + #preambleReceivedTargetPower = -118; + preambleReceivedTargetPower = -104; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 2; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 5; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14; //15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 1; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + #msg1_SubcarrierSpacing = 1, + +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + # pusch-ConfigCommon (up to 16 elements) + initialULBWPk2_0 = 2; + initialULBWPmappingType_0 = 1 + # this is SS=0 L=11 + initialULBWPstartSymbolAndLength_0 = 55; + + initialULBWPk2_1 = 2; + initialULBWPmappingType_1 = 1; + # this is SS=0 L=12 + initialULBWPstartSymbolAndLength_1 = 69; + + initialULBWPk2_2 = 7; + initialULBWPmappingType_2 = 1; + # this is SS=10 L=4 + initialULBWPstartSymbolAndLength_2 = 52; + + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; +# ssb_PositionsInBurs_BitmapPR +# 1=short, 2=medium, 3=long + ssb_PositionsInBurst_PR = 2; + ssb_PositionsInBurst_Bitmap = 1; #0x80; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 1; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; //8; //7; + nrofDownlinkSymbols = 6; //0; //6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; //0; //4; + + #ssPBCH_BlockPower = 10; + ssPBCH_BlockPower = 10; + } + + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.61.195"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + ///X2 + enable_x2 = "yes"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + target_enb_x2_ip_address = ( + { ipv4 = "127.0.0.1"; + ipv6 = "192:168:30::17"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + GNB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.160.146/24"; + GNB_INTERFACE_NAME_FOR_S1U = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1U = "192.168.160.146/24"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + GNB_IPV4_ADDRESS_FOR_X2C = "127.0.0.2/24"; + GNB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "no" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 114; + eNB_instances = [0]; + //clock_src = "internal"; + clock_src = "external"; + + local_if_name = "dpdk"; + sdr_addrs = "softmodem -m 2048 -l 6 -n 3 -b 0000:3b:00.1 --proc-type auto --file-prefix hhh -- -p 0x1"; + remote_address = "127.0.0.2"; + local_address = "127.0.0.1"; + local_portc = 50000; + remote_portc = 50000; + local_portd = 50001; + remote_portd = 50001; + tr_preference = "raw_if4p5" + + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + //parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + parallel_config = "PARALLEL_SINGLE_THREAD"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_DISABLE"; + } +); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf index d5bc492644..983404e459 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf @@ -235,7 +235,7 @@ RUs = ( att_rx = 0; bands = [7]; max_pdschReferenceSignalPower = -27; - max_rxgain = 114; + max_rxgain = 75; eNB_instances = [0]; sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2"; if_freq = 5300000000; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf index 93a6c7fbc9..2737357851 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf @@ -235,7 +235,7 @@ RUs = ( att_rx = 0; bands = [7]; max_pdschReferenceSignalPower = -27; - max_rxgain = 114; + max_rxgain = 75; eNB_instances = [0]; sdr_addrs = "type=n300"; } diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf index 72a27cc1e7..e171b2faa9 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf @@ -235,7 +235,7 @@ RUs = ( att_rx = 0; bands = [7]; max_pdschReferenceSignalPower = -27; - max_rxgain = 114; + max_rxgain = 75; eNB_instances = [0]; sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2"; if_freq = 5124520000L; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf index fdc4894da6..862f0e6303 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf @@ -21,183 +21,166 @@ gNBs = ////////// Physical parameters: - component_carriers = ( - { - node_function = "3GPP_gNODEB"; - node_timing = "synch_to_ext_device"; - node_synch_ref = 0; - frame_type = "TDD"; - DL_prefix_type = "NORMAL"; - UL_prefix_type = "NORMAL"; - eutra_band = 78; - downlink_frequency = 3510000000L; - uplink_frequency_offset = -120000000; - Nid_cell = 0; - N_RB_DL = 106; - nb_antenna_ports = 1; - nb_antennas_tx = 1; - nb_antennas_rx = 1; - tx_gain = 90; - rx_gain = 125; - MIB_subCarrierSpacingCommon = 30; - MIB_ssb_SubcarrierOffset = 0; - MIB_dmrs_TypeA_Position = 2; - pdcch_ConfigSIB1 = 0; - SIB1_frequencyOffsetSSB = "khz5"; - SIB1_ssb_PeriodicityServingCell = 5; - SIB1_ss_PBCH_BlockPower = -60; - absoluteFrequencySSB = 0; - DL_FreqBandIndicatorNR = 15; - DL_absoluteFrequencyPointA = 15; - DL_offsetToCarrier = 15; - DL_SCS_SubcarrierSpacing = "kHz30"; - DL_SCS_SpecificCarrier_k0 = 0; - DL_carrierBandwidth = 15; - DL_locationAndBandwidth = 15; - DL_BWP_SubcarrierSpacing = "kHz30"; - DL_BWP_prefix_type = "NORMAL"; - UL_FreqBandIndicatorNR = 15; - UL_absoluteFrequencyPointA = 13; - UL_additionalSpectrumEmission = 3; - UL_p_Max = -1; - UL_frequencyShift7p5khz = "TRUE"; - UL_offsetToCarrier = 10; - UL_SCS_SubcarrierSpacing = "kHz30"; - UL_SCS_SpecificCarrier_k0 = 0; - UL_carrierBandwidth = 15; - UL_locationAndBandwidth = 15; - UL_BWP_SubcarrierSpacing = "kHz30"; - UL_BWP_prefix_type = "NORMAL"; - UL_timeAlignmentTimerCommon = "infinity"; - ServingCellConfigCommon_n_TimingAdvanceOffset = "n0" - ServingCellConfigCommon_ssb_PositionsInBurst_PR = 0x01; - ServingCellConfigCommon_ssb_periodicityServingCell = 10; - ServingCellConfigCommon_dmrs_TypeA_Position = 2; - NIA_SubcarrierSpacing = "kHz15"; - ServingCellConfigCommon_ss_PBCH_BlockPower = -60; - referenceSubcarrierSpacing = "kHz15"; - dl_UL_TransmissionPeriodicity = "ms0p5"; - nrofDownlinkSlots = 10; - nrofDownlinkSymbols = 10; - nrofUplinkSlots = 10; - nrofUplinkSymbols = 10; - rach_totalNumberOfRA_Preambles = 63; - rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_choice = "oneEighth"; - rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneEighth = 4; - rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneFourth = 8; - rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneHalf = 16; - rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_one = 24; - rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_two = 32; - rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_four = 8; - rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_eight = 4; - rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_sixteen = 2; - rach_groupBconfigured = "ENABLE"; - rach_ra_Msg3SizeGroupA = 56; - rach_messagePowerOffsetGroupB = "dB0"; - rach_numberOfRA_PreamblesGroupA = 32; - rach_ra_ContentionResolutionTimer = 8; - rsrp_ThresholdSSB = 64; - rsrp_ThresholdSSB_SUL = 64; - prach_RootSequenceIndex_choice = "l839"; - prach_RootSequenceIndex_l839 = 0; - prach_RootSequenceIndex_l139 = 0; - prach_msg1_SubcarrierSpacing = "kHz30"; - restrictedSetConfig = "unrestrictedSet"; - msg3_transformPrecoding = "ENABLE"; - prach_ConfigurationIndex = 10; - prach_msg1_FDM = "one"; - prach_msg1_FrequencyStart = 10; - zeroCorrelationZoneConfig = 10; - preambleReceivedTargetPower = -150; - preambleTransMax = 6; - powerRampingStep = "dB0"; - ra_ResponseWindow = 8; - groupHoppingEnabledTransformPrecoding = "ENABLE"; - msg3_DeltaPreamble = 0; - p0_NominalWithGrant = 0; - PUSCH_TimeDomainResourceAllocation_k2 = 0; - PUSCH_TimeDomainResourceAllocation_mappingType = "typeA"; - PUSCH_TimeDomainResourceAllocation_startSymbolAndLength = 0; - pucch_ResourceCommon = 0; - pucch_GroupHopping = "neither"; - hoppingId = 0; - p0_nominal = -30; - PDSCH_TimeDomainResourceAllocation_k0 = 2; - PDSCH_TimeDomainResourceAllocation_mappingType = "typeA"; - PDSCH_TimeDomainResourceAllocation_startSymbolAndLength = 0; - rateMatchPatternId = 0; - RateMatchPattern_patternType = "bitmaps"; - symbolsInResourceBlock = "oneSlot"; - periodicityAndPattern = 2; - RateMatchPattern_controlResourceSet = 5; - RateMatchPattern_subcarrierSpacing = "kHz30"; - RateMatchPattern_mode = "dynamic"; - controlResourceSetZero = 0; - searchSpaceZero = 0; - searchSpaceSIB1 = 10; - searchSpaceOtherSystemInformation = 10; - pagingSearchSpace = 10; - ra_SearchSpace = 10; - PDCCH_common_controlResourceSetId = 5; - PDCCH_common_ControlResourceSet_duration = 2; - PDCCH_cce_REG_MappingType = "nonInterleaved"; - PDCCH_reg_BundleSize = 3; - PDCCH_interleaverSize = 3; - PDCCH_shiftIndex = 10; - PDCCH_precoderGranularity = "sameAsREG-bundle"; - PDCCH_TCI_StateId = 32; - tci_PresentInDCI = "ENABLE"; - PDCCH_DMRS_ScramblingID = 0; - SearchSpaceId = 10; - commonSearchSpaces_controlResourceSetId = 5; - SearchSpace_monitoringSlotPeriodicityAndOffset_choice = "sl1"; - SearchSpace_monitoringSlotPeriodicityAndOffset_value = 0; - SearchSpace_duration = 2; - SearchSpace_nrofCandidates_aggregationLevel1 = 0; - SearchSpace_nrofCandidates_aggregationLevel2 = 0; - SearchSpace_nrofCandidates_aggregationLevel4 = 0; - SearchSpace_nrofCandidates_aggregationLevel8 = 0; - SearchSpace_nrofCandidates_aggregationLevel16 = 0; - SearchSpace_searchSpaceType = "common"; - Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel1 = 1; - Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel2 = 1; - Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel4 = 1; - Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel8 = 1; - Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel16 = 1; - Common_dci_Format2_3_monitoringPeriodicity = 1; - Common_dci_Format2_3_nrofPDCCH_Candidates = 1; - ue_Specific__dci_Formats = "formats0-0-And-1-0"; - RateMatchPatternLTE_CRS_carrierFreqDL = 6; - RateMatchPatternLTE_CRS_carrierBandwidthDL = 6; - RateMatchPatternLTE_CRS_nrofCRS_Ports = 1; - RateMatchPatternLTE_CRS_v_Shift = 0; - RateMatchPatternLTE_CRS_radioframeAllocationPeriod = 1; - RateMatchPatternLTE_CRS_radioframeAllocationOffset = 0; - RateMatchPatternLTE_CRS_subframeAllocation_choice = "oneFrame"; - } - ); - - - srb1_parameters : + ssb_SubcarrierOffset = 0; + pdsch_AntennaPorts = 1; + + servingCellConfigCommon = ( { - # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] - timer_poll_retransmit = 80; + #spCellConfigCommon - # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] - timer_reordering = 35; + physCellId = 0; - # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] - timer_status_prohibit = 0; +# downlinkConfigCommon + #frequencyInfoDL + # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 641032; + dl_frequencyBand = 78; + # this is 3600 MHz + dl_absoluteFrequencyPointA = 640000; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 106; + #initialDownlinkBWP + #genericParameters + # this is RBstart=0,L=50 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 13475; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; + #pdsch-ConfigCommon + #pdschTimeDomainAllocationList (up to 16 entries) + initialDLBWPk0_0 = 0; + #initialULBWPmappingType + #0=typeA,1=typeB + initialDLBWPmappingType_0 = 0; + #this is SS=2,L=3 + initialDLBWPstartSymbolAndLength_0 = 40; - # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] - poll_pdu = 4; + initialDLBWPk0_1 = 0; + initialDLBWPmappingType_1 = 0; + #this is SS=2,L=12 + initialDLBWPstartSymbolAndLength_1 = 53; - # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] - poll_byte = 99999; + initialDLBWPk0_2 = 0; + initialDLBWPmappingType_2 = 0; + #this is SS=1,L=12 + initialDLBWPstartSymbolAndLength_2 = 54; + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 106; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 13475; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -118; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#0=oneeighth,1=onefourth,2=half,3=one,4=two,5=four,6=eight,7=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#0 = 839, 1 = 139 + prach_RootSequenceIndex_PR = 1; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, + +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + # pusch-ConfigCommon (up to 16 elements) + initialULBWPk2_0 = 2; + initialULBWPmappingType_0 = 1 + # this is SS=0 L=11 + initialULBWPstartSymbolAndLength_0 = 55; + + initialULBWPk2_1 = 2; + initialULBWPmappingType_1 = 1; + # this is SS=0 L=12 + initialULBWPstartSymbolAndLength_1 = 69; + + + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; +# ssb_PositionsInBurs_BitmapPR +# 1=short, 2=medium, 3=long + ssb_PositionsInBurst_PR = 2; + ssb_PositionsInBurst_Bitmap = 1; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 1; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = 10; + } + + ); - # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] - max_retx_threshold = 4; - } # ------- SCTP definitions SCTP : @@ -255,7 +238,7 @@ RUs = ( max_rxgain = 114; eNB_instances = [0]; sdr_addrs = "type=b200"; - + #clock_src = "external"; } ); @@ -264,20 +247,10 @@ THREAD_STRUCT = ( #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" parallel_config = "PARALLEL_SINGLE_THREAD"; #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" - worker_config = "WORKER_DISABLE"; + worker_config = "WORKER_ENABLE"; } ); -NETWORK_CONTROLLER : -{ - FLEXRAN_ENABLED = "no"; - FLEXRAN_INTERFACE_NAME = "lo"; - FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; - FLEXRAN_PORT = 2210; - FLEXRAN_CACHE = "/mnt/oai_agent_cache"; - FLEXRAN_AWAIT_RECONF = "no"; -}; - log_config : { global_log_level ="info"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf index dbcbb2ed4f..aeb9e2be88 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf @@ -246,7 +246,7 @@ RUs = ( att_rx = 0; bands = [7]; max_pdschReferenceSignalPower = -27; - max_rxgain = 114; + max_rxgain = 75; eNB_instances = [0]; #beamforming 1x4 matrix: bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf index ae17efc9bd..9420c488ec 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf @@ -254,7 +254,7 @@ RUs = ( att_rx = 0; bands = [7]; max_pdschReferenceSignalPower = -27; - max_rxgain = 114; + max_rxgain = 75; eNB_instances = [0]; sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2"; clock_src = "external"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf index 464ce6b9aa..0a6268f8a8 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf @@ -240,7 +240,7 @@ RUs = ( att_rx = 0; bands = [7]; max_pdschReferenceSignalPower = -27; - max_rxgain = 114; + max_rxgain = 75; eNB_instances = [0]; sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2"; clock_src = "external"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf new file mode 100644 index 0000000000..f30c928448 --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf @@ -0,0 +1,295 @@ +Active_gNBs = ( "gNB-Eurecom-5GNRBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + + cell_type = "CELL_MACRO_GNB"; + + gNB_name = "gNB-Eurecom-5GNRBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + + plmn_list = ({mcc = 222; mnc = 01; mnc_length = 2;}); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + ssb_SubcarrierOffset = 31; //0; + pdsch_AntennaPorts = 1; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3600 MHz + 84 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 641272; //641032; #641968; 641968=start of ssb at 3600MHz + 82 RBs 641032=center of SSB at center of cell + dl_frequencyBand = 78; + # this is 3600 MHz + dl_absoluteFrequencyPointA = 640000; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 106; + #initialDownlinkBWP + #genericParameters + # this is RBstart=84,L=13 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 6366; //28875; //6366; #6407; #3384; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 0; + initialDLBWPsearchSpaceZero = 0; + #pdsch-ConfigCommon + #pdschTimeDomainAllocationList (up to 16 entries) + initialDLBWPk0_0 = 0; + #initialULBWPmappingType + #0=typeA,1=typeB + initialDLBWPmappingType_0 = 0; + #this is SS=1,L=13 + initialDLBWPstartSymbolAndLength_0 = 40; + + initialDLBWPk0_1 = 0; + initialDLBWPmappingType_1 = 0; + #this is SS=2,L=12 + initialDLBWPstartSymbolAndLength_1 = 53; + + initialDLBWPk0_2 = 0; + initialDLBWPmappingType_2 = 0; + #this is SS=1,L=12 + initialDLBWPstartSymbolAndLength_2 = 54; + + initialDLBWPk0_3 = 0; + initialDLBWPmappingType_3 = 0; + #this is SS=1,L=4 //5 (4 is for 43, 5 is for 57) + initialDLBWPstartSymbolAndLength_3 = 57; //43; //57; + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 106; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 6366; //28875; //6366; #6407; #3384; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -90; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 5; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14; //15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, + +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + # pusch-ConfigCommon (up to 16 elements) + initialULBWPk2_0 = 2; + initialULBWPmappingType_0 = 1 + # this is SS=0 L=11 + initialULBWPstartSymbolAndLength_0 = 55; + + initialULBWPk2_1 = 2; + initialULBWPmappingType_1 = 1; + # this is SS=0 L=12 + initialULBWPstartSymbolAndLength_1 = 69; + + initialULBWPk2_2 = 7; + initialULBWPmappingType_2 = 1; + # this is SS=10 L=4 + initialULBWPstartSymbolAndLength_2 = 52; + + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; +# ssb_PositionsInBurs_BitmapPR +# 1=short, 2=medium, 3=long + ssb_PositionsInBurst_PR = 2; + ssb_PositionsInBurst_Bitmap = 1; #0x80; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 1; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; //8; //7; + nrofDownlinkSymbols = 6; //0; //6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; //0; //4; + + ssPBCH_BlockPower = 0; + } + + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.18.99"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + ///X2 + enable_x2 = "yes"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + target_enb_x2_ip_address = ( + { ipv4 = "192.168.18.199"; + ipv6 = "192:168:30::17"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + GNB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.18.196/24"; + GNB_INTERFACE_NAME_FOR_S1U = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1U = "192.168.18.196/24"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + GNB_IPV4_ADDRESS_FOR_X2C = "192.168.18.196/24"; + GNB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 75; + eNB_instances = [0]; + sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2"; + clock_src = "external"; + time_src = "external"; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + #parallel_config = "PARALLEL_SINGLE_THREAD"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 4d89020077..e3b9797105 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -2675,6 +2675,15 @@ void set_function_spec_param(RU_t *ru) { exit(-1); } + if (ru->ifdevice.get_internal_parameter != NULL) { + void *t = ru->ifdevice.get_internal_parameter("fh_if4p5_south_in"); + if (t != NULL) + ru->fh_south_in = t; + t = ru->ifdevice.get_internal_parameter("fh_if4p5_south_out"); + if (t != NULL) + ru->fh_south_out = t; + } + malloc_IF4p5_buffer(ru); break; diff --git a/targets/RT/USER/stats.h b/targets/RT/USER/stats.h index 264c8f7af0..15ee4a8087 100644 --- a/targets/RT/USER/stats.h +++ b/targets/RT/USER/stats.h @@ -21,8 +21,8 @@ /* Header file generated by fdesign on Thu Aug 28 12:13:51 2014 */ -#ifndef FD_stats_form_h_ -#define FD_stats_form_h_ +#ifndef _TARGETS_RT_USER_STATS_H_ +#define _TARGETS_RT_USER_STATS_H_ #include @@ -43,4 +43,4 @@ typedef struct { extern FD_stats_form * create_form_stats_form( void ); -#endif /* FD_stats_form_h_ */ +#endif /* _TARGETS_RT_USER_STATS_H_ */