diff --git a/CMakeLists.txt b/CMakeLists.txt index 0ae2cd3417..aa9f0c4685 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -268,7 +268,7 @@ add_library(ITTI ${OCP_ITTI}/intertask_interface.cpp) target_link_libraries(ITTI PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs) # asn1c skeletons have hardcoded this flag to make customized debug logs -# OAI uses this feature to re-use OAI LOG_I(ASN, ...) +# OAI uses this feature to re-use OAI LOG_I(ASN1, ...) if (DEBUG_ASN1C) add_definitions(-DHAVE_CONFIG_H) endif() @@ -1303,6 +1303,7 @@ set(NR_L2_SRC_UE ${NR_UE_RRC_DIR}/rrc_UE.c ${NR_UE_RRC_DIR}/rrc_nsa.c ${NR_UE_RRC_DIR}/rrc_timers_and_constants.c + ${NR_UE_RRC_DIR}/rrc_sl_preconfig.c ) set (MAC_SRC diff --git a/ci-scripts/ci_ueinfra.yaml b/ci-scripts/ci_ueinfra.yaml index daedf496f7..7cef916dd2 100644 --- a/ci-scripts/ci_ueinfra.yaml +++ b/ci-scripts/ci_ueinfra.yaml @@ -141,6 +141,18 @@ rfsim5g_ue: NetworkScript: docker exec rfsim5g-oai-nr-ue ip a show dev oaitun_ue1 CmdPrefix: docker exec rfsim5g-oai-nr-ue IF: oaitun_ue1 + AttachScript: docker start rfsim5g-oai-nr-ue + DetachScript: docker stop rfsim5g-oai-nr-ue + MTU: 1500 + +rfsim5g_ue2: + Host: localhost + NetworkScript: docker exec rfsim5g-oai-nr-ue2 ip a show dev oaitun_ue1 + CmdPrefix: docker exec rfsim5g-oai-nr-ue2 + IF: oaitun_ue1 + AttachScript: docker start rfsim5g-oai-nr-ue2 + DetachScript: docker stop rfsim5g-oai-nr-ue2 + MTU: 1500 rfsim5g_ext_dn: Host: localhost diff --git a/ci-scripts/cls_static_code_analysis.py b/ci-scripts/cls_static_code_analysis.py index 92f9268574..58dc94b734 100644 --- a/ci-scripts/cls_static_code_analysis.py +++ b/ci-scripts/cls_static_code_analysis.py @@ -42,9 +42,10 @@ from multiprocessing import Process, Lock, SimpleQueue #----------------------------------------------------------- # OAI Testing modules #----------------------------------------------------------- -import sshconnection as SSH import helpreadme as HELP import constants as CONST +import cls_cmd +from cls_containerize import CreateWorkspace #----------------------------------------------------------- # Class Declaration @@ -95,53 +96,31 @@ class StaticCodeAnalysis(): HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') logging.debug('Building on server: ' + lIpAddr) - mySSH = SSH.SSHConnection() - mySSH.open(lIpAddr, lUserName, lPassWord) - + cmd = cls_cmd.getConnection(lIpAddr) self.testCase_id = HTML.testCase_id - # on RedHat/CentOS .git extension is mandatory result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository) if result is not None: full_ran_repo_name = self.ranRepository.replace('git/', 'git') else: full_ran_repo_name = self.ranRepository + '.git' - mySSH.command('mkdir -p ' + lSourcePath, '\$', 5) - mySSH.command('cd ' + lSourcePath, '\$', 5) - mySSH.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + full_ran_repo_name + ' .; else stdbuf -o0 git fetch --prune; fi', '\$', 600) - # Raphael: here add a check if git clone or git fetch went smoothly - mySSH.command('git config user.email "jenkins@openairinterface.org"', '\$', 5) - mySSH.command('git config user.name "OAI Jenkins"', '\$', 5) - mySSH.command('echo ' + lPassWord + ' | sudo -S git clean -x -d -ff', '\$', 30) - mySSH.command('mkdir -p cmake_targets/log', '\$', 5) - # if the commit ID is provided use it to point to it - if self.ranCommitID != '': - mySSH.command('git checkout -f ' + self.ranCommitID, '\$', 30) - # if the branch is not develop, then it is a merge request and we need to do - # the potential merge. Note that merge conflicts should already been checked earlier - if (self.ranAllowMerge): - if self.ranTargetBranch == '': - if (self.ranBranch != 'develop') and (self.ranBranch != 'origin/develop'): - mySSH.command('git merge --ff origin/develop -m "Temporary merge for CI"', '\$', 30) - else: - logging.debug('Merging with the target branch: ' + self.ranTargetBranch) - mySSH.command('git merge --ff origin/' + self.ranTargetBranch + ' -m "Temporary merge for CI"', '\$', 30) + CreateWorkspace(cmd, lSourcePath, full_ran_repo_name, self.ranCommitID, self.ranTargetBranch, self.ranAllowMerge) - mySSH.command('docker image rm oai-cppcheck:bionic oai-cppcheck:focal || true', '\$', 60) - mySSH.command('sed -e "s@xenial@bionic@" ci-scripts/docker/Dockerfile.cppcheck.xenial > ci-scripts/docker/Dockerfile.cppcheck.bionic', '\$', 6) - mySSH.command('docker build --tag oai-cppcheck:bionic --file ci-scripts/docker/Dockerfile.cppcheck.bionic . > cmake_targets/log/cppcheck-bionic.txt 2>&1', '\$', 600) - mySSH.command('sed -e "s@xenial@focal@" ci-scripts/docker/Dockerfile.cppcheck.xenial > ci-scripts/docker/Dockerfile.cppcheck.focal', '\$', 6) - mySSH.command('docker build --tag oai-cppcheck:focal --file ci-scripts/docker/Dockerfile.cppcheck.focal . > cmake_targets/log/cppcheck-focal.txt 2>&1', '\$', 600) - mySSH.command('docker image rm oai-cppcheck:bionic oai-cppcheck:focal || true', '\$', 30) + logDir = f'{lSourcePath}/cmake_targets/build_log_{self.testCase_id}' + cmd.run(f'mkdir -p {logDir}') + cmd.run('docker image rm oai-cppcheck:bionic oai-cppcheck:focal') + cmd.run(f'sed -e "s@xenial@bionic@" {lSourcePath}/ci-scripts/docker/Dockerfile.cppcheck.xenial > {lSourcePath}/ci-scripts/docker/Dockerfile.cppcheck.bionic') + cmd.run(f'docker build --tag oai-cppcheck:bionic --file {lSourcePath}/ci-scripts/docker/Dockerfile.cppcheck.bionic . > {logDir}/cppcheck-bionic.txt 2>&1') + cmd.run(f'sed -e "s@xenial@focal@" {lSourcePath}/ci-scripts/docker/Dockerfile.cppcheck.xenial > {lSourcePath}/ci-scripts/docker/Dockerfile.cppcheck.focal') + cmd.run(f'docker build --tag oai-cppcheck:focal --file {lSourcePath}/ci-scripts/docker/Dockerfile.cppcheck.focal . > {logDir}/cppcheck-focal.txt 2>&1') + cmd.run('docker image rm oai-cppcheck:bionic oai-cppcheck:focal') # Analyzing the logs - mySSH.command('cd ' + lSourcePath + '/cmake_targets', '\$', 5) - mySSH.command('mkdir -p build_log_' + self.testCase_id, '\$', 5) - mySSH.command('mv log/* ' + 'build_log_' + self.testCase_id, '\$', 5) - mySSH.close() + cmd.copyin(f'{logDir}/cppcheck-bionic.txt', 'cppcheck-bionic.txt') + cmd.copyin(f'{logDir}/cppcheck-focal.txt', 'cppcheck-focal.txt') + cmd.close() - mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/build_log_' + self.testCase_id + '/*', '.') CCR = CppCheckResults() CCR_ref = CppCheckResults() vId = 0 @@ -251,57 +230,37 @@ class StaticCodeAnalysis(): HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') logging.debug('Building on server: ' + lIpAddr) - mySSH = SSH.SSHConnection() - mySSH.open(lIpAddr, lUserName, lPassWord) - + cmd = cls_cmd.getConnection(lIpAddr) self.testCase_id = HTML.testCase_id - # on RedHat/CentOS .git extension is mandatory result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository) if result is not None: full_ran_repo_name = self.ranRepository.replace('git/', 'git') else: full_ran_repo_name = self.ranRepository + '.git' - mySSH.command('mkdir -p ' + lSourcePath, '\$', 5) - mySSH.command('cd ' + lSourcePath, '\$', 5) - mySSH.command('if [ ! -e .git ]; then stdbuf -o0 git clone ' + full_ran_repo_name + ' .; else stdbuf -o0 git fetch --prune; fi', '\$', 600) - # Raphael: here add a check if git clone or git fetch went smoothly - mySSH.command('git config user.email "jenkins@openairinterface.org"', '\$', 5) - mySSH.command('git config user.name "OAI Jenkins"', '\$', 5) - mySSH.command('echo ' + lPassWord + ' | sudo -S git clean -x -d -ff', '\$', 30) - mySSH.command('mkdir -p cmake_targets/log', '\$', 5) - # if the commit ID is provided use it to point to it - if self.ranCommitID != '': - mySSH.command('git checkout -f ' + self.ranCommitID, '\$', 30) - # if the branch is not develop, then it is a merge request and we need to do - # the potential merge. Note that merge conflicts should already been checked earlier - argToPass = '' - if (self.ranAllowMerge): - argToPass = '--build-arg MERGE_REQUEST=true --build-arg SRC_BRANCH=' + self.ranBranch + CreateWorkspace(cmd, lSourcePath, full_ran_repo_name, self.ranCommitID, self.ranTargetBranch, self.ranAllowMerge) + check_options = '' + if self.ranAllowMerge: + check_options = f'--build-arg MERGE_REQUEST=true --build-arg SRC_BRANCH={self.ranBranch}' if self.ranTargetBranch == '': - if (self.ranBranch != 'develop') and (self.ranBranch != 'origin/develop'): - mySSH.command('git merge --ff origin/develop -m "Temporary merge for CI"', '\$', 30) - argToPass += ' --build-arg TARGET_BRANCH=develop ' + if self.ranBranch != 'develop' and self.ranBranch != 'origin/develop': + check_options += ' --build-arg TARGET_BRANCH=develop' else: - logging.debug('Merging with the target branch: ' + self.ranTargetBranch) - mySSH.command('git merge --ff origin/' + self.ranTargetBranch + ' -m "Temporary merge for CI"', '\$', 30) - argToPass += ' --build-arg TARGET_BRANCH=' + self.ranTargetBranch + ' ' + check_options += f' --build-arg TARGET_BRANCH={self.ranTargetBranch}' - mySSH.command('docker image rm oai-formatting-check:latest || true', '\$', 60) - mySSH.command('docker build --target oai-formatting-check --tag oai-formatting-check:latest ' + argToPass + '--file ci-scripts/docker/Dockerfile.formatting.bionic . > cmake_targets/log/oai-formatting-check.txt 2>&1', '\$', 600) + logDir = f'{lSourcePath}/cmake_targets/build_log_{self.testCase_id}' + cmd.run(f'mkdir -p {logDir}') + cmd.run('docker image rm oai-formatting-check:latest') + cmd.run(f'docker build --target oai-formatting-check --tag oai-formatting-check:latest {check_options} --file {lSourcePath}/ci-scripts/docker/Dockerfile.formatting.bionic . > {logDir}/oai-formatting-check.txt 2>&1') - mySSH.command('docker image rm oai-formatting-check:latest || true', '\$', 60) - mySSH.command('docker image prune --force', '\$', 60) - mySSH.command('docker volume prune --force', '\$', 60) + cmd.run('docker image rm oai-formatting-check:latest') + cmd.run('docker image prune --force') + cmd.run('docker volume prune --force') # Analyzing the logs - mySSH.command('cd ' + lSourcePath + '/cmake_targets', '\$', 5) - mySSH.command('mkdir -p build_log_' + self.testCase_id, '\$', 5) - mySSH.command('mv log/* ' + 'build_log_' + self.testCase_id, '\$', 5) - mySSH.close() - - mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/build_log_' + self.testCase_id + '/*', '.') + cmd.copyin(f'{logDir}/oai-formatting-check.txt', 'oai-formatting-check.txt') + cmd.close() finalStatus = 0 if (os.path.isfile('./oai-formatting-check.txt')): diff --git a/ci-scripts/conf_files/gnb.sa.band78.106prb.usrpb200.sc-fdma.conf b/ci-scripts/conf_files/gnb.sa.band78.106prb.usrpb200.sc-fdma.conf new file mode 100644 index 0000000000..a22bff5209 --- /dev/null +++ b/ci-scripts/conf_files/gnb.sa.band78.106prb.usrpb200.sc-fdma.conf @@ -0,0 +1,247 @@ +Active_gNBs = ( "gNB-in-docker"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + gNB_name = "gNB-in-docker"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ({ mcc = 222; mnc = 01; mnc_length = 2; snssaiList = ({ sst = 1, sd = 0xffffff }) }); + + nr_cellid = 12345678L; + + ////////// Physical parameters: + + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3300.30 MHz + (19 PRBs + 10 SCs)@30kHz SCS (GSCN: 7715) + absoluteFrequencySSB = 641280; + dl_frequencyBand = 78; + # this is 3300.30 MHz + dl_absoluteFrequencyPointA = 640008; + #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=27,L=48 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 28875; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; + + #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 = 28875; +# 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 = -96; +#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 +#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; +#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, + + 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; +# SC-FDMA: 0 = enabled, 1 = disabled + msg3_transformPrecoder = 0; + #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 = -25; + } + + ); + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// AMF parameters: + amf_ip_address = ( { ipv4 = "172.21.16.137"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + + NETWORK_INTERFACES : + { + GNB_INTERFACE_NAME_FOR_NG_AMF = "eth0"; + GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.68.194"; + GNB_INTERFACE_NAME_FOR_NGU = "eth0"; + GNB_IPV4_ADDRESS_FOR_NGU = "192.168.68.194"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + } +); + +MACRLCs = ( +{ + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + pusch_TargetSNRx10 = 200; + pucch_TargetSNRx10 = 200; + ul_prbblack_SNR_threshold = 10; + ulsch_max_frame_inactivity = 10; + ul_max_mcs = 9; +} +); + +L1s = ( +{ + num_cc = 1; + tr_n_preference = "local_mac"; + prach_dtx_threshold = 120; + pucch0_dtx_threshold = 100; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 +} +); + +RUs = ( +{ + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 14; + att_rx = 14; + bands = [78]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 114; + eNB_instances = [0]; + #beamforming 1x4 matrix: + bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; + clock_src = "internal"; +} +); + +security = { + # preferred ciphering algorithms + # the first one of the list that an UE supports in chosen + # valid values: nea0, nea1, nea2, nea3 + ciphering_algorithms = ( "nea0" ); + + # preferred integrity algorithms + # the first one of the list that an UE supports in chosen + # valid values: nia0, nia1, nia2, nia3 + integrity_algorithms = ( "nia2", "nia0" ); + + # setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter + # what 'ciphering_algorithms' configures; same thing for 'drb_integrity' + drb_ciphering = "yes"; + drb_integrity = "no"; +}; + +log_config : +{ + global_log_level ="info"; + hw_log_level ="info"; + phy_log_level ="info"; + mac_log_level ="info"; + rlc_log_level ="info"; + pdcp_log_level ="info"; + rrc_log_level ="info"; + ngap_log_level ="info"; + f1ap_log_level ="info"; +}; diff --git a/ci-scripts/xml_files/container_5g_rfsim.xml b/ci-scripts/xml_files/container_5g_rfsim.xml index 4923177ee5..36cbf21dc0 100644 --- a/ci-scripts/xml_files/container_5g_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_rfsim.xml @@ -39,6 +39,12 @@ 020004 030001 030002 + 444444 + 333333 + 020005 + 444444 + 333333 + 020005 100001 @@ -122,6 +128,14 @@ 5 + + Ping + Ping ext-dn from both UEs + rfsim5g_ue rfsim5g_ue2 + -c 20 192.168.72.135 + 5 + + IperfFromContainer Iperf UDP Downlink @@ -140,6 +154,18 @@ -B 12.1.1.2 -c 192.168.72.135 -u -i 1 -t 30 -b 1M + + Attach_UE + Attach OAI UE 1 and 2 + rfsim5g_ue rfsim5g_ue2 + + + + Detach_UE + Detach OAI UE 1 and 2 + rfsim5g_ue rfsim5g_ue2 + + UndeployGenObject Undeploy all OAI 5G stack diff --git a/ci-scripts/xml_files/container_sa_b200_quectel.xml b/ci-scripts/xml_files/container_sa_b200_quectel.xml index 9d36b76084..121b836769 100644 --- a/ci-scripts/xml_files/container_sa_b200_quectel.xml +++ b/ci-scripts/xml_files/container_sa_b200_quectel.xml @@ -41,6 +41,12 @@ 060002 050000 010010 + 010001 + 050001 + 010010 + 010001 + 050000 + 010010 010002 030201 200000 diff --git a/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml b/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml index a00a575a81..532d9eaef4 100644 --- a/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml +++ b/ci-scripts/xml_files/container_sa_f1_b200_quectel.xml @@ -37,6 +37,12 @@ 150000 150001 110011 + 110001 + 150001 + 110011 + 110001 + 150000 + 110011 110002 100001 130201 diff --git a/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml b/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml new file mode 100644 index 0000000000..0d4dd8f27e --- /dev/null +++ b/ci-scripts/xml_files/container_sa_sc_b200_quectel.xml @@ -0,0 +1,187 @@ + + + TEST-SA-FR1-SC-FDMA-B200 + 40 MHz TDD SA with SC-FDMA + tasks + 1 + + 300000 + 311111 + 210000 + 230101 + 210001 + 250000 + 250001 + 270000 + 270001 + 270002 + 260001 + 200002 + 260002 + 250000 + 210010 + 210002 + 230201 + 400000 + + + + + Pull_Local_Registry + Pull Images from Local Registry + 0 + oai-gnb + + + + Custom_Command + Disable Sleep States + ofqot + sudo cpupower idle-set -D 0 + + + Custom_Command + Enable Sleep States + ofqot + sudo cpupower idle-set -E + + + + Initialize_UE + Initialize Quectel + idefix + + + Terminate_UE + Terminate Quectel + idefix + + + Attach_UE + Attach UE + idefix + + + Detach_UE + Detach UE + idefix + + + + Deploy_Object + Deploy gNB (TDD/Band78/40MHz/B200) with SC-FDMA in a container + ci-scripts/yaml_files/sa_sc_b200_gnb + 0 + 0 + + + + IdleSleep + Sleep + 5 + + + + IdleSleep + Sleep + 20 + + + + + Ping + Ping: 20pings in 20sec + idefix + -c 20 %cn_ip% + 1 + 15 + + + + Ping + Ping: 100pings in 20sec + idefix + -c 100 -i 0.2 %cn_ip% + 1 + 15 + + + + Iperf + iperf (DL/100Mbps/UDP)(30 sec)(single-ue profile) + -u -b 100M -t 30 -i 1 -fm + DL + idefix + 5 + 95 + single-ue + + + + Iperf + iperf (UL/6Mbps/UDP)(30 sec)(single-ue profile) + -u -b 6M -t 30 -i 1 -fm + UL + idefix + 1 + 95 + single-ue + + + + Iperf + iperf (BIDIR TCP)(10 sec)(single-ue profile) + -t 10 --bidir + BIDIR + idefix + single-ue + + + + Custom_Command + Trigger Reestablishment + ofqot + echo ci force_reestab | nc -N 192.168.68.194 9090 | grep -E 'force-remove UE RNTI [0-9a-f]{4} from RLC to trigger reestablishment' + yes + + + Custom_Command + Verify Reestablishment + ofqot + echo ci get_reestab_count | nc -N 192.168.68.194 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1 reconf_after_reestab 1' + yes + + + + Undeploy_Object + Undeploy gNB + ci-scripts/yaml_files/sa_sc_b200_gnb + 0 + 0 + 10,100,100,100 + 10,100,100,100 + + + + diff --git a/ci-scripts/xml_files/container_sa_sc_b200_terminate.xml b/ci-scripts/xml_files/container_sa_sc_b200_terminate.xml new file mode 100644 index 0000000000..9a041fed7a --- /dev/null +++ b/ci-scripts/xml_files/container_sa_sc_b200_terminate.xml @@ -0,0 +1,41 @@ + + + TEST-SA-FR1-B200-terminate + Tear-down + tasks + 1 + + 030201 + + + + + Undeploy_Object + Undeploy gNB + ci-scripts/yaml_files/sa_sc_b200_gnb + 0 + 0 + + + diff --git a/ci-scripts/yaml_files/sa_sc_b200_gnb/docker-compose.yml b/ci-scripts/yaml_files/sa_sc_b200_gnb/docker-compose.yml new file mode 100644 index 0000000000..90f8bf2271 --- /dev/null +++ b/ci-scripts/yaml_files/sa_sc_b200_gnb/docker-compose.yml @@ -0,0 +1,32 @@ +version: '3.8' + +services: + gnb_mono_tdd: + image: oai-gnb:latest + privileged: true + container_name: sa-b200-gnb + environment: + USE_B2XX: 'yes' + USE_ADDITIONAL_OPTIONS: --sa --RUs.[0].sdr_addrs serial=30C51D4 --telnetsrv --telnetsrv.shrmod ci --continuous-tx --log_config.global_log_options level,nocolor,time,line_num,function -E + volumes: + - ../../conf_files/gnb.sa.band78.106prb.usrpb200.sc-fdma.conf:/opt/oai-gnb/etc/gnb.conf + - /dev:/dev + networks: + public_net: + ipv4_address: 192.168.68.194 + #entrypoint: /bin/bash -c "sleep infinity" + healthcheck: + # pgrep does NOT work + test: /bin/bash -c "ps aux | grep -v grep | grep -c softmodem" + interval: 10s + timeout: 5s + retries: 5 + +networks: + public_net: + name: sa-b200-gnb-net + ipam: + config: + - subnet: 192.168.68.192/26 + driver_opts: + com.docker.network.bridge.name: "sa-gnb-net" diff --git a/common/platform_constants.h b/common/platform_constants.h index 8e17c18343..454c24657b 100644 --- a/common/platform_constants.h +++ b/common/platform_constants.h @@ -70,7 +70,10 @@ #define NR_NB_RB_MAX (29 + 3) /* NR_maxDRB from NR_asn_constant.hm + 3 SRBs */ #define NGAP_MAX_PDU_SESSION (256) /* As defined in TS 38.413 9.2.1.1 Range Bound for PDU Sessions. */ -#define NGAP_MAX_DRBS_PER_UE (32) /* As defined in TS 38.413 9.2.1.1 - maxnoofDRBs */ + +#define MAX_DRBS_PER_UE (32) /* Maximum number of Data Radio Bearers per UE + * defined for NGAP in TS 38.413 - maxnoofDRBs */ +#define MAX_PDUS_PER_UE (8) /* Maximum number of PDU Sessions per UE */ #define NB_RB_MBMS_MAX (29 * 16) /* 29 = LTE_maxSessionPerPMCH + 16 = LTE_maxServiceCount from LTE_asn_constant.h */ diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c index cb46287733..f936ed5ae2 100644 --- a/common/utils/LOG/log.c +++ b/common/utils/LOG/log.c @@ -487,7 +487,7 @@ int logInit (void) register_log_component("SCTP","",SCTP); register_log_component("X2AP","",X2AP); register_log_component("LOADER","log",LOADER); - register_log_component("ASN","log",ASN); + register_log_component("ASN1","log",ASN1); register_log_component("NFAPI_VNF","log",NFAPI_VNF); register_log_component("NFAPI_PNF","log",NFAPI_PNF); register_log_component("GNB_APP","log",GNB_APP); diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h index ccd97f9779..37b89398cb 100644 --- a/common/utils/LOG/log.h +++ b/common/utils/LOG/log.h @@ -240,7 +240,7 @@ typedef enum { NR_MAC, NR_PHY, LOADER, - ASN, + ASN1, NFAPI_VNF, NFAPI_PNF, ITTI, diff --git a/common/utils/config.h b/common/utils/config.h index 597ead7ed6..6d15a309c9 100644 --- a/common/utils/config.h +++ b/common/utils/config.h @@ -27,28 +27,28 @@ /* * This file "config.h" will be used by asn1c if HAVE_CONFIG_H_ is defined and * included. This logs asn1c encoder and decoder traces at execution time using - * the regular OAI logging system, i.e., LOG_I(ASN...); + * the regular OAI logging system, i.e., LOG_I(ASN1...); * * As it is very verbose, note that you can change the log level per module in * source or in gdb, e.g., to only activate it for a short time. * * In code: * ``` - * set_log(ASN, OAI_INFO); // enable logging + * set_log(ASN1, OAI_INFO); // enable logging * // do your encoding here - * set_log(ASN, OAI_ERR); // disable logging + * set_log(ASN1, OAI_ERR); // disable logging * ``` * * in gdb: * ``` - * gdb> p set_log(ASN, 1) // disable log, 1 == OAI_ERR - * gdb> p set_log(ASN, 5) // enable log, 5 == OAI_INFO + * gdb> p set_log(ASN1, 1) // disable log, 1 == OAI_ERR + * gdb> p set_log(ASN1, 5) // enable log, 5 == OAI_INFO * ``` */ #include "common/utils/LOG/log.h" #if DEBUG_ASN1C -#define ASN_DEBUG(x...) do{ LOG_I(ASN,x);LOG_I(ASN,"\n"); } while(false) +#define ASN_DEBUG(x...) do{ LOG_I(ASN1,x);LOG_I(ASN1,"\n"); } while(false) #else #define ASN_DEBUG(x...) #endif diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 2d864abb8e..7d2b11cf65 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -726,6 +726,49 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { stop_meas(&ru->rx_fhaul); } +static radio_tx_gpio_flag_t get_gpio_flags(RU_t *ru, int slot) +{ + radio_tx_gpio_flag_t flags_gpio = 0; + NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; + openair0_config_t *cfg0 = &ru->openair0_cfg; + + switch (cfg0->gpio_controller) { + case RU_GPIO_CONTROL_GENERIC: + // currently we switch beams at the beginning of a slot and we take the beam index of the first symbol of this slot + // we only send the beam to the gpio if the beam is different from the previous slot + + if (ru->common.beam_id) { + int prev_slot = (slot - 1 + fp->slots_per_frame) % fp->slots_per_frame; + const uint8_t *beam_ids = ru->common.beam_id[0]; + int prev_beam = beam_ids[prev_slot * fp->symbols_per_slot]; + int beam = beam_ids[slot * fp->symbols_per_slot]; + if (prev_beam != beam) { + flags_gpio = beam | TX_GPIO_CHANGE; // enable change of gpio + LOG_I(HW, "slot %d, beam %d\n", slot, ru->common.beam_id[0][slot * fp->symbols_per_slot]); + } + } + break; + case RU_GPIO_CONTROL_INTERDIGITAL: { + // the beam index is written in bits 8-10 of the flags + // bit 11 enables the gpio programming + int beam = 0; + if ((slot % 10 == 0) && ru->common.beam_id && (ru->common.beam_id[0][slot * fp->symbols_per_slot] < 64)) { + // beam = ru->common.beam_id[0][slot*fp->symbols_per_slot] | 64; + beam = 1024; // hardcoded now for beam32 boresight + // beam = 127; //for the sake of trying beam63 + LOG_D(HW, "slot %d, beam %d\n", slot, beam); + } + flags_gpio = beam | TX_GPIO_CHANGE; + // flags_gpio |= beam << 8; // MSB 8 bits are used for beam + LOG_I(HW, "slot %d, beam %d, flags_gpio %d\n", slot, beam, flags_gpio); + break; + } + default: + AssertFatal(false, "illegal GPIO controller %d\n", cfg0->gpio_controller); + } + + return flags_gpio; +} void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { RU_proc_t *proc = &ru->proc; @@ -783,47 +826,47 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { flags_burst = proc->first_tx == 1 ? TX_BURST_START : TX_BURST_MIDDLE; } - if (fp->freq_range==nr_FR2) { - // currently we switch beams at the beginning of a slot and we take the beam index of the first symbol of this slot - // we only send the beam to the gpio if the beam is different from the previous slot + if (fp->freq_range == nr_FR2) + flags_gpio = get_gpio_flags(ru, slot); - if ( ru->common.beam_id) { - int prev_slot = (slot - 1 + fp->slots_per_frame) % fp->slots_per_frame; - const uint8_t *beam_ids = ru->common.beam_id[0]; - int prev_beam = beam_ids[prev_slot * fp->symbols_per_slot]; - int beam = beam_ids[slot * fp->symbols_per_slot]; - if (prev_beam != beam) { - flags_gpio = beam | TX_GPIO_CHANGE; // enable change of gpio - LOG_D(HW, "slot %d, beam %d\n", slot, ru->common.beam_id[0][slot * fp->symbols_per_slot]); - } - } - } + const int flags = flags_burst | (flags_gpio << 4); - const int flags = flags_burst | flags_gpio << 4; + if (proc->first_tx == 1) + proc->first_tx = 0; - if (proc->first_tx == 1) proc->first_tx = 0; + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_TRX_WRITE_FLAGS, flags); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, slot); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_WRITE_FLAGS, flags ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, slot ); + for (i = 0; i < ru->nb_tx; i++) + txp[i] = (void *)&ru->common.txdata[i][fp->get_samples_slot_timestamp(slot, fp, 0)] - sf_extension * sizeof(int32_t); - for (i=0; inb_tx; i++) - txp[i] = (void *)&ru->common.txdata[i][fp->get_samples_slot_timestamp(slot,fp,0)]-sf_extension*sizeof(int32_t); - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp+ru->ts_offset-ru->openair0_cfg.tx_sample_advance)&0xffffffff ); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); - // prepare tx buffer pointers - txs = ru->rfdevice.trx_write_func(&ru->rfdevice, - timestamp+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension, - txp, - siglen+sf_extension, - ru->nb_tx, - flags); - LOG_D(PHY,"[TXPATH] RU %d aa %d tx_rf, writing to TS %llu, %d.%d, unwrapped_frame %d, slot %d, flags %d, siglen+sf_extension %d, returned %d, E %f\n",ru->idx,i, - (long long unsigned int)(timestamp+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension),frame,slot,proc->frame_tx_unwrap,slot, flags, siglen+sf_extension, txs,10*log10((double)signal_energy(txp[0],siglen+sf_extension))); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); - //AssertFatal(txs == 0,"trx write function error %d\n", txs); - + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, + (timestamp + ru->ts_offset - ru->openair0_cfg.tx_sample_advance) & 0xffffffff); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1); + // prepare tx buffer pointers + txs = ru->rfdevice.trx_write_func(&ru->rfdevice, + timestamp + ru->ts_offset - ru->openair0_cfg.tx_sample_advance - sf_extension, + txp, + siglen + sf_extension, + ru->nb_tx, + flags); + LOG_D(PHY, + "[TXPATH] RU %d aa %d tx_rf, writing to TS %llu, %d.%d, unwrapped_frame %d, slot %d, flags %d, siglen+sf_extension %d, " + "returned %d, E %f\n", + ru->idx, + i, + (long long unsigned int)(timestamp + ru->ts_offset - ru->openair0_cfg.tx_sample_advance - sf_extension), + frame, + slot, + proc->frame_tx_unwrap, + slot, + flags, + siglen + sf_extension, + txs, + 10 * log10((double)signal_energy(txp[0], siglen + sf_extension))); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0); + // AssertFatal(txs == 0,"trx write function error %d\n", txs); } // this is for RU with local RF unit @@ -1881,6 +1924,23 @@ static void NRRCconfig_RU(void) RC.ru[j]->openair0_cfg.sdr_addrs = strdup(*(RUParamList.paramarray[j][RU_SDR_ADDRS].strptr)); } + if (config_isparamset(RUParamList.paramarray[j], RU_GPIO_CONTROL)) { + if (strcmp(*RUParamList.paramarray[j][RU_GPIO_CONTROL].strptr, "generic") == 0) { + RC.ru[j]->openair0_cfg.gpio_controller = RU_GPIO_CONTROL_GENERIC; + LOG_I(PHY, "RU GPIO control set as 'generic'\n"); + } else if (strcmp(*RUParamList.paramarray[j][RU_GPIO_CONTROL].strptr, "interdigital") == 0) { + RC.ru[j]->openair0_cfg.gpio_controller = RU_GPIO_CONTROL_INTERDIGITAL; + LOG_I(PHY, "RU GPIO control set as 'interdigital'\n"); + } else { + AssertFatal(false, + "bad GPIO controller in configuration file: '%s'\n", + *(RUParamList.paramarray[j][RU_GPIO_CONTROL].strptr)); + } + } else { + RC.ru[j]->openair0_cfg.gpio_controller = RU_GPIO_CONTROL_GENERIC; + LOG_I(PHY, "RU GPIO control set as 'generic'\n"); + } + if (config_isparamset(RUParamList.paramarray[j], RU_TX_SUBDEV)) { RC.ru[j]->openair0_cfg.tx_subdev = strdup(*(RUParamList.paramarray[j][RU_TX_SUBDEV].strptr)); LOG_I(PHY, "RU USRP tx subdev == %s\n", RC.ru[j]->openair0_cfg.tx_subdev); diff --git a/executables/nr-ue.c b/executables/nr-ue.c index aa7e9f26ea..40a3d16753 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -305,10 +305,10 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg) nr_ue_dl_indication(&mac->dl_info); process_queued_nr_nfapi_msgs(mac, sfn_slot); } - if (mac->scc == NULL && mac->scc_SIB == NULL) { - LOG_D(MAC, "[NSA] mac->scc == NULL and [SA] mac->scc_SIB == NULL!\n"); - continue; - } + + bool only_dl = false; + if (mac->scc == NULL && mac->scc_SIB == NULL) + only_dl = true; int CC_id = 0; uint8_t gNB_id = 0; @@ -332,7 +332,8 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg) free_and_zero(ch_info); } - if (is_nr_DL_slot(get_softmodem_params()->nsa ? + if (only_dl || + is_nr_DL_slot(get_softmodem_params()->nsa ? mac->scc->tdd_UL_DL_ConfigurationCommon : mac->scc_SIB->tdd_UL_DL_ConfigurationCommon, ul_info.slot_rx)) { @@ -349,7 +350,8 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg) if (pthread_mutex_unlock(&mac->mutex_dl_info)) abort(); - if (is_nr_UL_slot(get_softmodem_params()->nsa ? + if (!only_dl && + is_nr_UL_slot(get_softmodem_params()->nsa ? mac->scc->tdd_UL_DL_ConfigurationCommon : mac->scc_SIB->tdd_UL_DL_ConfigurationCommon, ul_info.slot_tx, mac->frame_type)) { @@ -510,8 +512,9 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD) { radio_tx_burst_flag_t flags = TX_BURST_INVALID; NR_UE_MAC_INST_t *mac = get_mac_inst(0); - - if (openair0_cfg[0].duplex_mode == duplex_mode_TDD && !get_softmodem_params()->continuous_tx) { + if (mac->phy_config_request_sent && + openair0_cfg[0].duplex_mode == duplex_mode_TDD && + !get_softmodem_params()->continuous_tx) { uint8_t tdd_period = mac->phy_config.config_req.tdd_table.tdd_period_in_slots; int nrofUplinkSlots, nrofUplinkSymbols; @@ -594,8 +597,8 @@ void processSlotTX(void *arg) { RU_write(rxtxD); } -nr_phy_data_t UE_dl_preprocessing(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { - +nr_phy_data_t UE_dl_preprocessing(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) +{ nr_phy_data_t phy_data = {0}; if (IS_SOFTMODEM_NOS1 || get_softmodem_params()->sa) { @@ -619,7 +622,7 @@ nr_phy_data_t UE_dl_preprocessing(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { } } - if (proc->rx_slot_type == NR_DOWNLINK_SLOT || proc->rx_slot_type == NR_MIXED_SLOT){ + if (proc->rx_slot_type == NR_DOWNLINK_SLOT || proc->rx_slot_type == NR_MIXED_SLOT) { if(UE->if_inst != NULL && UE->if_inst->dl_indication != NULL) { nr_downlink_indication_t dl_indication; @@ -749,7 +752,8 @@ static inline int get_readBlockSize(uint16_t slot, NR_DL_FRAME_PARMS *fp) { return rem_samples + next_slot_first_symbol; } -void *UE_thread(void *arg) { +void *UE_thread(void *arg) +{ //this thread should be over the processing thread to keep in real time PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *) arg; // int tx_enabled = 0; @@ -793,21 +797,14 @@ void *UE_thread(void *arg) { if (res) { syncRunning=false; - syncData_t *tmp=(syncData_t *)NotifiedFifoData(res); if (UE->is_synchronized) { - LOG_I(PHY,"UE synchronized decoded_frame_rx=%d UE->init_sync_frame=%d trashed_frames=%d\n", - decoded_frame_rx, - UE->init_sync_frame, - trashed_frames); - - decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx); + decoded_frame_rx = mac->mib_frame; + LOG_I(PHY,"UE synchronized decoded_frame_rx=%d UE->init_sync_frame=%d trashed_frames=%d\n", + decoded_frame_rx, + UE->init_sync_frame, + trashed_frames); // shift the frame index with all the frames we trashed meanwhile we perform the synch search - decoded_frame_rx=(decoded_frame_rx + UE->init_sync_frame + trashed_frames) % MAX_FRAME_NUMBER; - // wait for RRC to configure PHY parameters from SIB - if (get_softmodem_params()->sa) { - notifiedFIFO_elt_t *phy_config_res = pullNotifiedFIFO(&UE->phy_config_ind); - delNotifiedFIFO_elt(phy_config_res); - } + decoded_frame_rx = (decoded_frame_rx + UE->init_sync_frame + trashed_frames) % MAX_FRAME_NUMBER; } delNotifiedFIFO_elt(res); start_rx_stream=0; @@ -856,7 +853,7 @@ void *UE_thread(void *arg) { // and we shifted above to the first slot of next frame decoded_frame_rx++; // we do ++ first in the regular processing, so it will be begin of frame; - absolute_slot=decoded_frame_rx*nb_slot_frame -1; + absolute_slot = decoded_frame_rx * nb_slot_frame - 1; continue; } @@ -869,11 +866,16 @@ void *UE_thread(void *arg) { // update thread index for received subframe curMsg.proc.nr_slot_rx = slot_nr; curMsg.proc.nr_slot_tx = (absolute_slot + DURATION_RX_TO_TX) % nb_slot_frame; - curMsg.proc.frame_rx = (absolute_slot/nb_slot_frame) % MAX_FRAME_NUMBER; - curMsg.proc.frame_tx = ((absolute_slot+DURATION_RX_TO_TX)/nb_slot_frame) % MAX_FRAME_NUMBER; - curMsg.proc.rx_slot_type = nr_ue_slot_select(cfg, curMsg.proc.frame_rx, curMsg.proc.nr_slot_rx); - curMsg.proc.tx_slot_type = nr_ue_slot_select(cfg, curMsg.proc.frame_tx, curMsg.proc.nr_slot_tx); - curMsg.proc.decoded_frame_rx=-1; + curMsg.proc.frame_rx = (absolute_slot / nb_slot_frame) % MAX_FRAME_NUMBER; + curMsg.proc.frame_tx = ((absolute_slot + DURATION_RX_TO_TX) / nb_slot_frame) % MAX_FRAME_NUMBER; + if (mac->phy_config_request_sent) { + curMsg.proc.rx_slot_type = nr_ue_slot_select(cfg, curMsg.proc.frame_rx, curMsg.proc.nr_slot_rx); + curMsg.proc.tx_slot_type = nr_ue_slot_select(cfg, curMsg.proc.frame_tx, curMsg.proc.nr_slot_tx); + } + else { + curMsg.proc.rx_slot_type = NR_DOWNLINK_SLOT; + curMsg.proc.tx_slot_type = NR_DOWNLINK_SLOT; + } int firstSymSamp = get_firstSymSamp(slot_nr, &UE->frame_parms); for (int i=0; iframe_parms.nb_antennas_rx; i++) @@ -882,11 +884,11 @@ void *UE_thread(void *arg) { int readBlockSize, writeBlockSize; - readBlockSize=get_readBlockSize(slot_nr, &UE->frame_parms); - writeBlockSize=UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX) % nb_slot_frame, &UE->frame_parms); - if (UE->apply_timing_offset && (slot_nr == nb_slot_frame-1)) { + readBlockSize = get_readBlockSize(slot_nr, &UE->frame_parms); + writeBlockSize = UE->frame_parms.get_samples_per_slot((slot_nr + DURATION_RX_TO_TX) % nb_slot_frame, &UE->frame_parms); + if (UE->apply_timing_offset && (slot_nr == nb_slot_frame - 1)) { const int sampShift = -(UE->rx_offset>>1); - readBlockSize -= sampShift; + readBlockSize -= sampShift; writeBlockSize -= sampShift; UE->apply_timing_offset = false; } @@ -898,11 +900,11 @@ void *UE_thread(void *arg) { readBlockSize, UE->frame_parms.nb_antennas_rx),""); - if( slot_nr==(nb_slot_frame-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 + 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, @@ -915,7 +917,7 @@ void *UE_thread(void *arg) { } // use previous timing_advance value to compute writeTimestamp - writeTimestamp = timestamp+ + writeTimestamp = timestamp + UE->frame_parms.get_samples_slot_timestamp(slot_nr,&UE->frame_parms,DURATION_RX_TO_TX) - firstSymSamp - openair0_cfg[0].tx_sample_advance - UE->N_TA_offset - timing_advance; @@ -947,15 +949,6 @@ void *UE_thread(void *arg) { curMsgRx->phy_data = UE_dl_preprocessing(UE, &curMsg.proc); pushTpool(&(get_nrUE_params()->Tpool), newElt); - if (curMsg.proc.decoded_frame_rx != -1) - decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | curMsg.proc.decoded_frame_rx); - else - decoded_frame_rx=-1; - - if (decoded_frame_rx>0 && decoded_frame_rx != curMsg.proc.frame_rx) - LOG_E(PHY,"Decoded frame index (%d) is not compatible with current context (%d), UE should go back to synch mode\n", - decoded_frame_rx, curMsg.proc.frame_rx); - // Wait for TX slot processing to finish notifiedFIFO_elt_t *res; res = pullTpool(&txFifo, &(get_nrUE_params()->Tpool)); diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index c569ea38b1..29afb86a6f 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -515,6 +515,7 @@ int main( int argc, char **argv ) { if (get_softmodem_params()->sa) { // set frame config to initial values from command line and assume that the SSB is centered on the grid uint16_t nr_band = get_softmodem_params()->band; mac->nr_band = nr_band; + mac->ssb_start_subcarrier = UE[CC_id]->frame_parms.ssb_start_subcarrier; nr_init_frame_parms_ue_sa(&UE[CC_id]->frame_parms, downlink_frequency[CC_id][0], uplink_frequency_offset[CC_id][0], diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 580db261ae..c1477aa7c1 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -50,10 +50,8 @@ void RCconfig_nrUE_prs(void *cfg) if (gParamList.numelt > 0) { ue->prs_active_gNBs = *(gParamList.paramarray[j][PRS_ACTIVE_GNBS_IDX].uptr); - } - else - { - LOG_E(PHY,"%s configuration NOT found..!! Skipped configuring UE for the PRS reception\n", CONFIG_STRING_PRS_CONFIG); + } else { + LOG_I(PHY,"%s configuration NOT found..!! Skipped configuring UE for the PRS reception\n", CONFIG_STRING_PRS_CONFIG); } paramlist_def_t PRS_ParamList = {{0},NULL,0}; @@ -133,10 +131,8 @@ void RCconfig_nrUE_prs(void *cfg) LOG_I(PHY, "MutingPattern2 \t\t[%s\b\b]\n", str[6]); LOG_I(PHY, "-----------------------------------------\n"); } - } - else - { - LOG_E(PHY,"No %s configuration found..!!\n", PRS_ParamList.listname); + } else { + LOG_I(PHY,"No %s configuration found..!!\n", PRS_ParamList.listname); } } } diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index 0af0ca4b0d..43b83223f6 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -148,7 +148,7 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, unsigned int rx_offset = sample_offset + slot_offset; unsigned int abs_symbol = Ns * frame_parms->symbols_per_slot + symbol; for (int idx_symb = Ns*frame_parms->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++) - rx_offset += (abs_symbol%(0x7<numerology_index)) ? nb_prefix_samples : nb_prefix_samples0; + rx_offset += (idx_symb%(0x7<numerology_index)) ? nb_prefix_samples : nb_prefix_samples0; rx_offset += frame_parms->ofdm_symbol_size * symbol; #ifdef DEBUG_FEP diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 44f7507390..a800d3b8d7 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -101,7 +101,7 @@ void free_list(NR_UE_SSB *node) { } -int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_initial_symbol, nr_phy_data_t *phy_data, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) +int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_initial_symbol, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; int ret =-1; @@ -163,7 +163,6 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini frame_parms, temp_ptr->i_ssb, SISO, - phy_data, &result, rxdataF); @@ -213,9 +212,6 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, NR_DL_FRAME_PARMS *fp = &ue->frame_parms; int ret=-1; int rx_power=0; //aarx, - - nr_phy_data_t phy_data = {0}; - NR_UE_PDCCH_CONFIG *phy_pdcch_config = &phy_data.phy_pdcch_config; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INITIAL_UE_SYNC, VCD_FUNCTION_IN); @@ -317,7 +313,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, if (ret==0) { //we got sss channel nr_gold_pbch(ue); - ret = nr_pbch_detection(proc, ue, 1, &phy_data, rxdataF); // start pbch detection at first symbol after pss + ret = nr_pbch_detection(proc, ue, 1, rxdataF); // start pbch detection at first symbol after pss } if (ret == 0) { @@ -464,103 +460,6 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, #endif } - - if (ue->target_Nid_cell != -1) { - return ret; - } - - // if stand alone and sync on ssb do sib1 detection as part of initial sync - if (sa == 1 && ret == 0) { - nr_ue_dlsch_init(phy_data.dlsch, 1, ue->max_ldpc_iterations); - bool dec = false; - proc->gNB_id = 0; //FIXME - - // Hold the channel estimates in frequency domain. - int32_t pdcch_est_size = ((((fp->symbols_per_slot*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH))+15)/16)*16); - __attribute__ ((aligned(16))) int32_t pdcch_dl_ch_estimates[4*fp->nb_antennas_rx][pdcch_est_size]; - - for(int n_ss = 0; n_ss < phy_pdcch_config->nb_search_space; n_ss++) { - proc->nr_slot_rx = phy_pdcch_config->slot; // setting PDCCH slot to proc - uint8_t nb_symb_pdcch = phy_pdcch_config->pdcch_config[n_ss].coreset.duration; - int start_symb = phy_pdcch_config->pdcch_config[n_ss].coreset.StartSymbolIndex; - for (uint16_t l=start_symb; lsamples_per_frame + phy_pdcch_config->sfn * fp->samples_per_frame + ue->rx_offset, - true, - rxdataF, - link_type_dl); - - nr_pdcch_channel_estimation(ue, - proc, - l, - &phy_pdcch_config->pdcch_config[n_ss].coreset, - fp->first_carrier_offset, - phy_pdcch_config->pdcch_config[n_ss].BWPStart, - pdcch_est_size, - pdcch_dl_ch_estimates, - rxdataF); - - } - int dci_cnt = nr_ue_pdcch_procedures(ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, &phy_data, n_ss, rxdataF); - if (dci_cnt>0){ - NR_UE_DLSCH_t *dlsch = phy_data.dlsch; - if (dlsch[0].active == 1) { - uint16_t nb_symb_sch = dlsch->dlsch_config.number_symbols; - uint16_t start_symb_sch = dlsch->dlsch_config.start_symbol; - - for (uint16_t m=start_symb_sch;m<(nb_symb_sch+start_symb_sch) ; m++){ - nr_slot_fep_init_sync(ue, - proc, - m, - frame_id * fp->samples_per_frame + phy_pdcch_config->sfn * fp->samples_per_frame + ue->rx_offset, - true, - rxdataF, - link_type_dl); - } - - uint8_t nb_re_dmrs; - if (dlsch[0].dlsch_config.dmrsConfigType == NFAPI_NR_DMRS_TYPE1) { - nb_re_dmrs = 6*dlsch[0].dlsch_config.n_dmrs_cdm_groups; - } - else { - nb_re_dmrs = 4*dlsch[0].dlsch_config.n_dmrs_cdm_groups; - } - uint16_t dmrs_len = get_num_dmrs(dlsch[0].dlsch_config.dlDmrsSymbPos); - - const uint32_t rx_llr_size = nr_get_G(dlsch[0].dlsch_config.number_rbs, - dlsch[0].dlsch_config.number_symbols, - nb_re_dmrs, - dmrs_len, - dlsch[0].dlsch_config.qamModOrder, - dlsch[0].Nl); - int16_t* llr[2]; - int16_t* layer_llr[NR_MAX_NB_LAYERS]; - llr[0] = (int16_t *)malloc16_clear(rx_llr_size*sizeof(int16_t)); - - int ret = nr_ue_pdsch_procedures(ue, - proc, - phy_data.dlsch, - llr, - rxdataF); - if (ret >= 0) - dec = nr_ue_dlsch_procedures(ue, - proc, - phy_data.dlsch, - llr); - - // deactivate dlsch once dlsch proc is done - dlsch[0].active = 0; - free(llr[0]); - for (int i=0; iframe_parms.samples_per_slot_wCP]) { @@ -515,7 +514,7 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue, uint16_t number_pdus = 1; if(decoderState) { - nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, phy_data); + nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, NULL); nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, ue, NULL, NULL, number_pdus, proc, NULL, NULL); if (ue->if_inst && ue->if_inst->dl_indication) ue->if_inst->dl_indication(&dl_indication); @@ -569,12 +568,6 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue, if (frame_parms->half_frame_bit) ue->symbol_offset += (frame_parms->slots_per_frame>>1)*frame_parms->symbols_per_slot; - uint8_t frame_number_4lsb = 0; - - for (int i=0; i<4; i++) - frame_number_4lsb |= ((result->xtra_byte>>i)&1)<<(3-i); - - proc->decoded_frame_rx = frame_number_4lsb; #ifdef DEBUG_PBCH printf("xtra_byte %x payload %x\n", xtra_byte, payload); @@ -585,7 +578,7 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue, #endif - nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, phy_data); + nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, NULL); nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, ue, NULL, NULL, number_pdus, proc, (void *)result, NULL); if (ue->if_inst && ue->if_inst->dl_indication) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index 0112d5809e..18469fa733 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -291,14 +291,12 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue, NR_DL_FRAME_PARMS *frame_parms, uint8_t i_ssb, MIMO_mode_t mimo_mode, - nr_phy_data_t *phy_data, fapiPbch_t* result, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); int nr_pbch_detection(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int pbch_initial_symbol, - nr_phy_data_t *phy_data, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 0cd9cef722..97ff191d65 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -665,8 +665,6 @@ typedef struct { int frame_tx; /// frame to act upon for reception int frame_rx; - int frame_number_4lsb; - int decoded_frame_rx; } UE_nr_rxtx_proc_t; typedef struct nr_phy_data_tx_s { diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 2dbbfab2cc..21b344d901 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -361,7 +361,6 @@ static int nr_ue_pbch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int estimateSz, struct complex16 dl_ch_estimates[][estimateSz], - nr_phy_data_t *phy_data, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { int ret = 0; @@ -382,7 +381,6 @@ static int nr_ue_pbch_procedures(PHY_VARS_NR_UE *ue, &ue->frame_parms, (ue->frame_parms.ssb_index)&7, SISO, - phy_data, &result, rxdataF); @@ -904,7 +902,7 @@ void pbch_pdcch_processing(PHY_VARS_NR_UE *ue, if(ssb_index == fp->ssb_index) { LOG_D(PHY," ------ Decode MIB: frame.slot %d.%d ------ \n", frame_rx%1024, nr_slot_rx); - const int pbchSuccess = nr_ue_pbch_procedures(ue, proc, estimateSz, dl_ch_estimates, phy_data, rxdataF); + const int pbchSuccess = nr_ue_pbch_procedures(ue, proc, estimateSz, dl_ch_estimates, rxdataF); if (ue->no_timing_correction==0 && pbchSuccess == 0) { LOG_D(PHY,"start adjust sync slot = %d no timing %d\n", nr_slot_rx, ue->no_timing_correction); diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index f4f04b0538..4a45360ac0 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -782,7 +782,6 @@ int main(int argc, char **argv) } else { UE_nr_rxtx_proc_t proc={0}; - nr_phy_data_t phy_data={0}; UE->rx_offset=0; uint8_t ssb_index = 0; @@ -814,7 +813,6 @@ int main(int argc, char **argv) frame_parms, ssb_index%8, SISO, - &phy_data, &result, rxdataF); diff --git a/openair2/COMMON/mac_messages_types.h b/openair2/COMMON/mac_messages_types.h index 5703a886c0..db65e245d3 100644 --- a/openair2/COMMON/mac_messages_types.h +++ b/openair2/COMMON/mac_messages_types.h @@ -109,6 +109,7 @@ typedef struct NRRrcMacBcchDataInd_s { uint32_t sdu_size; uint8_t sdu[BCCH_SDU_SIZE]; uint8_t gnb_index; + bool is_bch; uint8_t rsrq; uint8_t rsrp; } NRRrcMacBcchDataInd; diff --git a/openair2/COMMON/ngap_messages_types.h b/openair2/COMMON/ngap_messages_types.h index 2f9f56e23a..a03a9d88b6 100644 --- a/openair2/COMMON/ngap_messages_types.h +++ b/openair2/COMMON/ngap_messages_types.h @@ -277,7 +277,7 @@ typedef struct pdusession_s { /* S-GW Tunnel endpoint identifier */ uint32_t gtp_teid; /* Stores the DRB ID of the DRBs used by this PDU Session */ - uint8_t used_drbs[NGAP_MAX_DRBS_PER_UE]; + uint8_t used_drbs[MAX_DRBS_PER_UE]; uint32_t gNB_teid_N3; transport_layer_addr_t gNB_addr_N3; uint32_t UPF_teid_N3; diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h index 58eebba278..6417d3cb75 100644 --- a/openair2/ENB_APP/enb_paramdef.h +++ b/openair2/ENB_APP/enb_paramdef.h @@ -112,6 +112,7 @@ typedef enum { #define CONFIG_STRING_RU_NUM_INTERFACES "num_interfaces" #define CONFIG_STRING_RU_HALF_SLOT_PARALLELIZATION "half_slot_parallelization" #define CONFIG_STRING_RU_RU_THREAD_CORE "ru_thread_core" +#define CONFIG_STRING_RU_GPIO_CONTROL "gpio_controller" #define HLP_RU_SF_AHEAD "LTE TX processing advance" #define HLP_RU_SL_AHEAD "NR TX processing advance" @@ -124,6 +125,7 @@ typedef enum { #define HLP_RU_NUM_INTERFACES "Number of network interfaces for RU" #define HLP_RU_HALF_SLOT_PARALLELIZATION "run half slots in parallel in RU FEP" #define HLP_RU_RU_THREAD_CORE "id of core to pin ru_thread, -1 is default" +#define HLP_RU_GPIO_CONTROL "set the GPIO control type for the RU" #define RU_LOCAL_IF_NAME_IDX 0 #define RU_LOCAL_ADDRESS_IDX 1 @@ -167,6 +169,7 @@ typedef enum { #define RU_NUM_INTERFACES 39 #define RU_HALF_SLOT_PARALLELIZATION 40 #define RU_RU_THREAD_CORE 41 +#define RU_GPIO_CONTROL 42 /*-----------------------------------------------------------------------------------------------------------------------------------------*/ /* RU configuration parameters */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ @@ -215,6 +218,7 @@ typedef enum { {CONFIG_STRING_RU_NUM_INTERFACES, HLP_RU_NUM_INTERFACES, 0, .uptr=NULL, .defintval=1, TYPE_UINT, 0}, \ {CONFIG_STRING_RU_HALF_SLOT_PARALLELIZATION, HLP_RU_HALF_SLOT_PARALLELIZATION, 0, .uptr=NULL, .defintval=1, TYPE_UINT, 0}, \ {CONFIG_STRING_RU_RU_THREAD_CORE, HLP_RU_RU_THREAD_CORE, 0, .uptr=NULL, .defintval=-1, TYPE_UINT, 0}, \ + {CONFIG_STRING_RU_GPIO_CONTROL, HLP_RU_GPIO_CONTROL, 0, .strptr=NULL, .defstrval="generic", TYPE_STRING, 0}, \ } // clang-format on diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index c15a5cd194..cfc32354e6 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -492,7 +492,6 @@ typedef struct Type0_PDCCH_CSS_config_s { int sfn_c; uint32_t n_c; uint32_t n_0; - uint32_t number_of_search_space_per_slot; uint32_t first_symbol_index; uint32_t search_space_duration; uint32_t search_space_frame_period; // in slots diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index e9fa641a07..8ed2b0d0ba 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -4106,8 +4106,8 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD int nr_band, uint32_t ssb_index, uint32_t ssb_period, - uint32_t ssb_offset_point_a) { - + uint32_t ssb_offset_point_a) +{ NR_SubcarrierSpacing_t scs_pdcch; channel_bandwidth_t min_channel_bw; @@ -4303,7 +4303,6 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD float big_m = 0.0f; type0_PDCCH_CSS_config->sfn_c = -1; // only valid for mux=1 type0_PDCCH_CSS_config->n_c = UINT_MAX; - type0_PDCCH_CSS_config->number_of_search_space_per_slot = UINT_MAX; type0_PDCCH_CSS_config->first_symbol_index = UINT_MAX; type0_PDCCH_CSS_config->search_space_duration = 0; // element of search space // 38.213 table 10.1-1 @@ -4311,7 +4310,6 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD /// MUX PATTERN 1 if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 1 && frequency_range == FR1){ big_o = table_38213_13_11_c1[index_4lsb]; - type0_PDCCH_CSS_config->number_of_search_space_per_slot = table_38213_13_11_c2[index_4lsb]; big_m = table_38213_13_11_c3[index_4lsb]; uint32_t temp = (uint32_t)(big_o*(1<ssb_index*big_m); @@ -4331,7 +4329,6 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 1 && frequency_range == FR2){ big_o = table_38213_13_12_c1[index_4lsb]; - type0_PDCCH_CSS_config->number_of_search_space_per_slot = table_38213_13_12_c2[index_4lsb]; big_m = table_38213_13_12_c3[index_4lsb]; uint32_t temp = (uint32_t)(big_o*(1<ssb_index*big_m); @@ -4448,25 +4445,11 @@ void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PD type0_PDCCH_CSS_config->search_space_frame_period = ssb_period*nr_slots_per_frame[scs_ssb]; } - AssertFatal(type0_PDCCH_CSS_config->number_of_search_space_per_slot!=UINT_MAX,""); - -// uint32_t coreset_duration = num_symbols * number_of_search_space_per_slot; -// mac->type0_pdcch_dci_config.number_of_candidates[0] = table_38213_10_1_1_c2[0]; -// mac->type0_pdcch_dci_config.number_of_candidates[1] = table_38213_10_1_1_c2[1]; -// mac->type0_pdcch_dci_config.number_of_candidates[2] = table_38213_10_1_1_c2[2]; // CCE aggregation level = 4 -// mac->type0_pdcch_dci_config.number_of_candidates[3] = table_38213_10_1_1_c2[3]; // CCE aggregation level = 8 -// mac->type0_pdcch_dci_config.number_of_candidates[4] = table_38213_10_1_1_c2[4]; // CCE aggregation level = 16 -// mac->type0_pdcch_dci_config.duration = search_space_duration; -// mac->type0_pdcch_dci_config.coreset.duration = coreset_duration; // coreset -// AssertFatal(first_symbol_index!=UINT_MAX,""); -// mac->type0_pdcch_dci_config.monitoring_symbols_within_slot = (0x3fff << first_symbol_index) & (0x3fff >> (14-coreset_duration-first_symbol_index)) & 0x3fff; - AssertFatal(type0_PDCCH_CSS_config->sfn_c >= 0, ""); AssertFatal(type0_PDCCH_CSS_config->n_c != UINT_MAX, ""); type0_PDCCH_CSS_config->n_0 = ((uint32_t)(big_o*(1<ssb_index*big_m))%num_slot_per_frame; type0_PDCCH_CSS_config->cset_start_rb = ssb_offset_point_a - type0_PDCCH_CSS_config->rb_offset; - } void fill_coresetZero(NR_ControlResourceSet_t *coreset0, NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config) { @@ -4522,7 +4505,10 @@ void fill_coresetZero(NR_ControlResourceSet_t *coreset0, NR_Type0_PDCCH_CSS_conf } -void fill_searchSpaceZero(NR_SearchSpace_t *ss0, NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config) { +void fill_searchSpaceZero(NR_SearchSpace_t *ss0, + int slots_per_frame, + NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config) +{ if(ss0 == NULL) ss0=calloc(1,sizeof(*ss0)); if(ss0->controlResourceSetId == NULL) ss0->controlResourceSetId=calloc(1,sizeof(*ss0->controlResourceSetId)); @@ -4537,8 +4523,9 @@ void fill_searchSpaceZero(NR_SearchSpace_t *ss0, NR_Type0_PDCCH_CSS_config_t *ty AssertFatal(type0_PDCCH_CSS_config!=NULL,"No type0 CSS configuration\n"); const uint32_t periodicity = type0_PDCCH_CSS_config->search_space_frame_period; - const uint32_t offset = type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 1 - ? type0_PDCCH_CSS_config->n_0 : type0_PDCCH_CSS_config->n_c; + const uint32_t offset = type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 1 ? + type0_PDCCH_CSS_config->n_0 + (slots_per_frame * type0_PDCCH_CSS_config->sfn_c) : + type0_PDCCH_CSS_config->n_c; ss0->searchSpaceId = 0; *ss0->controlResourceSetId = 0; diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index ccb630f63d..e2e97e0964 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -228,7 +228,9 @@ NR_tda_info_t get_info_from_tda_tables(default_table_type_t table_type, default_table_type_t get_default_table_type(int mux_pattern); void fill_coresetZero(NR_ControlResourceSet_t *coreset0, NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config); -void fill_searchSpaceZero(NR_SearchSpace_t *ss0, NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config); +void fill_searchSpaceZero(NR_SearchSpace_t *ss0, + int slots_per_frame, + NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config); uint8_t get_pusch_nb_antenna_ports(NR_PUSCH_Config_t *pusch_Config, NR_SRS_Config_t *srs_config, diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index b5c3e87a65..a04606b7e2 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -713,6 +713,8 @@ void nr_rrc_mac_config_req_mib(module_id_t module_id, mac->get_sib1 = true; else if (sched_sib == 2) mac->get_otherSI = true; + nr_ue_decode_mib(module_id, + cc_idP); } void nr_rrc_mac_config_req_sib1(module_id_t module_id, diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 5051d92143..596354223f 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -477,6 +477,8 @@ typedef struct { RA_config_t ra; /// SSB index from MIB decoding uint8_t mib_ssb; + uint32_t mib_additional_bits; + int mib_frame; nr_csi_report_t csi_report_template[MAX_CSI_REPORTCONFIG]; @@ -510,6 +512,7 @@ typedef struct { frequency_range_t frequency_range; uint16_t nr_band; uint8_t ssb_subcarrier_offset; + int ssb_start_subcarrier; NR_SSB_meas_t ssb_measurements; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 09d85cb7a2..383880bcb2 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -47,27 +47,7 @@ void nr_ue_init_mac(module_id_t module_idP); \param mac mac instance */ void nr_ue_mac_default_configs(NR_UE_MAC_INST_t *mac); -/**\brief decode mib pdu in NR_UE, from if_module ul_ind with P7 tx_ind message - \param module_id module id - \param cc_id component carrier id - \param gNB_index gNB index - \param phy_data PHY structure to be filled in by the callee in the FAPI call (L1 caller -> indication to L2 -> FAPI call to L1 callee) - \param extra_bits extra bits for frame calculation - \param l_ssb_equal_64 check if ssb number of candicate is equal 64, 1=equal; 0=non equal. Reference 38.212 7.1.1 - \param pduP pointer to pdu - \param pdu_length length of pdu - \param cell_id cell id */ -int8_t nr_ue_decode_mib( - module_id_t module_id, - int cc_id, - uint8_t gNB_index, - void *phy_data, - uint8_t extra_bits, - uint32_t ssb_length, - uint32_t ssb_index, - void *pduP, - uint16_t ssb_start_subcarrier, - uint16_t cell_id ); +int8_t nr_ue_decode_mib(module_id_t module_id, int cc_id); /**\brief decode SIB1 and other SIs pdus in NR_UE, from if_module dl_ind \param module_id module id @@ -341,16 +321,6 @@ void nr_ue_msg3_scheduler(NR_UE_MAC_INST_t *mac, sub_frame_t current_slot, uint8_t Msg3_tda_id); -void nr_ue_sib1_scheduler(module_id_t module_idP, - int cc_id, - uint16_t ssb_start_symbol, - uint16_t frame, - uint8_t ssb_subcarrier_offset, - uint32_t ssb_index, - uint16_t ssb_start_subcarrier, - frequency_range_t frequency_range, - void *phy_data); - /* \brief Function called by PHY to process the received RAR and check that the preamble matches what was sent by the gNB. It provides the timing advance and t-CRNTI. @param Mod_id Index of UE instance @param CC_id Index to a component carrier diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c index b69097ae8e..efcbd7e2ff 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -425,7 +425,39 @@ bool monitior_dci_for_other_SI(NR_UE_MAC_INST_t *mac, void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl_config, const frame_t frame, const int slot) { const NR_UE_DL_BWP_t *current_DL_BWP = &mac->current_DL_BWP; - const int slots_per_frame = nr_slots_per_frame[current_DL_BWP->scs]; + int scs = mac->get_sib1 ? get_softmodem_params()->numerology : current_DL_BWP->scs; + const int slots_per_frame = nr_slots_per_frame[scs]; + if (mac->get_sib1) { + int ssb_sc_offset_norm; + if (mac->ssb_subcarrier_offset < 24 && mac->frequency_range == FR1) + ssb_sc_offset_norm = mac->ssb_subcarrier_offset >> scs; + else + ssb_sc_offset_norm = mac->ssb_subcarrier_offset; + uint16_t ssb_offset_point_a = (mac->ssb_start_subcarrier - ssb_sc_offset_norm) / 12; + int ssb_start_symbol = get_ssb_start_symbol(mac->nr_band, scs, mac->mib_ssb); + get_type0_PDCCH_CSS_config_parameters(&mac->type0_PDCCH_CSS_config, + mac->mib_frame, + mac->mib, + slots_per_frame, + ssb_sc_offset_norm, + ssb_start_symbol, + scs, + mac->frequency_range, + mac->nr_band, + mac->mib_ssb, + 1, // If the UE is not configured with a periodicity, the UE assumes a periodicity of a half frame + ssb_offset_point_a); + if(mac->search_space_zero == NULL) + mac->search_space_zero=calloc(1,sizeof(*mac->search_space_zero)); + if(mac->coreset0 == NULL) + mac->coreset0 = calloc(1,sizeof(*mac->coreset0)); + fill_coresetZero(mac->coreset0, &mac->type0_PDCCH_CSS_config); + fill_searchSpaceZero(mac->search_space_zero, slots_per_frame, &mac->type0_PDCCH_CSS_config); + if (is_ss_monitor_occasion(frame, slot, slots_per_frame, mac->search_space_zero)) { + LOG_D(NR_MAC, "Monitoring DCI for SIB1 in frame %d slot %d\n", frame, slot); + config_dci_pdu(mac, dl_config, NR_RNTI_SI, slot, mac->search_space_zero); + } + } if (mac->get_otherSI) { // If searchSpaceOtherSystemInformation is set to zero, // PDCCH monitoring occasions for SI message reception in SI-window diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 5d949f74f2..0bc0546fe4 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -246,51 +246,36 @@ int get_rnti_type(NR_UE_MAC_INST_t *mac, uint16_t rnti) int8_t nr_ue_decode_mib(module_id_t module_id, - int cc_id, - uint8_t gNB_index, - void *phy_data, - uint8_t extra_bits, // 8bits 38.212 c7.1.1 - uint32_t ssb_length, - uint32_t ssb_index, - void *pduP, - uint16_t ssb_start_subcarrier, - uint16_t cell_id) + int cc_id) { LOG_D(MAC,"[L2][MAC] decode mib\n"); NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); - mac->physCellId = cell_id; - - nr_mac_rrc_data_ind_ue(module_id, cc_id, gNB_index, 0, 0, 0, NR_BCCH_BCH, (uint8_t *) pduP, 3); // fixed 3 bytes MIB PDU - - AssertFatal(mac->mib != NULL, "nr_ue_decode_mib() mac->mib == NULL\n"); uint16_t frame = (mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused); uint16_t frame_number_4lsb = 0; - for (int i=0; i<4; i++) - frame_number_4lsb |= ((extra_bits>>i)&1)<<(3-i); + int extra_bits = mac->mib_additional_bits; + for (int i = 0; i < 4; i++) + frame_number_4lsb |= ((extra_bits >> i) & 1) << (3 - i); - uint8_t ssb_subcarrier_offset_msb = ( extra_bits >> 5 ) & 0x1; // extra bits[5] + uint8_t ssb_subcarrier_offset_msb = (extra_bits >> 5) & 0x1; // extra bits[5] uint8_t ssb_subcarrier_offset = (uint8_t)mac->mib->ssb_SubcarrierOffset; frame = frame << 4; - frame = frame | frame_number_4lsb; - if(ssb_length == 64){ - mac->frequency_range = FR2; - for (int i=0; i<3; i++) - ssb_index += (((extra_bits>>(7-i))&0x01)<<(3+i)); - }else{ - mac->frequency_range = FR1; - if(ssb_subcarrier_offset_msb){ + mac->mib_frame = frame | frame_number_4lsb; + if (mac->frequency_range == FR2) { + for (int i = 0; i < 3; i++) + mac->mib_ssb += (((extra_bits >> (7 - i)) & 0x01) << (3 + i)); + } else{ + if(ssb_subcarrier_offset_msb) ssb_subcarrier_offset = ssb_subcarrier_offset | 0x10; - } } #ifdef DEBUG_MIB - uint8_t half_frame_bit = ( extra_bits >> 4 ) & 0x1; // extra bits[4] + uint8_t half_frame_bit = (extra_bits >> 4) & 0x1; // extra bits[4] LOG_I(MAC,"system frame number(6 MSB bits): %d\n", mac->mib->systemFrameNumber.buf[0]); - LOG_I(MAC,"system frame number(with LSB): %d\n", (int)frame); + LOG_I(MAC,"system frame number(with LSB): %d\n", (int) mac->mib_frame); LOG_I(MAC,"subcarrier spacing (0=15or60, 1=30or120): %d\n", (int)mac->mib->subCarrierSpacingCommon); LOG_I(MAC,"ssb carrier offset(with MSB): %d\n", (int)ssb_subcarrier_offset); LOG_I(MAC,"dmrs type A position (0=pos2,1=pos3): %d\n", (int)mac->mib->dmrs_TypeA_Position); @@ -299,49 +284,13 @@ int8_t nr_ue_decode_mib(module_id_t module_id, LOG_I(MAC,"cell barred (0=barred,1=notBarred): %d\n", (int)mac->mib->cellBarred); LOG_I(MAC,"intra frequency reselection (0=allowed,1=notAllowed): %d\n", (int)mac->mib->intraFreqReselection); LOG_I(MAC,"half frame bit(extra bits): %d\n", (int)half_frame_bit); - LOG_I(MAC,"ssb index(extra bits): %d\n", (int)ssb_index); + LOG_I(MAC,"ssb index(extra bits): %d\n", (int)mac->mib_ssb); #endif - //storing ssb index in the mac structure - mac->mib_ssb = ssb_index; mac->ssb_subcarrier_offset = ssb_subcarrier_offset; - uint8_t scs_ssb; - uint32_t band; - uint16_t ssb_start_symbol; - - if (get_softmodem_params()->sa == 1) { - - scs_ssb = get_softmodem_params()->numerology; - band = mac->nr_band; - ssb_start_symbol = get_ssb_start_symbol(band,scs_ssb,ssb_index); - int ssb_sc_offset_norm; - if (ssb_subcarrier_offset<24 && mac->frequency_range == FR1) - ssb_sc_offset_norm = ssb_subcarrier_offset>>scs_ssb; - else - ssb_sc_offset_norm = ssb_subcarrier_offset; - - if (mac->get_sib1) { - nr_ue_sib1_scheduler(module_id, - cc_id, - ssb_start_symbol, - frame, - ssb_sc_offset_norm, - ssb_index, - ssb_start_subcarrier, - mac->frequency_range, - phy_data); - mac->first_sync_frame = frame; - } - } - else { - NR_ServingCellConfigCommon_t *scc = mac->scc; - scs_ssb = *scc->ssbSubcarrierSpacing; - band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; - ssb_start_symbol = get_ssb_start_symbol(band,scs_ssb,ssb_index); - if (mac->first_sync_frame == -1) - mac->first_sync_frame = frame; - } + if (mac->first_sync_frame == -1) + mac->first_sync_frame = frame; if(get_softmodem_params()->phy_test) mac->state = UE_CONNECTED; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 33201d8921..defaf6c37d 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -2648,72 +2648,6 @@ static void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_fr } // if is_nr_UL_slot } -// This function schedules the reception of SIB1 after initial sync and before going to real time state -void nr_ue_sib1_scheduler(module_id_t module_idP, - int cc_id, - uint16_t ssb_start_symbol, - uint16_t frame, - uint8_t ssb_subcarrier_offset, - uint32_t ssb_index, - uint16_t ssb_start_subcarrier, - frequency_range_t frequency_range, - void *phy_data) { - - NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); - nr_scheduled_response_t scheduled_response; - - uint8_t scs_ssb = get_softmodem_params()->numerology; - uint16_t ssb_offset_point_a = (ssb_start_subcarrier - ssb_subcarrier_offset)/12; - - get_type0_PDCCH_CSS_config_parameters(&mac->type0_PDCCH_CSS_config, - frame, - mac->mib, - nr_slots_per_frame[scs_ssb], - ssb_subcarrier_offset, - ssb_start_symbol, - scs_ssb, - frequency_range, - mac->nr_band, - ssb_index, - 1, // If the UE is not configured with a periodicity, the UE assumes a periodicity of a half frame - ssb_offset_point_a); - - int frame_s,slot_s; - if(mac->type0_PDCCH_CSS_config.type0_pdcch_ss_mux_pattern == 1){ - // same frame as ssb - if ((mac->type0_PDCCH_CSS_config.frame & 0x1) == mac->type0_PDCCH_CSS_config.sfn_c) - frame_s = 0; - else - frame_s = 1; - slot_s = mac->type0_PDCCH_CSS_config.n_0; - } - else{ - frame_s = 0; // same frame as ssb - slot_s = mac->type0_PDCCH_CSS_config.n_c; - } - - if(mac->search_space_zero == NULL) - mac->search_space_zero=calloc(1,sizeof(*mac->search_space_zero)); - if(mac->coreset0 == NULL) - mac->coreset0 = calloc(1,sizeof(*mac->coreset0)); - fill_coresetZero(mac->coreset0, &mac->type0_PDCCH_CSS_config); - fill_searchSpaceZero(mac->search_space_zero, &mac->type0_PDCCH_CSS_config); - - fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request[0]; // Take the first dl_config_request for SIB1 - config_dci_pdu(mac, dl_config, NR_RNTI_SI, slot_s, mac->search_space_zero); - - LOG_D(MAC,"Calling fill_scheduled_response, type0_pdcch, num_pdus %d\n", dl_config->number_pdus); - fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, module_idP, cc_id, frame_s, slot_s, phy_data); - - if (dl_config->number_pdus) { - if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) - mac->if_module->scheduled_response(&scheduled_response); - } - else - AssertFatal(1==0,"Unable to find aggregation level for type0 CSS\n"); -} - - #define MAX_LCID 8 // NR_MAX_NUM_LCID shall be used but the mac_rlc_data_req function can fetch data for max 8 LCID typedef struct { uint8_t bsr_len; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 49d23185dc..5d36b7d51b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -290,8 +290,10 @@ static uint32_t schedule_control_sib1(module_id_t module_id, gNB_mac->sched_ctrlCommon = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon)); gNB_mac->sched_ctrlCommon->search_space = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->search_space)); gNB_mac->sched_ctrlCommon->coreset = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->coreset)); - fill_searchSpaceZero(gNB_mac->sched_ctrlCommon->search_space,type0_PDCCH_CSS_config); - fill_coresetZero(gNB_mac->sched_ctrlCommon->coreset,type0_PDCCH_CSS_config); + fill_searchSpaceZero(gNB_mac->sched_ctrlCommon->search_space, + nr_slots_per_frame[*scc->ssbSubcarrierSpacing], + type0_PDCCH_CSS_config); + fill_coresetZero(gNB_mac->sched_ctrlCommon->coreset, type0_PDCCH_CSS_config); gNB_mac->cset0_bwp_start = type0_PDCCH_CSS_config->cset_start_rb; gNB_mac->cset0_bwp_size = type0_PDCCH_CSS_config->num_rbs; gNB_mac->sched_ctrlCommon->sched_pdcch = set_pdcch_structure(NULL, diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity.h index 675f4a3e96..cd26094cf7 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity.h @@ -23,7 +23,6 @@ #define _NR_RLC_ENTITY_H_ #include -#include "openair2/RRC/NR/rrc_gNB_radio_bearers.h" #include "common/utils/time_stat.h" diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index b4dea5b51b..f4097d721b 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -179,7 +179,7 @@ mac_rlc_status_resp_t mac_rlc_status_ind( switch (channel_idP) { case 0: rb = ue->srb0; break; case 1 ... 3: rb = ue->srb[channel_idP - 1]; break; - case 4 ... NGAP_MAX_DRBS_PER_UE: rb = ue->drb[channel_idP - 4]; break; + case 4 ... MAX_DRBS_PER_UE: rb = ue->drb[channel_idP - 4]; break; default: rb = NULL; break; } @@ -241,9 +241,9 @@ rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind( ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rntiP); switch (channel_idP) { - case 1 ... 3: rb = ue->srb[channel_idP - 1]; break; - case 4 ... NGAP_MAX_DRBS_PER_UE: rb = ue->drb[channel_idP - 4]; break; - default: rb = NULL; break; + case 1 ... 3: rb = ue->srb[channel_idP - 1]; break; + case 4 ... MAX_DRBS_PER_UE: rb = ue->drb[channel_idP - 4]; break; + default: rb = NULL; break; } if (rb != NULL) { @@ -333,9 +333,9 @@ int nr_rlc_get_available_tx_space( ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rntiP); switch (channel_idP) { - case 1 ... 3: rb = ue->srb[channel_idP - 1]; break; - case 4 ... NGAP_MAX_DRBS_PER_UE: rb = ue->drb[channel_idP - 4]; break; - default: rb = NULL; break; + case 1 ... 3: rb = ue->srb[channel_idP - 1]; break; + case 4 ... MAX_DRBS_PER_UE: rb = ue->drb[channel_idP - 4]; break; + default: rb = NULL; break; } if (rb != NULL) { diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h index c7e42a0a0d..958f216592 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h @@ -23,6 +23,7 @@ #define _NR_RLC_UE_MANAGER_H_ #include "openair2/COMMON/platform_types.h" #include "nr_rlc_entity.h" +#include "common/platform_constants.h" typedef void nr_rlc_ue_manager_t; diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 45c4a5d5c5..8f269a5cd0 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -327,35 +327,37 @@ static void fill_mib_in_rx_ind(nfapi_nr_dl_tti_request_pdu_t *pdu_list, fapi_nr_ static bool is_my_dci(NR_UE_MAC_INST_t *mac, nfapi_nr_dl_dci_pdu_t *received_pdu) { - /* For multiple UEs, we need to be able to filter the rx'd messages by - the RNTI. The filtering is different between NSA mode and SA mode. - NSA mode has a two step CFRA procedure and SA has a 4 step procedure. - We only need to check if the rx'd RNTI doesnt match the CRNTI if the RAR - has been processed already, in NSA mode. - In SA, depending on the RA state, we can have a SIB (0xffff), RAR (0x10b), - Msg3 (TC_RNTI) or an actual DCI message (CRNTI). When we get Msg3, the - MAC instance of the UE still has a CRNTI = 0. We should only check if the - CRNTI doesnt match the received RNTI in SA mode if Msg3 has been processed - already. Only once the RA procedure succeeds is the CRNTI value updated - to the TC_RNTI. */ - if (get_softmodem_params()->nsa) - { - if (received_pdu->RNTI != mac->crnti && - (received_pdu->RNTI != mac->ra.ra_rnti || mac->ra.RA_RAPID_found)) - return false; - } - if (get_softmodem_params()->sa) - { - if (received_pdu->RNTI != mac->crnti && mac->ra.ra_state == RA_SUCCEEDED) - return false; - if (received_pdu->RNTI != mac->ra.t_crnti && mac->ra.ra_state == WAIT_CONTENTION_RESOLUTION) - return false; - if (received_pdu->RNTI != 0x10b && mac->ra.ra_state == WAIT_RAR) - return false; - if (received_pdu->RNTI != 0xFFFF && mac->ra.ra_state <= GENERATE_PREAMBLE) - return false; - } - return true; + /* For multiple UEs, we need to be able to filter the rx'd messages by + the RNTI. The filtering is different between NSA mode and SA mode. + NSA mode has a two step CFRA procedure and SA has a 4 step procedure. + We only need to check if the rx'd RNTI doesnt match the CRNTI if the RAR + has been processed already, in NSA mode. + In SA, depending on the RA state, we can have a SIB (0xffff), RAR (0x10b), + Msg3 (TC_RNTI) or an actual DCI message (CRNTI). When we get Msg3, the + MAC instance of the UE still has a CRNTI = 0. We should only check if the + CRNTI doesnt match the received RNTI in SA mode if Msg3 has been processed + already. Only once the RA procedure succeeds is the CRNTI value updated + to the TC_RNTI. */ + if (get_softmodem_params()->nsa) { + if (received_pdu->RNTI != mac->crnti && + (received_pdu->RNTI != mac->ra.ra_rnti || mac->ra.RA_RAPID_found)) + return false; + } + if (get_softmodem_params()->sa) { + if (mac->state == UE_NOT_SYNC) + return false; + if (received_pdu->RNTI == 0xFFFF && mac->scc_SIB) + return false; + if (received_pdu->RNTI != mac->crnti && mac->ra.ra_state == RA_SUCCEEDED) + return false; + if (received_pdu->RNTI != mac->ra.t_crnti && mac->ra.ra_state == WAIT_CONTENTION_RESOLUTION) + return false; + if (received_pdu->RNTI != 0x10b && mac->ra.ra_state == WAIT_RAR) + return false; + if (received_pdu->RNTI != 0xFFFF && mac->ra.ra_state <= GENERATE_PREAMBLE) + return false; + } + return true; } static void copy_dl_tti_req_to_dl_info(nr_downlink_indication_t *dl_info, nfapi_nr_dl_tti_request_t *dl_tti_request) @@ -1037,19 +1039,18 @@ int handle_bcch_bch(module_id_t module_id, int cc_id, unsigned int gNB_index, void *phy_data, uint8_t *pduP, unsigned int additional_bits, uint32_t ssb_index, uint32_t ssb_length, - uint16_t ssb_start_subcarrier, uint16_t cell_id){ - - return nr_ue_decode_mib(module_id, - cc_id, - gNB_index, - phy_data, - additional_bits, - ssb_length, // Lssb = 64 is not support - ssb_index, - pduP, - ssb_start_subcarrier, - cell_id); - + uint16_t ssb_start_subcarrier, uint16_t cell_id) +{ + NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); + mac->mib_ssb = ssb_index; + mac->physCellId = cell_id; + mac->mib_additional_bits = additional_bits; + if(ssb_length == 64) + mac->frequency_range = FR2; + else + mac->frequency_range = FR1; + nr_mac_rrc_data_ind_ue(module_id, cc_id, gNB_index, 0, 0, 0, NR_BCCH_BCH, (uint8_t *) pduP, 3); // fixed 3 bytes MIB PDU + return 0; } // L2 Abstraction Layer @@ -1149,11 +1150,9 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info) uint32_t ret_mask = 0x0; module_id_t module_id = dl_info->module_id; NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); - if ((!dl_info->dci_ind && !dl_info->rx_ind)) { // UL indication to schedule DCI reception - if (mac->phy_config_request_sent) - nr_ue_dl_scheduler(dl_info); + nr_ue_dl_scheduler(dl_info); } else { // UL indication after reception of DCI or DL PDU if (dl_info && dl_info->dci_ind && dl_info->dci_ind->number_of_dcis) { diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index e72624527c..51ef9d0f8d 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -223,7 +223,6 @@ typedef struct drb_s { } drb_t; typedef enum { - RRC_FIRST_RECONF, RRC_SETUP, RRC_SETUP_FOR_REESTABLISHMENT, RRC_REESTABLISH, @@ -237,8 +236,8 @@ typedef enum { typedef struct gNB_RRC_UE_s { uint8_t primaryCC_id; - drb_t established_drbs[NGAP_MAX_DRBS_PER_UE]; - uint8_t DRB_active[NGAP_MAX_DRBS_PER_UE]; + drb_t established_drbs[MAX_DRBS_PER_UE]; + uint8_t DRB_active[MAX_DRBS_PER_UE]; NR_SRB_INFO_TABLE_ENTRY Srb[maxSRBs]; // 3gpp max is 3 SRBs, number 1..3, we waste the entry 0 for code simplicity NR_MeasConfig_t *measConfig; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 776c6b9275..f731ed0fbe 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -120,7 +120,7 @@ NR_DRB_ToAddModList_t *fill_DRB_configList(gNB_RRC_UE_t *ue) if (ue->nb_of_pdusessions == 0) return NULL; int nb_drb_to_setup = rrc->configuration.drbs; - long drb_priority[NGAP_MAX_DRBS_PER_UE] = {0}; + long drb_priority[MAX_DRBS_PER_UE] = {0}; uint8_t drb_id_to_setup_start = 0; NR_DRB_ToAddModList_t *DRB_configList = CALLOC(sizeof(*DRB_configList), 1); for (int i = 0; i < ue->nb_of_pdusessions; i++) { @@ -399,7 +399,7 @@ static NR_DRB_ToAddModList_t *createDRBlist(gNB_RRC_UE_t *ue, bool reestablish) NR_DRB_ToAddMod_t *DRB_config = NULL; NR_DRB_ToAddModList_t *DRB_configList = CALLOC(sizeof(*DRB_configList), 1); - for (int i = 0; i < NGAP_MAX_DRBS_PER_UE; i++) { + for (int i = 0; i < MAX_DRBS_PER_UE; i++) { if (ue->established_drbs[i].status != DRB_INACTIVE) { DRB_config = generateDRB_ASN1(&ue->established_drbs[i]); if (reestablish) { @@ -822,13 +822,13 @@ rrc_gNB_modify_dedicatedRRCReconfiguration( // search exist DRB_config int j; - for (j = 0; i < NGAP_MAX_DRBS_PER_UE; j++) { + for (j = 0; i < MAX_DRBS_PER_UE; j++) { if (ue_p->established_drbs[j].status != DRB_INACTIVE && ue_p->established_drbs[j].cnAssociation.sdap_config.pdusession_id == ue_p->pduSession[i].param.pdusession_id) break; } - if (j == NGAP_MAX_DRBS_PER_UE) { + if (j == MAX_DRBS_PER_UE) { ue_p->pduSession[i].xid = xid; ue_p->pduSession[i].status = PDU_SESSION_STATUS_FAILED; ue_p->pduSession[i].cause = NGAP_CAUSE_RADIO_NETWORK; @@ -1951,11 +1951,8 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_ case RRC_PDUSESSION_MODIFY: rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP(ctxt_pP, ue_context_p, xid); break; - case RRC_FIRST_RECONF: - rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p); - break; case RRC_DEFAULT_RECONF: - /* nothing to do */ + rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p); break; default: LOG_E(RRC, "Received unexpected xid: %d\n", xid); diff --git a/openair2/RRC/NR/rrc_gNB_radio_bearers.c b/openair2/RRC/NR/rrc_gNB_radio_bearers.c index 4c5c50fb00..77ad016350 100644 --- a/openair2/RRC/NR/rrc_gNB_radio_bearers.c +++ b/openair2/RRC/NR/rrc_gNB_radio_bearers.c @@ -52,7 +52,7 @@ void generateDRB(gNB_RRC_UE_t *ue, est_drb->drb_id = drb_id; est_drb->reestablishPDCP = -1; est_drb->recoverPDCP = -1; - for (i = 0; i < NGAP_MAX_DRBS_PER_UE; i++) { + for (i = 0; i < MAX_DRBS_PER_UE; i++) { if ((est_drb->cnAssociation.sdap_config.pdusession_id == 0 || est_drb->cnAssociation.sdap_config.pdusession_id == pduSession->param.pdusession_id) && est_drb->defaultDRBid == 0) { @@ -148,12 +148,12 @@ uint8_t next_available_drb(gNB_RRC_UE_t *ue, rrc_pdu_session_param_t *pdusession uint8_t drb_id; if (0 /*!is_gbr*/) { /* Find if Non-GBR DRB exists in the same PDU Session */ - for (drb_id = 0; drb_id < NGAP_MAX_DRBS_PER_UE; drb_id++) + for (drb_id = 0; drb_id < MAX_DRBS_PER_UE; drb_id++) if (pdusession->param.used_drbs[drb_id] == DRB_ACTIVE_NONGBR) return drb_id + 1; } /* GBR Flow or a Non-GBR DRB does not exist in the same PDU Session, find an available DRB */ - for (drb_id = 0; drb_id < NGAP_MAX_DRBS_PER_UE; drb_id++) + for (drb_id = 0; drb_id < MAX_DRBS_PER_UE; drb_id++) if (ue->DRB_active[drb_id] == DRB_INACTIVE) return drb_id + 1; /* From this point, we need to handle the case that all DRBs are already used by the UE. */ diff --git a/openair2/RRC/NR/rrc_gNB_radio_bearers.h b/openair2/RRC/NR/rrc_gNB_radio_bearers.h index 219bc21948..aff6e75ea6 100644 --- a/openair2/RRC/NR/rrc_gNB_radio_bearers.h +++ b/openair2/RRC/NR/rrc_gNB_radio_bearers.h @@ -27,8 +27,8 @@ #include "NR_DRB-ToAddMod.h" #include "NR_SRB-ToAddMod.h" -#define MAX_DRBS_PER_UE (32) /* Maximum number of Data Radio Bearers per UE */ -#define MAX_PDUS_PER_UE (8) /* Maximum number of PDU Sessions per UE */ +#include "common/platform_constants.h" + #define DRB_ACTIVE_NONGBR (2) /* DRB is used for Non-GBR Flows */ #define DRB_ACTIVE (1) #define DRB_INACTIVE (0) diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c index 06fb26536e..d0fb36c475 100644 --- a/openair2/RRC/NR_UE/L2_interface_ue.c +++ b/openair2/RRC/NR_UE/L2_interface_ue.c @@ -61,11 +61,8 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, { sdu_size_t sdu_size = 0; - switch(channel){ + switch(channel) { case NR_BCCH_BCH: - AssertFatal(nr_rrc_ue_decode_NR_BCCH_BCH_Message(module_id, gNB_index, (uint8_t*)pduP, pdu_len) == 0, "UE decode BCCH-BCH error!\n"); - break; - case NR_BCCH_DL_SCH: if (pdu_len>0) { LOG_T(NR_RRC, "[UE %d] Received SDU for NR-BCCH-DL-SCH on SRB %u from gNB %d\n", module_id, channel & RAB_OFFSET, @@ -88,6 +85,7 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, NR_RRC_MAC_BCCH_DATA_IND (message_p).slot = slot; NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu_size = sdu_size; NR_RRC_MAC_BCCH_DATA_IND (message_p).gnb_index = gNB_index; + NR_RRC_MAC_BCCH_DATA_IND (message_p).is_bch = (channel == NR_BCCH_BCH); itti_send_msg_to_task(TASK_RRC_NRUE, GNB_MODULE_ID_TO_INSTANCE(module_id), message_p); } break; diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 3ffae4b07d..892c48a734 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -451,6 +451,10 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* rrc_config_ { LOG_D(NR_RRC, "In NSA mode \n"); } + + if (get_softmodem_params()->sl_mode) { + configure_NR_SL_Preconfig(get_softmodem_params()->sync_ref); + } } else{ NR_UE_rrc_inst = NULL; @@ -480,24 +484,89 @@ int8_t nr_ue_process_physical_cell_group_config(NR_PhysicalCellGroupConfig_t *ph return 0; } +bool check_si_validity(NR_UE_RRC_SI_INFO *SI_info, int si_type) +{ + switch (si_type) { + case NR_SIB_TypeInfo__type_sibType2: + if (!SI_info->sib2) + return false; + break; + case NR_SIB_TypeInfo__type_sibType3: + if (!SI_info->sib3) + return false; + break; + case NR_SIB_TypeInfo__type_sibType4: + if (!SI_info->sib4) + return false; + break; + case NR_SIB_TypeInfo__type_sibType5: + if (!SI_info->sib5) + return false; + break; + case NR_SIB_TypeInfo__type_sibType6: + if (!SI_info->sib6) + return false; + break; + case NR_SIB_TypeInfo__type_sibType7: + if (!SI_info->sib7) + return false; + break; + case NR_SIB_TypeInfo__type_sibType8: + if (!SI_info->sib8) + return false; + break; + case NR_SIB_TypeInfo__type_sibType9: + if (!SI_info->sib9) + return false; + break; + case NR_SIB_TypeInfo__type_sibType10_v1610: + if (!SI_info->sib10) + return false; + break; + case NR_SIB_TypeInfo__type_sibType11_v1610: + if (!SI_info->sib11) + return false; + break; + case NR_SIB_TypeInfo__type_sibType12_v1610: + if (!SI_info->sib12) + return false; + break; + case NR_SIB_TypeInfo__type_sibType13_v1610: + if (!SI_info->sib13) + return false; + break; + case NR_SIB_TypeInfo__type_sibType14_v1610: + if (!SI_info->sib14) + return false; + break; + default : + AssertFatal(false, "Invalid SIB type %d\n", si_type); + } + return true; +} + int check_si_status(NR_UE_RRC_SI_INFO *SI_info) { - // schedule reception of SIB1 + if (!get_softmodem_params()->sa) + return 0; + // schedule reception of SIB1 if RRC doesn't have it if (!SI_info->sib1) return 1; else { - if (!SI_info->sib1->si_SchedulingInfo) - return 0; - // The UE in RRC_IDLE and RRC_INACTIVE shall ensure having - // a valid version of (at least) the MIB, SIB1 through - // SIB4 (and SIB5 if the UE supports E-UTRA) - if (!SI_info->sib2 || - !SI_info->sib3 || - !SI_info->sib4) - // we schedule reception of otherSI - // if UE RRC doesn't have any of the - // default SIBs for now - return 2; + if (SI_info->sib1->si_SchedulingInfo) { + // Check if RRC has configured default SI + // from SIB2 to SIB14 as current ASN1 version + // TODO can be used for on demand SI when (if) implemented + for (int i = 2; i < 15; i++) { + int si_index = i - 2; + if ((SI_info->default_otherSI_map >> si_index) & 0x01) { + // if RRC has no valid version of one of the default configured SI + // Then schedule reception of otherSI + if (!check_si_validity(SI_info, si_index)) + return 2; + } + } + } } return 0; } @@ -700,6 +769,22 @@ int8_t nr_rrc_ue_generate_ra_msg(module_id_t module_id, uint8_t gNB_index) { return 0; } +void nr_rrc_configure_default_SI(NR_UE_RRC_SI_INFO *SI_info, + NR_SIB1_t *sib1) +{ + struct NR_SI_SchedulingInfo *si_SchedulingInfo = sib1->si_SchedulingInfo; + if (!si_SchedulingInfo) + return; + SI_info->default_otherSI_map = 0; + for (int i = 0; i < si_SchedulingInfo->schedulingInfoList.list.count; i++) { + struct NR_SchedulingInfo *schedulingInfo = si_SchedulingInfo->schedulingInfoList.list.array[i]; + for (int j = 0; j < schedulingInfo->sib_MappingInfo.list.count; j++) { + struct NR_SIB_TypeInfo *sib_Type = schedulingInfo->sib_MappingInfo.list.array[j]; + SI_info->default_otherSI_map |= 1 << sib_Type->type; + } + } +} + /**\brief decode NR BCCH-DLSCH (SI) messages \param module_idP module id \param gNB_index gNB index @@ -758,6 +843,8 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(module_id_t module_id, LOG_D(PHY,"Setting state to RRC_STATE_IDLE_NR\n"); nr_rrc_set_state(module_id, RRC_STATE_IDLE_NR); } + // configure default SI + nr_rrc_configure_default_SI(SI_info, sib1); // configure timers and constant nr_rrc_set_sib1_timers_and_constants(&NR_UE_rrc_inst[module_id].timers_and_constants, sib1); // take ServingCellConfigCommon and configure L1/L2 @@ -1961,15 +2048,22 @@ void *rrc_nrue_task(void *args_p) break; case NR_RRC_MAC_BCCH_DATA_IND: - LOG_D(NR_RRC, "[UE %d] Received %s: frameP %d, gNB %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p), - NR_RRC_MAC_BCCH_DATA_IND (msg_p).frame, NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index); - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NOT_A_RNTI, NR_RRC_MAC_BCCH_DATA_IND (msg_p).frame, 0,NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index); - nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message (ctxt.module_id, - NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index, - NR_RRC_MAC_BCCH_DATA_IND (msg_p).sdu, - NR_RRC_MAC_BCCH_DATA_IND (msg_p).sdu_size, - NR_RRC_MAC_BCCH_DATA_IND (msg_p).rsrq, - NR_RRC_MAC_BCCH_DATA_IND (msg_p).rsrp); + LOG_D(NR_RRC, "[UE %d] Received %s: gNB %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p), + NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index); + NRRrcMacBcchDataInd *bcch = &NR_RRC_MAC_BCCH_DATA_IND (msg_p); + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NOT_A_RNTI, bcch->frame, 0, bcch->gnb_index); + if (bcch->is_bch) + nr_rrc_ue_decode_NR_BCCH_BCH_Message(ue_mod_id, + bcch->gnb_index, + bcch->sdu, + bcch->sdu_size); + else + nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(ctxt.module_id, + bcch->gnb_index, + bcch->sdu, + bcch->sdu_size, + bcch->rsrq, + bcch->rsrp); break; case NR_RRC_MAC_CCCH_DATA_IND: @@ -2059,7 +2153,7 @@ void *rrc_nrue_task(void *args_p) break; } LOG_D(NR_RRC, "[UE %d] RRC Status %d\n", ue_mod_id, nr_rrc_get_state(ue_mod_id)); - result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p); + result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), msg_p); AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); msg_p = NULL; } diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index ea9ae55ba2..53eaf69c4b 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -134,6 +134,7 @@ typedef enum RA_trigger_e { } RA_trigger_t; typedef struct UE_RRC_SI_INFO_NR_s { + uint32_t default_otherSI_map; NR_SIB1_t *sib1; int sib1_timer; NR_SIB2_t *sib2; diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index 6d453dbec5..d4bfe0e52d 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -173,6 +173,7 @@ void handle_rlf_sync(NR_UE_Timers_Constants_t *tac, void nr_rrc_handle_SetupRelease_RLF_TimersAndConstants(NR_UE_RRC_INST_t *rrc, struct NR_SetupRelease_RLF_TimersAndConstants *rlf_TimersAndConstants); +int configure_NR_SL_Preconfig(int sync_source); /** @}*/ #endif diff --git a/openair2/RRC/NR_UE/rrc_sl_preconfig.c b/openair2/RRC/NR_UE/rrc_sl_preconfig.c new file mode 100644 index 0000000000..15b23a9956 --- /dev/null +++ b/openair2/RRC/NR_UE/rrc_sl_preconfig.c @@ -0,0 +1,432 @@ +/* + * 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 + */ + +#define RRC_SL_PRECONFIG +#define RRC_SL_PRECONFIG_C + +#include "oai_asn1.h" +#include "NR_SL-PreconfigurationNR-r16.h" +#include "common/utils/LOG/log.h" +#include "sl_preconfig_paramvalues.h" +#include "common/config/config_userapi.h" + +static void prepare_NR_SL_SyncConfig(NR_SL_SyncConfig_r16_t *sl_syncconfig) +{ + + // Hysteris when evaluating SyncRef UE + sl_syncconfig->sl_SyncRefMinHyst_r16 = NULL; + + // Hysteris when evaluating SyncRef UE + sl_syncconfig->sl_SyncRefDiffHyst_r16 = NULL; + + // Filtering for SL RSRP + sl_syncconfig->sl_filterCoefficient_r16 = NULL; + + // SSB Periodicity within 16 frames. + sl_syncconfig->sl_SSB_TimeAllocation1_r16 = calloc(1, sizeof(NR_SL_SSB_TimeAllocation_r16_t)); + sl_syncconfig->sl_SSB_TimeAllocation1_r16->sl_NumSSB_WithinPeriod_r16 = calloc(1, sizeof(long)); + sl_syncconfig->sl_SSB_TimeAllocation1_r16->sl_TimeOffsetSSB_r16 = calloc(1, sizeof(long)); + sl_syncconfig->sl_SSB_TimeAllocation1_r16->sl_TimeInterval_r16 = calloc(1, sizeof(long)); + sl_syncconfig->sl_SSB_TimeAllocation2_r16 = NULL; + sl_syncconfig->sl_SSB_TimeAllocation3_r16 = NULL; + + //SLSS Id + sl_syncconfig->sl_SSID_r16 = NULL; + + // Threshold to be used in coverage + sl_syncconfig->txParameters_r16.syncTxThreshIC_r16 = NULL; + + // Threshold to be used when Out of coverage + sl_syncconfig->txParameters_r16.syncTxThreshOoC_r16 = NULL; + + // Syncconfig is used when UE is synced to GNSS if set, else if UE is synced to eNB/gNB + sl_syncconfig->gnss_Sync_r16 = calloc(1, sizeof(long)); + *sl_syncconfig->gnss_Sync_r16 = 0; // GNSS + + char aprefix[MAX_OPTNAME_SIZE*2 + 8]; + paramdef_t SL_SYNCCFGPARAMS[] = SL_SYNCPARAMS_DESC(sl_syncconfig); + paramlist_def_t SL_SYNCFGParamList = {SL_CONFIG_STRING_SL_SYNCCONFIG_LIST, NULL, 0}; + sprintf(aprefix, "%s.[%i]", SL_CONFIG_STRING_SL_PRECONFIGURATION, 0); + config_getlist(&SL_SYNCFGParamList, NULL, 0, aprefix); + LOG_I(RRC, "NUM SL-SYNCCFG elem in cfg file:%d\n", SL_SYNCFGParamList.numelt); + sprintf(aprefix, "%s.[%i].%s.[%i]", SL_CONFIG_STRING_SL_PRECONFIGURATION, 0,SL_CONFIG_STRING_SL_SYNCCONFIG_LIST, 0); + config_get(SL_SYNCCFGPARAMS,sizeof(SL_SYNCCFGPARAMS)/sizeof(paramdef_t),aprefix); +} + +static void prepare_NR_SL_ResourcePool(NR_SL_ResourcePool_r16_t *sl_res_pool, + uint16_t is_txpool, + uint16_t is_sl_syncsource) +{ + + // PSCCH configuration + sl_res_pool->sl_PSCCH_Config_r16 = calloc(1, sizeof(*sl_res_pool->sl_PSCCH_Config_r16)); + sl_res_pool->sl_PSCCH_Config_r16->present = NR_SetupRelease_SL_PSCCH_Config_r16_PR_setup; + sl_res_pool->sl_PSCCH_Config_r16->choice.setup = calloc(1, sizeof(NR_SL_PSCCH_Config_r16_t)); + // Indicates number of symbols for PSCCH in a resource pool + sl_res_pool->sl_PSCCH_Config_r16->choice.setup->sl_TimeResourcePSCCH_r16 = calloc(1, sizeof(long)); + + // Indicates number of PRBs for PSCCH in a resource pool + sl_res_pool->sl_PSCCH_Config_r16->choice.setup->sl_FreqResourcePSCCH_r16 = calloc(1, sizeof(long)); + + // Inititation during PSCCH DMRS Sequence generation + sl_res_pool->sl_PSCCH_Config_r16->choice.setup->sl_DMRS_ScrambleID_r16 = calloc(1, sizeof(long)); + *sl_res_pool->sl_PSCCH_Config_r16->choice.setup->sl_DMRS_ScrambleID_r16 = 0; + + // num reserve bits used for first stage SCI + sl_res_pool->sl_PSCCH_Config_r16->choice.setup->sl_NumReservedBits_r16 = calloc(1, sizeof(long)); + *sl_res_pool->sl_PSCCH_Config_r16->choice.setup->sl_NumReservedBits_r16 = 2; + + //PSSCH Configuration + sl_res_pool->sl_PSSCH_Config_r16 = calloc(1, sizeof(NR_SetupRelease_SL_PSSCH_Config_r16_t)); + sl_res_pool->sl_PSSCH_Config_r16->present = NR_SetupRelease_SL_PSSCH_Config_r16_PR_setup; + sl_res_pool->sl_PSSCH_Config_r16->choice.setup = calloc(1, sizeof(NR_SL_PSSCH_Config_r16_t)); + sl_res_pool->sl_PSSCH_Config_r16->choice.setup->sl_PSSCH_DMRS_TimePatternList_r16 = + calloc(1, sizeof(*sl_res_pool->sl_PSSCH_Config_r16->choice.setup->sl_PSSCH_DMRS_TimePatternList_r16)); + for(int i=0; i<3; i++) { + long *p = calloc(1, sizeof(long)); + *p = 2+i; // valid values: 2..4 + ASN_SEQUENCE_ADD(&sl_res_pool->sl_PSSCH_Config_r16->choice.setup->sl_PSSCH_DMRS_TimePatternList_r16->list, p); + } + + //PSFCH configuration + sl_res_pool->sl_PSFCH_Config_r16 = NULL; + + // indicates allowed sync sources which are allowed to use this resource pool + sl_res_pool->sl_SyncAllowed_r16 = calloc(1, sizeof(NR_SL_SyncAllowed_r16_t)); + + //configured resources can be used if UE is directly/indirectly synced to network. + sl_res_pool->sl_SyncAllowed_r16->gnbEnb_Sync_r16 = NULL; + + //configured resources can be used if UE is directly/indirectly synced to GNSS. + sl_res_pool->sl_SyncAllowed_r16->gnss_Sync_r16 = calloc(1, sizeof(long)); + *sl_res_pool->sl_SyncAllowed_r16->gnss_Sync_r16 = NR_SL_SyncAllowed_r16__gnss_Sync_r16_true; + + //configured resources can be used if UE is directly/indirectly synced to SYNC REF UE. + sl_res_pool->sl_SyncAllowed_r16->ue_Sync_r16 = calloc(1, sizeof(long)); + *sl_res_pool->sl_SyncAllowed_r16->ue_Sync_r16 = NR_SL_SyncAllowed_r16__ue_Sync_r16_true; + + //Min freq domain resources used for resource sensing. Size of Subchannels + sl_res_pool->sl_SubchannelSize_r16 = calloc(1, sizeof(long)); + + sl_res_pool->dummy = NULL; + + // lowest RB index of lowest subch in this resource pool + sl_res_pool->sl_StartRB_Subchannel_r16 = calloc(1, sizeof(long)); + + //number of subchannels in this res pool. contiguous PRBs + sl_res_pool->sl_NumSubchannel_r16 = calloc(1, sizeof(long)); + + + // 64QAM table is default. in case other MCS tables needs tobe used. + sl_res_pool->sl_Additional_MCS_Table_r16 = NULL; + + sl_res_pool->sl_ThreshS_RSSI_CBR_r16 = NULL; + sl_res_pool->sl_TimeWindowSizeCBR_r16 = NULL; + sl_res_pool->sl_TimeWindowSizeCR_r16 = NULL; + sl_res_pool->sl_PTRS_Config_r16 = NULL; + sl_res_pool->sl_UE_SelectedConfigRP_r16 = NULL; + sl_res_pool->sl_RxParametersNcell_r16 = NULL; + sl_res_pool->sl_ZoneConfigMCR_List_r16 = NULL; + sl_res_pool->sl_FilterCoefficient_r16 = NULL; + + //number of contiguous PRBS in this res pool. + sl_res_pool->sl_RB_Number_r16 = calloc(1, sizeof(long)); + + sl_res_pool->sl_PreemptionEnable_r16 = NULL; + sl_res_pool->sl_PriorityThreshold_UL_URLLC_r16 = NULL; + sl_res_pool->sl_PriorityThreshold_r16 = NULL; + sl_res_pool->sl_X_Overhead_r16 = NULL; + sl_res_pool->sl_PowerControl_r16 = NULL; + sl_res_pool->sl_TxPercentageList_r16 = NULL; + sl_res_pool->sl_MinMaxMCS_List_r16 = NULL; + + sl_res_pool->ext1 = calloc(1, sizeof(*sl_res_pool->ext1)); + sl_res_pool->ext1->sl_TimeResource_r16 = calloc(1, sizeof(*sl_res_pool->ext1->sl_TimeResource_r16)); + sl_res_pool->ext1->sl_TimeResource_r16->size = 8; + sl_res_pool->ext1->sl_TimeResource_r16->bits_unused = 4; + sl_res_pool->ext1->sl_TimeResource_r16->buf = calloc(sl_res_pool->ext1->sl_TimeResource_r16->size, sizeof(uint8_t)); + // EX: BITMAP 10101010.. indicating every alternating slot supported for sidelink + for (int i=0;iext1->sl_TimeResource_r16->size;i++) { + if (is_txpool) { + sl_res_pool->ext1->sl_TimeResource_r16->buf[i] = (is_sl_syncsource) ? 0xAA //0x88;//0xAA; + : 0x55;//0x11;//0x55; + } else { + sl_res_pool->ext1->sl_TimeResource_r16->buf[i] = (is_sl_syncsource) ? 0x55 //0x88;//0xAA; + : 0xAA;//0x11;//0x55; + } + } + + // mask out unused bits + sl_res_pool->ext1->sl_TimeResource_r16->buf[sl_res_pool->ext1->sl_TimeResource_r16->size - 1] &= (0 - (1 << (sl_res_pool->ext1->sl_TimeResource_r16->bits_unused))); + + char aprefix[MAX_OPTNAME_SIZE*2 + 8]; + paramdef_t SL_POOLPARAMS[] = SL_RESPOOLPARAMS_DESC(sl_res_pool); + if (is_txpool) + sprintf(aprefix, "%s.[%i].%s.[%i]", SL_CONFIG_STRING_SL_PRECONFIGURATION, 0,SL_CONFIG_STRING_SL_TX_RPOOL_LIST, 0); + else + sprintf(aprefix, "%s.[%i].%s.[%i]", SL_CONFIG_STRING_SL_PRECONFIGURATION, 0,SL_CONFIG_STRING_SL_RX_RPOOL_LIST, 0); + + config_get(SL_POOLPARAMS,sizeof(SL_POOLPARAMS)/sizeof(paramdef_t),aprefix); +} + +static void prepare_NR_SL_BWPConfigCommon(NR_SL_BWP_ConfigCommon_r16_t *sl_bwp, + uint16_t num_tx_pools, + uint16_t num_rx_pools, + uint16_t sl_syncsource) +{ + + sl_bwp->sl_BWP_Generic_r16 = calloc(1, sizeof(NR_SL_BWP_Generic_r16_t)); + sl_bwp->sl_BWP_Generic_r16->sl_BWP_r16 = calloc(1, sizeof(NR_BWP_t)); + // if Cyclicprefix is NULL, then default value Normal cyclic prefix is configured. else EXT CP. + sl_bwp->sl_BWP_Generic_r16->sl_BWP_r16->cyclicPrefix = NULL; + + // Value can be between symbols 7 to 14 + sl_bwp->sl_BWP_Generic_r16->sl_LengthSymbols_r16 = calloc(1, sizeof(long)); + + // Value can be between symbols 0 to 7 + sl_bwp->sl_BWP_Generic_r16->sl_StartSymbol_r16 = calloc(1, sizeof(long)); + + sl_bwp->sl_BWP_Generic_r16->sl_PSBCH_Config_r16 = calloc(1,sizeof(NR_SL_PSBCH_Config_r16_t)); + // PSBCH CONFIG contains PO and alpha for PSBCH powercontrol. + sl_bwp->sl_BWP_Generic_r16->sl_PSBCH_Config_r16->present = NR_SetupRelease_SL_PSBCH_Config_r16_PR_release; + + sl_bwp->sl_BWP_Generic_r16->sl_TxDirectCurrentLocation_r16 = NULL; + + char aprefix[MAX_OPTNAME_SIZE*2 + 8]; + paramdef_t SL_BWPPARAMS[] = SL_BWPPARAMS_DESC(sl_bwp); + paramlist_def_t SL_BWPParamList = {SL_CONFIG_STRING_SL_BWP_LIST, NULL, 0}; + sprintf(aprefix, "%s.[%i]", SL_CONFIG_STRING_SL_PRECONFIGURATION, 0); + config_getlist(&SL_BWPParamList, NULL, 0, aprefix); + LOG_I(RRC, "NUM SL-BWP elem in cfg file:%d\n", SL_BWPParamList.numelt); + sprintf(aprefix, "%s.[%i].%s.[%i]", SL_CONFIG_STRING_SL_PRECONFIGURATION, 0, SL_CONFIG_STRING_SL_BWP_LIST, 0); + config_get( SL_BWPPARAMS,sizeof(SL_BWPPARAMS)/sizeof(paramdef_t),aprefix); + + sl_bwp->sl_BWP_PoolConfigCommon_r16 = calloc(1, sizeof(NR_SL_BWP_PoolConfigCommon_r16_t)); + + paramlist_def_t SL_RxPoolParamList = {SL_CONFIG_STRING_SL_RX_RPOOL_LIST, NULL, 0}; + sprintf(aprefix, "%s.[%i]", SL_CONFIG_STRING_SL_PRECONFIGURATION, 0); + config_getlist(&SL_RxPoolParamList, NULL, 0, aprefix); + LOG_I(RRC, "NUM Rx RPOOLs in cfg file:%d\n", SL_RxPoolParamList.numelt); + AssertFatal(SL_RxPoolParamList.numelt <= 1 && num_rx_pools <= 1, "Only Max 1 RX Respool Supported now\n"); + + if (num_rx_pools || SL_RxPoolParamList.numelt) { + // Receiving resource pool. + NR_SL_ResourcePool_r16_t *respool = calloc(1, sizeof(*respool)); + sl_bwp->sl_BWP_PoolConfigCommon_r16->sl_RxPool_r16 = calloc(1, sizeof(*sl_bwp->sl_BWP_PoolConfigCommon_r16->sl_RxPool_r16)); + ASN_SEQUENCE_ADD(&sl_bwp->sl_BWP_PoolConfigCommon_r16->sl_RxPool_r16->list, respool); + // Fill RX resource pool + prepare_NR_SL_ResourcePool(sl_bwp->sl_BWP_PoolConfigCommon_r16->sl_RxPool_r16->list.array[0], 0, sl_syncsource); + } else + sl_bwp->sl_BWP_PoolConfigCommon_r16->sl_RxPool_r16 = NULL; + + paramlist_def_t SL_TxPoolParamList = {SL_CONFIG_STRING_SL_TX_RPOOL_LIST, NULL, 0}; + sprintf(aprefix, "%s.[%i]", SL_CONFIG_STRING_SL_PRECONFIGURATION, 0); + config_getlist(&SL_TxPoolParamList, NULL, 0, aprefix); + LOG_I(RRC, "NUM Tx RPOOL in cfg file:%d\n", SL_TxPoolParamList.numelt); + AssertFatal(SL_TxPoolParamList.numelt <= 1 && num_tx_pools <= 1, "Only Max 1 TX Respool Supported now\n"); + + if (num_tx_pools || SL_TxPoolParamList.numelt) { + //resource pool(s) to transmit NR SL + NR_SL_ResourcePoolConfig_r16_t *respoolcfg = calloc(1, sizeof(*respoolcfg)); + sl_bwp->sl_BWP_PoolConfigCommon_r16->sl_TxPoolSelectedNormal_r16 = + calloc(1, sizeof(*sl_bwp->sl_BWP_PoolConfigCommon_r16->sl_TxPoolSelectedNormal_r16)); + ASN_SEQUENCE_ADD(&sl_bwp->sl_BWP_PoolConfigCommon_r16->sl_TxPoolSelectedNormal_r16->list, respoolcfg); + sl_bwp->sl_BWP_PoolConfigCommon_r16->sl_TxPoolSelectedNormal_r16->list.array[0]->sl_ResourcePoolID_r16 = 0; + sl_bwp->sl_BWP_PoolConfigCommon_r16->sl_TxPoolSelectedNormal_r16->list.array[0]->sl_ResourcePool_r16 = calloc(1, sizeof(NR_SL_ResourcePool_r16_t)); + // Fill tx resource pool + prepare_NR_SL_ResourcePool(sl_bwp->sl_BWP_PoolConfigCommon_r16->sl_TxPoolSelectedNormal_r16->list.array[0]->sl_ResourcePool_r16, 1, sl_syncsource); + } else + sl_bwp->sl_BWP_PoolConfigCommon_r16->sl_TxPoolSelectedNormal_r16 = NULL; + + sl_bwp->sl_BWP_PoolConfigCommon_r16->sl_TxPoolExceptional_r16 = NULL; +} + +static void prepare_NR_SL_FreqConfigCommon(NR_SL_FreqConfigCommon_r16_t *sl_fcfg, + uint16_t num_tx_pools, + uint16_t num_rx_pools, + uint16_t sl_syncsource) +{ + + // Sub carrier spacing used on this frequency configured. + NR_SCS_SpecificCarrier_t *scs_specific = calloc(1, sizeof(*scs_specific)); + ASN_SEQUENCE_ADD(&sl_fcfg->sl_SCS_SpecificCarrierList_r16.list, scs_specific); + + // NR bands for Sidelink n47, n38. + // N47band - 5855Mhz - 5925Mhz + //sl_fcfg->sl_AbsoluteFrequencyPointA_r16 = 792000; //freq 5880Mhz + + //SL SSB chosen to be located from RB10 to RB21. points to the middle of the SSB block. + //SSB location should be within Sidelink BWP + //792000 + 10*12*2 + 66*2. channel raster is 15Khz for band47 + sl_fcfg->sl_AbsoluteFrequencySSB_r16 = calloc(1, sizeof(NR_ARFCN_ValueNR_t)); + + //NR SL transmission with a 7.5 Khz shift to the LTE raster. if absent, freq shift is disabled. + //Required if carrier freq configured for NR SL shared by LTE SL + sl_fcfg->frequencyShift7p5khzSL_r16 = NULL; + + //NR SL transmission with valueN*5Khz shift to LTE raster. + sl_fcfg->valueN_r16 = 0; + + char aprefix[MAX_OPTNAME_SIZE*2 + 8]; + paramdef_t SL_FCCPARAMS[] = SL_FCCPARAMS_DESC(sl_fcfg); + paramlist_def_t SL_FCCParamList = {SL_CONFIG_STRING_SL_FCC_LIST, NULL, 0}; + sprintf(aprefix, "%s.[%i]", SL_CONFIG_STRING_SL_PRECONFIGURATION,0); + config_getlist(&SL_FCCParamList, NULL, 0, aprefix); + LOG_I(RRC, "NUM SL-FCC elem in cfg file:%d\n", SL_FCCParamList.numelt); + sprintf(aprefix, "%s.[%i].%s.[%i]", SL_CONFIG_STRING_SL_PRECONFIGURATION,0, SL_CONFIG_STRING_SL_FCC_LIST, 0); + config_get( SL_FCCPARAMS,sizeof(SL_FCCPARAMS)/sizeof(paramdef_t),aprefix); + + // Sidelink BWP configuration. + // In REL16, 17 SUPPORTS only 1 SIDELINK Bandwidth part + NR_SL_BWP_ConfigCommon_r16_t *bwpcfgcommon = calloc(1, sizeof(*bwpcfgcommon)); + sl_fcfg->sl_BWP_List_r16 = calloc(1, sizeof(*sl_fcfg->sl_BWP_List_r16)); + ASN_SEQUENCE_ADD(&sl_fcfg->sl_BWP_List_r16->list, bwpcfgcommon); + prepare_NR_SL_BWPConfigCommon(sl_fcfg->sl_BWP_List_r16->list.array[0], num_tx_pools, num_rx_pools, sl_syncsource); + + // sync prio between GNSS and gNB/eNB + sl_fcfg->sl_SyncPriority_r16 = calloc(1, sizeof(long)); + *sl_fcfg->sl_SyncPriority_r16 = 0; // Set to GNSS + + // If TRUE/1 - Network can be selected as sync source directly/indirectly in case syncprio = GNSS. + sl_fcfg->sl_NbAsSync_r16 = calloc(1, sizeof(long)); + *sl_fcfg->sl_NbAsSync_r16 = 1; + + // config info related to rx and tx of SL SYNC SIGNALS (SLSS) + NR_SL_SyncConfig_r16_t *synccfg = calloc(1, sizeof(*synccfg)); + sl_fcfg->sl_SyncConfigList_r16 = calloc(1, sizeof(*sl_fcfg->sl_SyncConfigList_r16)); + ASN_SEQUENCE_ADD(&sl_fcfg->sl_SyncConfigList_r16->list, synccfg); + prepare_NR_SL_SyncConfig(sl_fcfg->sl_SyncConfigList_r16->list.array[0]); + +} + +NR_SL_PreconfigurationNR_r16_t *prepare_NR_SL_PRECONFIGURATION(uint16_t num_tx_pools, + uint16_t num_rx_pools, + uint16_t sl_syncsource) +{ + + NR_SL_PreconfigurationNR_r16_t *sl_preconfiguration = CALLOC(1, sizeof(NR_SL_PreconfigurationNR_r16_t)); + NR_SidelinkPreconfigNR_r16_t *sl_preconfig = &sl_preconfiguration->sidelinkPreconfigNR_r16; + + //FILL in Frequency config common + NR_SL_FreqConfigCommon_r16_t *freqcfgcommon = calloc(1, sizeof(*freqcfgcommon)); + sl_preconfig->sl_PreconfigFreqInfoList_r16 = calloc(1, sizeof(*sl_preconfig->sl_PreconfigFreqInfoList_r16)); + //Supported only 1 FREQs for NR SL communication. + ASN_SEQUENCE_ADD(&sl_preconfig->sl_PreconfigFreqInfoList_r16->list, freqcfgcommon); + + prepare_NR_SL_FreqConfigCommon(sl_preconfig->sl_PreconfigFreqInfoList_r16->list.array[0], + num_tx_pools, num_rx_pools, sl_syncsource); + + // NR Frequency list + sl_preconfig->sl_PreconfigNR_AnchorCarrierFreqList_r16 = NULL; + + // EUTRA Frequency list + sl_preconfig->sl_PreconfigEUTRA_AnchorCarrierFreqList_r16 = NULL; + + // NR sidelink radio bearer(s) configuration(s) + sl_preconfig->sl_RadioBearerPreConfigList_r16 = NULL; // fill later + + // NR sidelink RLC bearer(s) configuration(s) + sl_preconfig->sl_RLC_BearerPreConfigList_r16 = NULL; // fill later + + //Measurement and reporting configuration + sl_preconfig->sl_MeasPreConfig_r16 = NULL; + + //DFN timing offset used if GNSS is used as sync source. + //1-.001ms, 2 - .002ms so on. value 0 if absent. + sl_preconfig->sl_OffsetDFN_r16 = NULL; + + // t400 started upon txn of RRCreconfSidelink. + sl_preconfig->t400_r16 = NULL; + + //Max num consecutive HARQ DTX before triggering SL RLF. + sl_preconfig->sl_MaxNumConsecutiveDTX_r16 = NULL; + + //Priority of SSB transmission and reception. used in comparison to UL rxns/txns + sl_preconfig->sl_SSB_PriorityNR_r16 = NULL; + + //Contains TDD ULDL confiuguration to be used by the sync source UE. + //Currently set to the default used in OAI 5G. Changes TBD.. + //For the UE with sync reference as another UE, TDD ULDL config is determined from SL-MIB + sl_preconfig->sl_PreconfigGeneral_r16 = calloc(1, sizeof(NR_SL_PreconfigGeneral_r16_t)); + sl_preconfig->sl_PreconfigGeneral_r16->sl_TDD_Configuration_r16 = calloc(1, sizeof(NR_TDD_UL_DL_ConfigCommon_t)); + NR_TDD_UL_DL_ConfigCommon_t *tdd_uldl_cfg = sl_preconfig->sl_PreconfigGeneral_r16->sl_TDD_Configuration_r16; + tdd_uldl_cfg->pattern1.ext1 = NULL; + tdd_uldl_cfg->pattern2 = NULL; + + char aprefix[MAX_OPTNAME_SIZE*2 + 8]; + sprintf(aprefix, "%s.[%i]", SL_CONFIG_STRING_SL_PRECONFIGURATION,0); + paramdef_t SLTDDCFG_PARAMS[] = SL_TDDCONFIGPARAMS_DESC(tdd_uldl_cfg); + config_get(SLTDDCFG_PARAMS,sizeof(SLTDDCFG_PARAMS)/sizeof(paramdef_t),aprefix); + + NR_SL_FreqConfigCommon_r16_t *fcc = sl_preconfig->sl_PreconfigFreqInfoList_r16->list.array[0]; + tdd_uldl_cfg->referenceSubcarrierSpacing = + fcc->sl_SCS_SpecificCarrierList_r16.list.array[0]->subcarrierSpacing; + NR_SL_BWP_ConfigCommon_r16_t *sl_bwp = fcc->sl_BWP_List_r16->list.array[0]; + sl_bwp->sl_BWP_Generic_r16->sl_BWP_r16->subcarrierSpacing = + fcc->sl_SCS_SpecificCarrierList_r16.list.array[0]->subcarrierSpacing; + + // Configurations used for UE autonomous resource selection + sl_preconfig->sl_UE_SelectedPreConfig_r16 = NULL; + + // indicates if CSI reporting supported in SL unicast. + sl_preconfig->sl_CSI_Acquisition_r16 = NULL; + + // ROHC profiles for NR SL + sl_preconfig->sl_RoHC_Profiles_r16 = NULL; + + // MaxCID value for PDCP as specified in 38.323 + sl_preconfig->sl_MaxCID_r16 = NULL; + + + return sl_preconfiguration; +} + + +int configure_NR_SL_Preconfig(int sync_source) +{ + + NR_SL_PreconfigurationNR_r16_t *sl_preconfig = NULL; + int num_txpools = 0, num_rxpools = 0; + + if (sync_source) { + //SL-Preconfiguration with 1 txpool, 0 rxpool if UE is a syncsource + num_txpools = 1; + sl_preconfig = prepare_NR_SL_PRECONFIGURATION(num_txpools,num_rxpools,sync_source); + + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + xer_fprint(stdout, &asn_DEF_NR_SL_PreconfigurationNR_r16, sl_preconfig); + } + } else { + //SL-Preconfiguration with 0 txpool, 1 rxpool if UE is not a syncsource + num_rxpools = 1; + sl_preconfig = prepare_NR_SL_PRECONFIGURATION(num_txpools,num_rxpools,sync_source); + + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + xer_fprint(stdout, &asn_DEF_NR_SL_PreconfigurationNR_r16, sl_preconfig); + } + } + + ASN_STRUCT_FREE(asn_DEF_NR_SL_PreconfigurationNR_r16, sl_preconfig); + sl_preconfig = NULL; + //END....... + + return 0; +} diff --git a/openair2/RRC/NR_UE/sl_preconfig_paramvalues.h b/openair2/RRC/NR_UE/sl_preconfig_paramvalues.h new file mode 100644 index 0000000000..a44c5e4d1f --- /dev/null +++ b/openair2/RRC/NR_UE/sl_preconfig_paramvalues.h @@ -0,0 +1,158 @@ +/* + * 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 __SL_PRECONFIG_PARAMSVALUES__H__ +#define __SL_PRECONFIG_PARAMSVALUES__H__ + +#include "NR_SL-PreconfigurationNR-r16.h" +#include "common/config/config_userapi.h" + +#define SL_CONFIG_STRING_SL_PRECONFIGURATION "SIDELINK_PRECONFIGURATION" + +/* Sidelink Frequency common configuration in SL-Preconfig */ +#define SL_CONFIG_STRING_SL_FCC_LIST "sl_FrequencyCommonConfig" +#define SL_CONFIG_STRING_SLOFFSETTOCARRIER "sl_offstToCarrier" +#define SL_CONFIG_STRING_FCC_SUBCARRIERSPACING "sl_subcarrierSpacing" +#define SL_CONFIG_STRING_SLCARRIERBANDWIDTH "sl_carrierBandwidth" +#define SL_CONFIG_STRING_SLABSOLUTEFREQUENCYSSB "sl_absoluteFrequencySSB" +#define SL_CONFIG_STRING_SLABSOLUEFREQUENCYPOINTA "sl_absoluteFrequencyPointA" + +// Sidelink TDD ULDL configuration parameters in SL-Preconfig +#define SL_CONFIG_STRING_DLULTRANSMISSIONPERIODICITY "sl_dl_UL_TransmissionPeriodicity" +#define SL_CONFIG_STRING_NROFDOWNLINKSLOTS "sl_nrofDownlinkSlots" +#define SL_CONFIG_STRING_NROFDOWNLINKSYMBOLS "sl_nrofDownlinkSymbols" +#define SL_CONFIG_STRING_NROFUPLINKSLOTS "sl_nrofUplinkSlots" +#define SL_CONFIG_STRING_NROFUPLINKSYMBOLS "sl_nrofUplinkSymbols" + + +// Sidelink sync config parameters in SL-Preconfig. +// 3 sets possible per sync config list entry +#define SL_CONFIG_STRING_SL_SYNCCONFIG_LIST "sl_syncCfg" +#define SL_CONFIG_STRING_SL_NUMSSB_WITHINPERIOD_0 "sl_NumSSB_WithinPeriod_0" +#define SL_CONFIG_STRING_SL_TIMEOFFSET_SSB_0 "sl_TimeOffsetSSB_0" +#define SL_CONFIG_STRING_SL_TIMEINTERVAL_0 "sl_TimeInterval_0" +#define SL_CONFIG_STRING_SL_NUMSSB_WITHINPERIOD_1 "sl_NumSSB_WithinPeriod_1" +#define SL_CONFIG_STRING_SL_TIMEOFFSET_SSB_1 "sl_TimeOffsetSSB_1" +#define SL_CONFIG_STRING_SL_TIMEINTERVAL_1 "sl_TimeInterval_1" +#define SL_CONFIG_STRING_SL_NUMSSB_WITHINPERIOD_2 "sl_NumSSB_WithinPeriod_2" +#define SL_CONFIG_STRING_SL_TIMEOFFSET_SSB_2 "sl_TimeOffsetSSB_2" +#define SL_CONFIG_STRING_SL_TIMEINTERVAL_2 "sl_TimeInterval_2" + + +/*Sidelink Bandwidth related parameters in SL-Preconfig */ +#define SL_CONFIG_STRING_SL_BWP_LIST "sl_BWP" +#define SL_CONFIG_STRING_SL_BWP_START_AND_SIZE "sl_locationAndBandwidth" +#define SL_CONFIG_STRING_SL_BWP_NUM_SYMBOLS "sl_LengthSymbols" +#define SL_CONFIG_STRING_SL_BWP_START_SYMBOL "sl_StartSymbol" + + + +/*Sidelink Resource pool related parameters in SL-Preconfig */ +#define SL_CONFIG_STRING_SL_RX_RPOOL_LIST "sl_RxResPools" +#define SL_CONFIG_STRING_SL_TX_RPOOL_LIST "sl_TxResPools" +#define SL_CONFIG_STRING_RESPOOL_PSCCH_NUMSYM "sl_TimeResourcePSCCH" +#define SL_CONFIG_STRING_RESPOOL_PSCCH_NUMRBS "sl_FreqResourcePSCCH" +#define SL_CONFIG_STRING_RESPOOL_SUBCH_SIZE_IN_RBS "sl_SubchannelSize" +#define SL_CONFIG_STRING_RESPOOL_SUBCH_START_RB "sl_StartRB_Subchannel" +#define SL_CONFIG_STRING_RESPOOL_NUM_RBS "sl_RB_Number" +#define SL_CONFIG_STRING_RESPOOL_NUM_SUBCHS "sl_NumSubchannel" + + + +/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* Sidelink Frequency common Cell Config parameters */ +/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +/* Please refer to 3GPP SPEC 38.331 (RRC Specification) for details about these parameters + sl_AbsoluteFrequencyPointA_r16 - ARFCN of the lowest subcarrier for sidelink operation + sl_AbsoluteFrequencySSB_r16 - ARFCN of the center RE of sidelink SSB of length 11 RBs +*/ +#define SL_FCCPARAMS_DESC(sl_fcc) { \ +{SL_CONFIG_STRING_SLOFFSETTOCARRIER,NULL,0,.i64ptr=&sl_fcc->sl_SCS_SpecificCarrierList_r16.list.array[0]->offsetToCarrier,.defint64val=0,TYPE_INT64,0}, \ +{SL_CONFIG_STRING_FCC_SUBCARRIERSPACING,NULL,0,.i64ptr=&sl_fcc->sl_SCS_SpecificCarrierList_r16.list.array[0]->subcarrierSpacing,.defint64val=NR_SubcarrierSpacing_kHz30,TYPE_INT64,0},\ +{SL_CONFIG_STRING_SLCARRIERBANDWIDTH,NULL,0,.i64ptr=&sl_fcc->sl_SCS_SpecificCarrierList_r16.list.array[0]->carrierBandwidth,.defint64val=106,TYPE_INT64,0}, \ +{SL_CONFIG_STRING_SLABSOLUEFREQUENCYPOINTA,NULL,0,.i64ptr=&sl_fcc->sl_AbsoluteFrequencyPointA_r16,.defint64val=792000,TYPE_INT64,0},\ +{SL_CONFIG_STRING_SLABSOLUTEFREQUENCYSSB,NULL,0,.i64ptr=sl_fcc->sl_AbsoluteFrequencySSB_r16,.defint64val=792372,TYPE_INT64,0}} + + +/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* Sidelink TDD ULDL Config parameters */ +/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* Please refer to 3GPP SPEC 38.331 (RRC Specification) for details about these parameters + TDD ul dl configuration used for sidelink operation set in Sidelink Preconfiguration IE +*/ +#define SL_TDDCONFIGPARAMS_DESC(sl_tdd_ul_dl_cfg) { \ +{SL_CONFIG_STRING_DLULTRANSMISSIONPERIODICITY,NULL,0,.i64ptr=&sl_tdd_ul_dl_cfg->pattern1.dl_UL_TransmissionPeriodicity,.defint64val=6,TYPE_INT64,0}, \ +{SL_CONFIG_STRING_NROFDOWNLINKSLOTS,NULL,0,.i64ptr=&sl_tdd_ul_dl_cfg->pattern1.nrofDownlinkSlots,.defint64val=7,TYPE_INT64,0},\ +{SL_CONFIG_STRING_NROFDOWNLINKSYMBOLS,NULL,0,.i64ptr=&sl_tdd_ul_dl_cfg->pattern1.nrofDownlinkSymbols,.defint64val=10,TYPE_INT64,0}, \ +{SL_CONFIG_STRING_NROFUPLINKSLOTS,NULL,0,.i64ptr=&sl_tdd_ul_dl_cfg->pattern1.nrofUplinkSlots,.defint64val=2,TYPE_INT64,0},\ +{SL_CONFIG_STRING_NROFUPLINKSYMBOLS,NULL,0,.i64ptr=&sl_tdd_ul_dl_cfg->pattern1.nrofUplinkSymbols,.defint64val=4,TYPE_INT64,0}} + + +/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* Sidelink Sync config parameters */ +/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* Please refer to 3GPP SPEC 38.331 (RRC Specification) for details about these parameters + These parameters indicate the repetition of Sidelink SSB + sl_NumSSB_WithinPeriod_r16 - number of SSB transmissions within 16 frames + sl_TimeOffsetSSB_r16 - timeoffset in slots for the first SL-SSB transmission within 16 frames + sl_TimeInterval_r16 - interval in slots between SL-SSB transmissions +*/ +#define SL_SYNCPARAMS_DESC(sl_syncconfig) { \ +{SL_CONFIG_STRING_SL_NUMSSB_WITHINPERIOD_0,NULL,0,.i64ptr=sl_syncconfig->sl_SSB_TimeAllocation1_r16->sl_NumSSB_WithinPeriod_r16,.defint64val=1,TYPE_INT64,0}, \ +{SL_CONFIG_STRING_SL_TIMEOFFSET_SSB_0,NULL,0,.i64ptr=sl_syncconfig->sl_SSB_TimeAllocation1_r16->sl_TimeOffsetSSB_r16,.defint64val=8,TYPE_INT64,0},\ +{SL_CONFIG_STRING_SL_TIMEINTERVAL_0,NULL,0,.i64ptr=sl_syncconfig->sl_SSB_TimeAllocation1_r16->sl_TimeInterval_r16,.defint64val=60,TYPE_INT64,0}} + + +/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* Sidelink BWP Config parameters */ +/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* Please refer to 3GPP SPEC 38.331 (RRC Specification) for details about these parameters + Sidelink BandWidthPart parameters + locationAndBandwidth - determines the start and size of Sidelink BWP + sl_LengthSymbols_r16 - number of symbols in a slot used for sidelink operation + sl_StartSymbol_r16 - start symbol for sidelink operation in a slot +*/ +#define SL_BWPPARAMS_DESC(sl_bwp) { \ +{SL_CONFIG_STRING_SL_BWP_START_AND_SIZE,NULL,0,.i64ptr=&sl_bwp->sl_BWP_Generic_r16->sl_BWP_r16->locationAndBandwidth,.defint64val=28875,TYPE_INT64,0}, \ +{SL_CONFIG_STRING_SL_BWP_NUM_SYMBOLS,NULL,0,.i64ptr=sl_bwp->sl_BWP_Generic_r16->sl_LengthSymbols_r16,.defint64val=7,TYPE_INT64,0}, \ +{SL_CONFIG_STRING_SL_BWP_START_SYMBOL,NULL,0,.i64ptr=sl_bwp->sl_BWP_Generic_r16->sl_StartSymbol_r16,.defint64val=0,TYPE_INT64,0}} + +/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* Sidelink Resource pool parameters */ +/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* Please refer to 3GPP SPEC 38.331 (RRC Specification) for details about these parameters + Sidelink TX/RX resource pool parameters + sl_TimeResourcePSCCH_r16 - number of symbols used for PSCCH + sl_SubchannelSize_r16 - number of PRBs in every subchannel in a resource pool + sl_StartRB_Subchannel_r16 - lowest RB of a lowest subchannel in a resource pool + sl_RB_Number_r16 - number of RBs in a resource pool +*/ +#define SL_RESPOOLPARAMS_DESC(sl_res_pool) { \ +{SL_CONFIG_STRING_RESPOOL_PSCCH_NUMSYM,NULL,0,.i64ptr=sl_res_pool->sl_PSCCH_Config_r16->choice.setup->sl_TimeResourcePSCCH_r16,.defint64val=1,TYPE_INT64,0}, \ +{SL_CONFIG_STRING_RESPOOL_PSCCH_NUMRBS,NULL,0,.i64ptr=sl_res_pool->sl_PSCCH_Config_r16->choice.setup->sl_FreqResourcePSCCH_r16,.defint64val=4,TYPE_INT64,0}, \ +{SL_CONFIG_STRING_RESPOOL_SUBCH_SIZE_IN_RBS,NULL,0,.i64ptr=sl_res_pool->sl_SubchannelSize_r16,.defint64val=0,TYPE_INT64,0},\ +{SL_CONFIG_STRING_RESPOOL_SUBCH_START_RB,NULL,0,.i64ptr=sl_res_pool->sl_StartRB_Subchannel_r16,.defint64val=0,TYPE_INT64,0},\ +{SL_CONFIG_STRING_RESPOOL_NUM_RBS,NULL,0,.i64ptr=sl_res_pool->sl_RB_Number_r16,.defint64val=106,TYPE_INT64,0},\ +{SL_CONFIG_STRING_RESPOOL_NUM_SUBCHS,NULL,0,.i64ptr=sl_res_pool->sl_NumSubchannel_r16,.defint64val=10,TYPE_INT64,0}} + + +#endif diff --git a/openair2/SDAP/nr_sdap/nr_sdap_entity.c b/openair2/SDAP/nr_sdap/nr_sdap_entity.c index 25254e0905..6fdd8eb54a 100644 --- a/openair2/SDAP/nr_sdap/nr_sdap_entity.c +++ b/openair2/SDAP/nr_sdap/nr_sdap_entity.c @@ -518,7 +518,7 @@ bool nr_sdap_delete_ue_entities(ue_id_t ue_id) } /* Handle scenario where ue_id matches the head of the list */ - while (entityPtr != NULL && entityPtr->ue_id == ue_id && upperBound < NGAP_MAX_DRBS_PER_UE) { + while (entityPtr != NULL && entityPtr->ue_id == ue_id && upperBound < MAX_DRBS_PER_UE) { sdap_info.sdap_entity_llist = entityPtr->next_entity; free(entityPtr); entityPtr = sdap_info.sdap_entity_llist; diff --git a/openair2/SDAP/nr_sdap/nr_sdap_entity.h b/openair2/SDAP/nr_sdap/nr_sdap_entity.h index b90da9d380..41a52c083b 100644 --- a/openair2/SDAP/nr_sdap/nr_sdap_entity.h +++ b/openair2/SDAP/nr_sdap/nr_sdap_entity.h @@ -44,7 +44,7 @@ #define SDAP_CTRL_PDU_MAP_DEF_DRB (0) #define SDAP_CTRL_PDU_MAP_RULE_DRB (1) #define SDAP_MAX_PDU (9000) -#define SDAP_MAX_NUM_OF_ENTITIES (NGAP_MAX_DRBS_PER_UE * MAX_MOBILES_PER_ENB) +#define SDAP_MAX_NUM_OF_ENTITIES (MAX_DRBS_PER_UE * MAX_MOBILES_PER_ENB) #define SDAP_MAX_UE_ID (65536) /* diff --git a/radio/COMMON/common_lib.h b/radio/COMMON/common_lib.h index 2e06744aaa..19fe3e468b 100644 --- a/radio/COMMON/common_lib.h +++ b/radio/COMMON/common_lib.h @@ -173,6 +173,10 @@ typedef struct { notifiedFIFO_t *resp; } udp_ctx_t; +typedef enum { + RU_GPIO_CONTROL_GENERIC, + RU_GPIO_CONTROL_INTERDIGITAL, +} gpio_control_t; /*! \brief RF frontend parameters set by application */ typedef struct { @@ -275,6 +279,8 @@ typedef struct { int rxfh_cores[4]; //! Core IDs for TX FH int txfh_cores[4]; + //! select the GPIO control method + gpio_control_t gpio_controller; } openair0_config_t; /*! \brief RF mapping */ diff --git a/radio/USRP/usrp_lib.cpp b/radio/USRP/usrp_lib.cpp index 3c5d1e2009..06b0c9bace 100644 --- a/radio/USRP/usrp_lib.cpp +++ b/radio/USRP/usrp_lib.cpp @@ -263,7 +263,42 @@ static int sync_to_gps(openair0_device *device) { #define ATR_MASK 0x7f //pins controlled by ATR #define ATR_RX 0x50 //data[4] and data[6] #define ATR_XX 0x20 //data[5] -#define MAN_MASK ATR_MASK^0xFFF //manually controlled pins +#define MAN_MASK ATR_MASK ^ 0xFFF // manually controlled pins + +static void trx_usrp_start_interdigital_gpio(openair0_device *device, usrp_state_t *s) +{ + AssertFatal(device->type == USRP_X400_DEV, + "interdigital frontend device for beam management can only be used together with an X400\n"); + + // s->gpio_bank="GPIO0"; + std::vector sxx{12, "DB0_RF0"}; + // set every pin on GPIO0 to be ocntrolled by DB1_RF0 + s->usrp->set_gpio_src(s->gpio_bank, sxx); + // set data direction register (DDR) to output + s->usrp->set_gpio_attr(s->gpio_bank, "DDR", 0xfff, 0xfff); + // set lower GPIO#1 to be controlled automatically by ATR (the rest bits are controlled manually) + s->usrp->set_gpio_attr(s->gpio_bank, "CTRL", (1 << 1), (1 << 1)); + // set GPIO1 (Tx/Rx1) to 1 for MHU1 for transmistting + s->usrp->set_gpio_attr(s->gpio_bank, "ATR_XX", (1 << 1), (1 << 1)); + // set GPIO4 (ID0) to 1 and GPIO2 (TX/RX2) &GPIO3 (ID1) to 0 + s->usrp->set_gpio_attr(s->gpio_bank, "OUT", (1 << 4), 0x1c); +} + +static void trx_usrp_start_generic_gpio(openair0_device *device, usrp_state_t *s) +{ + // setup GPIO for TDD, GPIO(4) = ATR_RX + // set data direction register (DDR) to output + s->usrp->set_gpio_attr(s->gpio_bank, "DDR", 0xfff, 0xfff); + // set bits to be controlled automatically by ATR + s->usrp->set_gpio_attr(s->gpio_bank, "CTRL", ATR_MASK, 0xfff); + // set bits to 1 when the radio is only receiving (ATR_RX) + s->usrp->set_gpio_attr(s->gpio_bank, "ATR_RX", ATR_RX, ATR_MASK); + // set bits 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(s->gpio_bank, "ATR_XX", ATR_XX, ATR_MASK); + // set all other pins to manual + s->usrp->set_gpio_attr(s->gpio_bank, "OUT", MAN_MASK, 0xfff); +} /*! \brief Called to start the USRP transceiver. Return 0 if OK, < 0 if error @param device pointer to the device structure specific to the RF hardware target @@ -280,21 +315,19 @@ static int trx_usrp_start(openair0_device *device) { s->gpio_bank = (char *) "GPIO0"; s->usrp->set_gpio_src(s->gpio_bank, sxx); } -#endif +#endif + + switch (device->openair0_cfg->gpio_controller) { + case RU_GPIO_CONTROL_GENERIC: + trx_usrp_start_generic_gpio(device, s); + break; + case RU_GPIO_CONTROL_INTERDIGITAL: + trx_usrp_start_interdigital_gpio(device, s); + break; + default: + AssertFatal(false, "illegal GPIO controller %d\n", device->openair0_cfg->gpio_controller); + } - // setup GPIO for TDD, GPIO(4) = ATR_RX - //set data direction register (DDR) to output - s->usrp->set_gpio_attr(s->gpio_bank, "DDR", 0xfff, 0xfff); - //set bits to be controlled automatically by ATR - s->usrp->set_gpio_attr(s->gpio_bank, "CTRL", ATR_MASK, 0xfff); - //set bits to 1 when the radio is only receiving (ATR_RX) - s->usrp->set_gpio_attr(s->gpio_bank, "ATR_RX", ATR_RX, ATR_MASK); - // set bits 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(s->gpio_bank, "ATR_XX", ATR_XX, ATR_MASK); - // set all other pins to manual - s->usrp->set_gpio_attr(s->gpio_bank, "OUT", MAN_MASK, 0xfff); - s->wait_for_first_pps = 1; s->rx_count = 0; s->tx_count = 0; diff --git a/targets/PROJECTS/NR-SIDELINK/CONF/sidelink_preconfig_1rxpool.conf b/targets/PROJECTS/NR-SIDELINK/CONF/sidelink_preconfig_1rxpool.conf new file mode 100644 index 0000000000..f6a934e0a3 --- /dev/null +++ b/targets/PROJECTS/NR-SIDELINK/CONF/sidelink_preconfig_1rxpool.conf @@ -0,0 +1,69 @@ + +#Configure Sidelink Preconfiguration params here. +SIDELINK_PRECONFIGURATION = ( + { + # TDD ULDL CONFIG used for sidelink + sl_dl_UL_TransmissionPeriodicity = 6; + sl_nrofDownlinkSlots = 7; + sl_nrofDownlinkSymbols = 10; + sl_nrofUplinkSlots = 2; + sl_nrofUplinkSymbols = 4; + + sl_FrequencyCommonConfig = ( + { + sl_offstToCarrier = 0; + sl_subcarrierSpacing = 1;//0-15Khz, 1-30Khz + sl_carrierBandwidth = 106;//numPRBs +#NR bands for Sidelink n47, n38. N47 - 5855Mhz - 5925Mhz +#SL SSB chosen to be located from RB10 to RB21. points to the middle of the SSB block. +#SSB location should be within Sidelink BWP +#792000 + 10*12*2 + 66*2. channel raster is 15Khz for band47 + sl_absoluteFrequencySSB = 792372; + sl_absoluteFrequencyPointA = 792000; + } + ); + + sl_BWP = ( + { +#RB start 0, RB size = 106. occupies complete Bw. + sl_locationAndBandwidth = 28875; +#Num Symbols used for Sidelink in an uplink slot +#Value can be between 0 to 7 indicating 7 to 14 symbols. + sl_LengthSymbols = 4; +#Sidelink Starting symbol in a slot +#Value can be between symbols 0 to 7 + sl_StartSymbol = 0; + } + ); + + sl_syncCfg = ( + { +#NUM SL-SSB within 16 frames + sl_NumSSB_WithinPeriod_0 = 2; +#Slot Offset for the first txn in the 16 frame period + sl_TimeOffsetSSB_0 = 8; +#interval in slots for repetition of SL-SSB + sl_TimeInterval_0 = 120; + } + ); + + sl_RxResPools = ( + { +#Number of symbols which carry PSCCH. +#Possible values 0 means 2 symbols, 1 - means 3 symbols. + sl_TimeResourcePSCCH = 1; +#Number of RBS which carry PSCCH +#Possible values {n10,n12,n15,n20,n25} + sl_FreqResourcePSCCH = 4; //25RBs +#Size of subchannel in RBs +#Possible values - {n10,n12,n15,n20,n25,n50,n75,n100} + sl_SubchannelSize = 5;//50RBs +#start in RB of the lowest subchannel in a rpool + sl_StartRB_Subchannel = 0; +#number of PRBs in a rpool + sl_RB_Number = 50; + sl_NumSubchannel = 1; + } + ); + } +); diff --git a/targets/PROJECTS/NR-SIDELINK/CONF/sidelink_preconfig_1rxpool_1txpool.conf b/targets/PROJECTS/NR-SIDELINK/CONF/sidelink_preconfig_1rxpool_1txpool.conf new file mode 100644 index 0000000000..b65b785393 --- /dev/null +++ b/targets/PROJECTS/NR-SIDELINK/CONF/sidelink_preconfig_1rxpool_1txpool.conf @@ -0,0 +1,89 @@ + +#Configure Sidelink Preconfiguration params here. +SIDELINK_PRECONFIGURATION = ( + { + # TDD ULDL CONFIG used for sidelink + sl_dl_UL_TransmissionPeriodicity = 6; + sl_nrofDownlinkSlots = 7; + sl_nrofDownlinkSymbols = 10; + sl_nrofUplinkSlots = 2; + sl_nrofUplinkSymbols = 4; + + sl_FrequencyCommonConfig = ( + { + sl_offstToCarrier = 0; + sl_subcarrierSpacing = 1;//0-15Khz, 1-30Khz + sl_carrierBandwidth = 106;//numPRBs +#NR bands for Sidelink n47, n38. N47 - 5855Mhz - 5925Mhz +#SL SSB chosen to be located from RB10 to RB21. points to the middle of the SSB block. +#SSB location should be within Sidelink BWP +#792000 + 10*12*2 + 66*2. channel raster is 15Khz for band47 + sl_absoluteFrequencySSB = 792372; + sl_absoluteFrequencyPointA = 792000; + } + ); + + sl_BWP = ( + { +#RB start 0, RB size = 106. occupies complete Bw. + sl_locationAndBandwidth = 28875; +#Num Symbols used for Sidelink in an uplink slot +#Value can be between symbols 7 to 14 + sl_LengthSymbols = 4; +#Sidelink Starting symbol in a slot +#Value can be between symbols 0 to 7 + sl_StartSymbol = 0; + } + ); + + sl_syncCfg = ( + { +#NUM SL-SSB within 16 frames + sl_NumSSB_WithinPeriod_0 = 2; +#Slot Offset for the first txn in the 16 frame period + sl_TimeOffsetSSB_0 = 8; +#interval in slots for repetition of SL-SSB + sl_TimeInterval_0 = 120; + } + ); + + sl_RxResPools = ( + { +#Number of symbols which carry PSCCH. +#Possible values 0 means 2 symbols, 1 - means 3 symbols. + sl_TimeResourcePSCCH = 1; +#Number of RBS which carry PSCCH +#Possible values {n10,n12,n15,n20,n25} + sl_FreqResourcePSCCH = 4; //25RBs +#Size of subchannel in RBs +#Possible values - {n10,n12,n15,n20,n25,n50,n75,n100} + sl_SubchannelSize = 5;//10RBs +#start in RB of the lowest subchannel in a rpool + sl_StartRB_Subchannel = 0; +#number of PRBs in a rpool + sl_RB_Number = 50; + sl_NumSubchannel = 1; + } + ); + + sl_TxResPools = ( + { +#Number of symbols which carry PSCCH. +#Possible values 0 means 2 symbols, 1 - means 3 symbols. + sl_TimeResourcePSCCH = 1; +#Number of RBS which carry PSCCH +#Possible values {n10,n12,n15,n20,n25} + sl_FreqResourcePSCCH = 4; //25RBs +#Size of subchannel in RBs +#Possible values - {n10,n12,n15,n20,n25,n50,n75,n100} + sl_SubchannelSize = 5;//50RBs +#start in RB of the lowest subchannel in a rpool + sl_StartRB_Subchannel = 0; +#number of PRBs in a rpool + sl_RB_Number = 50; + sl_NumSubchannel = 1; + } + ); + + } +); diff --git a/targets/PROJECTS/NR-SIDELINK/CONF/sidelink_preconfig_1txpool.conf b/targets/PROJECTS/NR-SIDELINK/CONF/sidelink_preconfig_1txpool.conf new file mode 100644 index 0000000000..46a2773f5a --- /dev/null +++ b/targets/PROJECTS/NR-SIDELINK/CONF/sidelink_preconfig_1txpool.conf @@ -0,0 +1,69 @@ + +#Configure Sidelink Preconfiguration params here. +SIDELINK_PRECONFIGURATION = ( + { + # TDD ULDL CONFIG used for sidelink + sl_dl_UL_TransmissionPeriodicity = 6; + sl_nrofDownlinkSlots = 7; + sl_nrofDownlinkSymbols = 10; + sl_nrofUplinkSlots = 2; + sl_nrofUplinkSymbols = 4; + + sl_FrequencyCommonConfig = ( + { + sl_offstToCarrier = 0; + sl_subcarrierSpacing = 1;//0-15Khz, 1-30Khz + sl_carrierBandwidth = 106;//numPRBs +#NR bands for Sidelink n47, n38. N47 - 5855Mhz - 5925Mhz +#SL SSB chosen to be located from RB10 to RB21. points to the middle of the SSB block. +#SSB location should be within Sidelink BWP +#792000 + 10*12*2 + 66*2. channel raster is 15Khz for band47 + sl_absoluteFrequencySSB = 792372; + sl_absoluteFrequencyPointA = 792000; + } + ); + + sl_BWP = ( + { +#RB start 0, RB size = 106. occupies complete Bw. + sl_locationAndBandwidth = 28875; +#Num Symbols used for Sidelink in an uplink slot +#Value can be between 0 to 7 indicating 7 to 14 symbols. + sl_LengthSymbols = 4; +#Sidelink Starting symbol in a slot +#Value can be between symbols 0 to 7 + sl_StartSymbol = 0; + } + ); + + sl_syncCfg = ( + { +#NUM SL-SSB within 16 frames + sl_NumSSB_WithinPeriod_0 = 2; +#Slot Offset for the first txn in the 16 frame period + sl_TimeOffsetSSB_0 = 8; +#interval in slots for repetition of SL-SSB + sl_TimeInterval_0 = 120; + } + ); + + sl_TxResPools = ( + { +#Number of symbols which carry PSCCH. +#Possible values 0 means 2 symbols, 1 - means 3 symbols. + sl_TimeResourcePSCCH = 1; +#Number of RBS which carry PSCCH +#Possible values {n10,n12,n15,n20,n25} + sl_FreqResourcePSCCH = 4; //25RBs +#Size of subchannel in RBs +#Possible values - {n10,n12,n15,n20,n25,n50,n75,n100} + sl_SubchannelSize = 5;//50RBs +#start in RB of the lowest subchannel in a rpool + sl_StartRB_Subchannel = 0; +#number of PRBs in a rpool + sl_RB_Number = 50; + sl_NumSubchannel = 1; + } + ); + } +);