diff --git a/CHANGELOG.md b/CHANGELOG.md index 5df218b36d..a9b355d079 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,51 @@ # RELEASE NOTES: # +## [v2.3.0](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tags/v2.3.0) -> July 2025. ## + +General new features and improvements (both RAN and UE): +- Preliminary support for RedCap UEs +- Support for NTN LEO scenarios including SIB19 and channel emulation (see + doc/RUNMODEM.md) +- VRTSIM: new shared memory realtime radio (see develop/radio/vrtsim/README.md) +- Support for TDD pattern 2 +- Support for long PRACH +- Support for SIB2 +- Add unit tests using ctest (see doc/UnitTests.md) + +Stability and bug fixes: +- Improve various procedures (e.g., RRC reestablishment, RRC Reject, ...) +- Add improvements for ImScope +- Bugfixes in the entire stack (e.g., #803, #805, #810, #812, #818, #852, #878, + #884, #890, #895, #901, #907, #932, #939 ...) +- Documentation updates +- And many other small fixes, like memory leaks, crashes, ... + +RAN changes (gNB/CU/CU-CP/CU-UP/DU/DU-high/DU-low): +- Stability and performance improvements when running with 4-layer DL MIMO +- Stability and performance improvements when running with 2-layer UL MIMO +- Interoperability testing with Metanoia Jura and Foxconn RUs +- Support of O-RAN 7.2 M-plane (Start-up procedure including configuration + management, see also doc/ORAN_FHI7.2_Tutorial.md) +- Upgrade OSC FHI (xran) from E to F release +- Refactoring of LDPC interface and performance improvements +- Support for nFAPI in all scenarios for FR1 (see doc/nfapi.md) +- Support at least 32 UEs concurrently +- Improve robustness when running in split modes (F1, E1) +- Add basic support for beam management in FR2 +- Add support for O1 on DU (see also https://gitlab.eurecom.fr/oai/o1-adapter) +- E2 agent: Support for multiple E2SM-RC report service styles + +nrUE changes: +- Refactoring of threading towards better code and performance +- Add or rework various procedures (e.g., RA with C-RNTI, Going to Idle, RA, ...) +- Refactor and extend NAS implementation (e.g., Service Request, Registration + Request, Service Acept, Service Reject, ...) +- Support for continuous frequency offset compensation +- Reduce minimum RX-to-TX time to 3 + +Regression: +- Multiple BWPs do not work reliably on gNB; use tag 2025.w17 + ## [v2.2.0](https://gitlab.eurecom.fr/oai/openairinterface5g/-/tags/v2.2.0) -> November 2024. ## General 5G improvements (both gNB and UE): diff --git a/ci-scripts/Jenkinsfile-GitLab-Container b/ci-scripts/Jenkinsfile-GitLab-Container index 3301c133ec..a2bb8112fc 100644 --- a/ci-scripts/Jenkinsfile-GitLab-Container +++ b/ci-scripts/Jenkinsfile-GitLab-Container @@ -271,14 +271,15 @@ pipeline { when { expression {doBuild && "PUSH".equals(env.gitlabActionType)} } steps { script { - triggerSlaveJob ('RAN-DockerHub-Push', 'DockerHub-Push') + catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') { + triggerSlaveJob ('RAN-DockerHub-Push', 'DockerHub-Push') + } } } post { failure { script { echo "Push to Docker-Hub KO" - currentBuild.result = 'FAILURE' failingStages += '\n * RAN-DockerHub-Push' } } diff --git a/ci-scripts/Jenkinsfile-push-registry b/ci-scripts/Jenkinsfile-push-registry index ccd91e28ff..60b8777ba9 100644 --- a/ci-scripts/Jenkinsfile-push-registry +++ b/ci-scripts/Jenkinsfile-push-registry @@ -84,9 +84,20 @@ pipeline { sh "docker login -u ${DH_Username} -p ${DH_Password} > /dev/null 2>&1" sh "docker login -u oaicicd -p oaicicd ${OAI_Registry} > /dev/null 2>&1" listOfImages.eachWithIndex { item, iindex -> - sh "docker rmi ${DH_Account}/${item}:${WEEK_TAG} ${DH_Account}/${item}:develop || true" - sh "docker buildx imagetools create --tag ${DH_Account}/${item}:${WEEK_TAG} ${OAI_Registry}/${item}:armv8_develop-${WEEK_SHA} ${OAI_Registry}/${item}:develop-${WEEK_SHA}" - sh "docker buildx imagetools create --tag ${DH_Account}/${item}:develop ${OAI_Registry}/${item}:armv8_develop-${WEEK_SHA} ${OAI_Registry}/${item}:develop-${WEEK_SHA}" + if (["oai-gnb", "oai-nr-ue", "oai-nr-cuup"].contains(item)) { + // For images built on AMD64 and ARMv8 Jetson + echo "Pushing image '${item}' for both AMD64 and ARM64 architectures with tags: ${WEEK_TAG} and develop" + sh "docker rmi ${DH_Account}/${item}:${WEEK_TAG} ${DH_Account}/${item}:develop || true" + sh "docker buildx imagetools create --tag ${DH_Account}/${item}:${WEEK_TAG} ${OAI_Registry}/${item}:armv8_develop-${WEEK_SHA} ${OAI_Registry}/${item}:develop-${WEEK_SHA}" + sh "docker buildx imagetools create --tag ${DH_Account}/${item}:develop ${OAI_Registry}/${item}:armv8_develop-${WEEK_SHA} ${OAI_Registry}/${item}:develop-${WEEK_SHA}" + } else { + sh "docker pull --quiet ${OAI_Registry}/${item}:develop-${WEEK_SHA}" + sh "docker image tag ${OAI_Registry}/${item}:develop-${WEEK_SHA} ${DH_Account}/${item}:develop" + sh "docker image tag ${OAI_Registry}/${item}:develop-${WEEK_SHA} ${DH_Account}/${item}:${WEEK_TAG}" + sh "docker push --quiet ${DH_Account}/${item}:develop" + sh "docker push --quiet ${DH_Account}/${item}:${WEEK_TAG}" + } + sh "docker rmi ${DH_Account}/${item}:${WEEK_TAG} ${DH_Account}/${item}:develop ${OAI_Registry}/${item}:develop-${WEEK_SHA} || true" } // Proxy is not following the same pattern. sh "docker image tag proxy:develop ${DH_Account}/proxy:develop" diff --git a/ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf b/ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf index e4d9127284..23475e3838 100644 --- a/ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf +++ b/ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf @@ -135,11 +135,11 @@ gNBs = # 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; + dl_UL_TransmissionPeriodicity = 5; + nrofDownlinkSlots = 3; + nrofDownlinkSymbols = 10; + nrofUplinkSlots = 1; + nrofUplinkSymbols = 2; ssPBCH_BlockPower = -25; } diff --git a/ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn.conf b/ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn.conf index a7663ae811..b3884a3d31 100644 --- a/ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn.conf +++ b/ci-scripts/conf_files/gnb.sa.band254.u0.25prb.rfsim.ntn.conf @@ -16,7 +16,7 @@ gNBs = ////////// Physical parameters: - do_SINR = 1; + CSI_report_type = "ssb_sinr"; min_rxtxtime = 6; disable_harq = 1; cu_sibs = [2]; diff --git a/ci-scripts/conf_files/gnb.sa.band77.273prb.fhi72.4x4.2L-metanoia.conf b/ci-scripts/conf_files/gnb.sa.band77.273prb.fhi72.4x4.2L-metanoia.conf index 4be45f6e19..41e9974caf 100644 --- a/ci-scripts/conf_files/gnb.sa.band77.273prb.fhi72.4x4.2L-metanoia.conf +++ b/ci-scripts/conf_files/gnb.sa.band77.273prb.fhi72.4x4.2L-metanoia.conf @@ -106,8 +106,7 @@ gNBs = pucchGroupHopping = 0; hoppingId = 40; p0_nominal = -90; -# ssb_PositionsInBurs_BitmapPR -# 1=short, 2=medium, 3=long + ssb_PositionsInBurst_Bitmap = 1; # ssb_periodicityServingCell # 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 diff --git a/ci-scripts/conf_files/gnb.sa.band77.51prb.usrpb200.n2-ho.conf b/ci-scripts/conf_files/gnb.sa.band77.51prb.usrpb200.n2-ho.conf new file mode 100644 index 0000000000..dc24284c18 --- /dev/null +++ b/ci-scripts/conf_files/gnb.sa.band77.51prb.usrpb200.n2-ho.conf @@ -0,0 +1,237 @@ +Active_gNBs = ( "gNB-OAI"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + gNB_name = "gNB-OAI"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ({ mcc = 001; mnc = 03; mnc_length = 2; snssaiList = ({ sst = 1, sd = 0xffffff }) }); + + // Include neighbour configuration for N2 handover + @include "neighbour-config-ho.conf" + + nr_cellid = 12345678L; + + ////////// Physical parameters: + + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3610.56 MHz + absoluteFrequencySSB = 679104; + dl_frequencyBand = 77; + # this is 3599.94 MHz + dl_absoluteFrequencyPointA = 678388; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 51; + #initialDownlinkBWP + #genericParameters + # this is RBstart=27,L=48 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 13750; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 77; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 51; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 13750; +# 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; +#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; +#one (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_PositionsInBurst_Bitmap = 1; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 1; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = -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.6.109"; }); + + + NETWORK_INTERFACES : + { + GNB_IPV4_ADDRESS_FOR_NG_AMF = "172.21.19.98"; + GNB_IPV4_ADDRESS_FOR_NGU = "172.21.19.98"; + 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; +} +); + +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 = 0; + att_rx = 0; + bands = [77]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 114; + eNB_instances = [0]; + clock_src = "external"; + time_src = "external"; +} +); + + +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 ="debug"; + f1ap_log_level ="debug"; +}; + diff --git a/ci-scripts/conf_files/nrue.band78.106prb.l2sim.conf b/ci-scripts/conf_files/nrue.band78.106prb.l2sim.conf index 45d192dc04..0dfd31a789 100644 --- a/ci-scripts/conf_files/nrue.band78.106prb.l2sim.conf +++ b/ci-scripts/conf_files/nrue.band78.106prb.l2sim.conf @@ -14,7 +14,6 @@ key = "fec86ba6eb707ed08905757b1bb44b8f"; opc= "C42449363BBAD02B66D16BC975D77CC1"; dnn= "oai"; nssai_sst=1; -nssai_sd=16777215; } MACRLCs = ( diff --git a/ci-scripts/conf_files/ue.sa.conf b/ci-scripts/conf_files/ue.sa.conf index 9101c7e8e9..dc744fb732 100644 --- a/ci-scripts/conf_files/ue.sa.conf +++ b/ci-scripts/conf_files/ue.sa.conf @@ -4,7 +4,6 @@ uicc0 = { opc= "c42449363bbad02b66d16bc975d77cc1"; dnn= "oai"; nssai_sst=1; - nssai_sd=66051; } thread-pool = "-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1" diff --git a/ci-scripts/xml_files/container_4g_l2sim_tdd.xml b/ci-scripts/xml_files/container_4g_l2sim_tdd.xml index eabece50cd..d9ac14038b 100644 --- a/ci-scripts/xml_files/container_4g_l2sim_tdd.xml +++ b/ci-scripts/xml_files/container_4g_l2sim_tdd.xml @@ -44,7 +44,7 @@ Pull_Local_Registry Pull Images from Local Registry - obelix + localhost oai-enb oai-lte-ue @@ -88,16 +88,16 @@ Attach_UE Attach OAI UE l2sim4g_ue - obelix + localhost Ping Ping trf-gen from LTE-UE 1 l2sim4g_ue - obelix + localhost l2sim4g_ext_dn - obelix + localhost -c 20 0 @@ -106,9 +106,9 @@ Ping Ping LTE-UE 1 from trf-gen l2sim4g_ext_dn - obelix + localhost l2sim4g_ue - obelix + localhost -c 20 0 @@ -117,9 +117,9 @@ Iperf Iperf UDP Downlink l2sim4g_ue - obelix + localhost l2sim4g_ext_dn - obelix + localhost -u -t 30 -b 1M -R 25 80 @@ -129,9 +129,9 @@ Iperf Iperf UDP Uplink l2sim4g_ue - obelix + localhost l2sim4g_ext_dn - obelix + localhost -u -t 30 -b 3M 25 80 @@ -149,7 +149,7 @@ Clean_Test_Server_Images true Clean Test Images on Test Server - obelix + localhost oai-enb oai-lte-ue diff --git a/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz.xml b/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz.xml index 4b93c10fcd..562856b00c 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz.xml @@ -103,16 +103,16 @@ Attach_UE Attach OAI UE (Wait for IP) rfsim4g_ue - acamas + localhost Ping Ping Traffic-Gen from LTE-UE rfsim4g_ue - acamas + localhost rfsim4g_ext_dn - acamas + localhost -c 20 5 @@ -121,9 +121,9 @@ Ping Ping LTE-UE from Traffic-Gen rfsim4g_ext_dn - acamas + localhost rfsim4g_ue - acamas + localhost -c 20 5 @@ -136,8 +136,8 @@ -u -t 30 -b 2M -R 25 80 - acamas - acamas + localhost + localhost @@ -148,8 +148,8 @@ -u -t 30 -b 1M 25 80 - acamas - acamas + localhost + localhost diff --git a/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz_noS1.xml b/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz_noS1.xml index 968e30071a..1773d5d439 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz_noS1.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_fdd_05MHz_noS1.xml @@ -83,9 +83,9 @@ Ping Ping Traffic-Gen from LTE-UE rfsim4g_ue - acamas + localhost rfsim4g_enb_nos1 - acamas + localhost -c 20 5 @@ -94,9 +94,9 @@ Ping Ping LTE-UE from eNB rfsim4g_enb_nos1 - acamas + localhost rfsim4g_ue - acamas + localhost -c 20 5 @@ -105,9 +105,9 @@ Iperf Iperf UDP DL rfsim4g_ue - acamas + localhost rfsim4g_enb_nos1 - acamas + localhost -u -t 30 -b 2M -R 25 80 @@ -117,9 +117,9 @@ Iperf Iperf UDP UL rfsim4g_ue - acamas + localhost rfsim4g_enb_nos1 - acamas + localhost -u -t 30 -b 1M 25 80 diff --git a/ci-scripts/xml_files/container_4g_rfsim_fdd_10MHz.xml b/ci-scripts/xml_files/container_4g_rfsim_fdd_10MHz.xml index 076ee6995b..7861d8f332 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_fdd_10MHz.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_fdd_10MHz.xml @@ -103,16 +103,16 @@ Attach_UE Attach OAI UE (Wait for IP) rfsim4g_ue - acamas + localhost Ping Ping Traffic-Gen from LTE-UE rfsim4g_ue - acamas + localhost rfsim4g_ext_dn - acamas + localhost -c 20 5 @@ -121,9 +121,9 @@ Ping Ping LTE-UE from Traffic-Gen rfsim4g_ext_dn - acamas + localhost rfsim4g_ue - acamas + localhost -c 20 5 @@ -132,9 +132,9 @@ Iperf Iperf UDP DL rfsim4g_ue - acamas + localhost rfsim4g_ext_dn - acamas + localhost -u -t 30 -b 2M -R 25 80 @@ -144,9 +144,9 @@ Iperf Iperf UDP UL rfsim4g_ue - acamas + localhost rfsim4g_ext_dn - acamas + localhost -u -t 30 -b 1M 25 80 diff --git a/ci-scripts/xml_files/container_4g_rfsim_fdd_20MHz.xml b/ci-scripts/xml_files/container_4g_rfsim_fdd_20MHz.xml index 2e049e4efe..9199f276e7 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_fdd_20MHz.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_fdd_20MHz.xml @@ -103,16 +103,16 @@ Attach_UE Attach OAI UE (Wait for IP) rfsim4g_ue - acamas + localhost Ping Ping Traffic-Gen from LTE-UE rfsim4g_ue - acamas + localhost rfsim4g_ext_dn - acamas + localhost -c 20 5 @@ -121,9 +121,9 @@ Ping Ping LTE-UE from Traffic-Gen rfsim4g_ext_dn - acamas + localhost rfsim4g_ue - acamas + localhost -c 20 5 @@ -132,9 +132,9 @@ Iperf Iperf UDP DL rfsim4g_ue - acamas + localhost rfsim4g_ext_dn - acamas + localhost -u -t 30 -b 2M -R 25 80 @@ -144,9 +144,9 @@ Iperf Iperf UDP UL rfsim4g_ue - acamas + localhost rfsim4g_ext_dn - acamas + localhost -u -t 30 -b 1M 25 80 diff --git a/ci-scripts/xml_files/container_4g_rfsim_fembms.xml b/ci-scripts/xml_files/container_4g_rfsim_fembms.xml index 7ab434c804..73c01f2b32 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_fembms.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_fembms.xml @@ -80,9 +80,9 @@ Iperf2_Unidir Iperf2 UDP DL rfsim4g_ue_fembms - acamas + localhost rfsim4g_enb_fembms - acamas + localhost -u -t 30 -b 2M 25 80 diff --git a/ci-scripts/xml_files/container_4g_rfsim_mbms.xml b/ci-scripts/xml_files/container_4g_rfsim_mbms.xml index e6a4cde19a..ea00caa09e 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_mbms.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_mbms.xml @@ -80,9 +80,9 @@ Iperf Iperf UDP DL rfsim4g_ue - acamas + localhost rfsim4g_enb_nos1 - acamas + localhost -u -t 30 -b 2M -R 25 80 diff --git a/ci-scripts/xml_files/container_4g_rfsim_tdd_05MHz.xml b/ci-scripts/xml_files/container_4g_rfsim_tdd_05MHz.xml index 2e22577879..d3129e0c68 100644 --- a/ci-scripts/xml_files/container_4g_rfsim_tdd_05MHz.xml +++ b/ci-scripts/xml_files/container_4g_rfsim_tdd_05MHz.xml @@ -103,9 +103,9 @@ Ping Ping Traffic-Gen from LTE-UE rfsim4g_ue - acamas + localhost rfsim4g_ext_dn - acamas + localhost -c 20 5 @@ -114,9 +114,9 @@ Ping Ping LTE-UE from Traffic-Gen rfsim4g_ext_dn - acamas + localhost rfsim4g_ue - acamas + localhost -c 20 5 @@ -125,9 +125,9 @@ Iperf Iperf UDP DL rfsim4g_ue - acamas + localhost rfsim4g_ext_dn - acamas + localhost -u -t 30 -b 2M -R 25 80 @@ -137,9 +137,9 @@ Iperf Iperf UDP UL rfsim4g_ue - acamas + localhost rfsim4g_ext_dn - acamas + localhost -u -t 30 -b 1M 25 80 diff --git a/ci-scripts/xml_files/container_5g_e1_rfsim.xml b/ci-scripts/xml_files/container_5g_e1_rfsim.xml index d27091ac63..54b34e0cff 100644 --- a/ci-scripts/xml_files/container_5g_e1_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_e1_rfsim.xml @@ -76,16 +76,16 @@ Attach_UE Attach OAI UE (Wait for IP) rfsim5g_ue rfsim5g_ue2 rfsim5g_ue3 - acamas acamas acamas + localhost localhost localhost Ping Ping ext-dn from all NR-UEs rfsim5g_ue rfsim5g_ue2 rfsim5g_ue3 - acamas acamas acamas + localhost localhost localhost rfsim5g_5gc_fixed_ip - acamas + localhost -c 20 -i0.25 5 diff --git a/ci-scripts/xml_files/container_5g_f1_rfsim.xml b/ci-scripts/xml_files/container_5g_f1_rfsim.xml index 50e794e4cb..d8dc580a04 100644 --- a/ci-scripts/xml_files/container_5g_f1_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_f1_rfsim.xml @@ -107,7 +107,7 @@ Attach_UE Attach OAI UE (Wait for IP) rfsim5g_ue - acamas + localhost @@ -122,9 +122,9 @@ Ping Ping ext-dn from all NR-UEs rfsim5g_ue - acamas + localhost rfsim5g_ext_dn - acamas + localhost -c 20 -i0.25 5 @@ -132,7 +132,7 @@ Custom_Command Simulate a DL radio channel with noise (3 dB) - acamas + localhost echo channelmod modify 0 noise_power_dB 3 | ncat --send-only 192.168.71.181 8091 @@ -141,9 +141,9 @@ Iperf (DL/3Mbps/UDP)(30 sec) -u -b 3M -t 20 -R rfsim5g_ue - acamas + localhost rfsim5g_ext_dn - acamas + localhost 5 90 @@ -153,9 +153,9 @@ Iperf (UL/3Mbps/UDP)(30 sec) -u -b 3M -t 20 rfsim5g_ue - acamas + localhost rfsim5g_ext_dn - acamas + localhost 5 90 @@ -163,7 +163,7 @@ Custom_Command Trigger Reestablishment - acamas + localhost echo ci force_reestab | ncat 192.168.71.171 9090 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment' @@ -171,9 +171,9 @@ Ping Ping ext-dn from NR-UE rfsim5g_ue - acamas + localhost rfsim5g_ext_dn - acamas + localhost -c 20 -i0.5 -w25 80 @@ -181,56 +181,56 @@ Custom_Command Verify Reestablishment - acamas + localhost echo ci get_reestab_count | ncat 192.168.71.150 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1' Custom_Command Simulate a disruption of DL radio channel (ploss 55) - acamas + localhost echo channelmod modify 0 ploss 55 | ncat 192.168.71.181 8091 Custom_Command Get UE sync state (UE ID 0) - acamas + localhost echo ciUE sync_state 0 | ncat 192.168.71.181 8091 | grep -E UE_NOT_SYNC Custom_Command Restoration of the original DL channel conditions (ploss 20) - acamas + localhost echo channelmod modify 0 ploss 20 | ncat 192.168.71.181 8091 Custom_Command Get UE sync state (UE ID 0) - acamas + localhost echo ciUE sync_state 0 | ncat 192.168.71.181 8091 | grep -E UE_CONNECTED Custom_Command Trigger Handover - acamas + localhost echo ci trigger_f1_ho | ncat 192.168.71.150 9090 Custom_Command UE (1) connected to DU-PCI 0? - acamas + localhost echo ci fetch_du_by_ue_id 1 | ncat 192.168.71.150 9090 | grep "3584" Custom_Command UE (1) connected to DU-PCI 1? - acamas + localhost echo ci fetch_du_by_ue_id 1 | ncat 192.168.71.150 9090 | grep "3585" diff --git a/ci-scripts/xml_files/container_5g_fdd_rfsim.xml b/ci-scripts/xml_files/container_5g_fdd_rfsim.xml index 6ce1e37b90..3c4e30c97b 100644 --- a/ci-scripts/xml_files/container_5g_fdd_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_fdd_rfsim.xml @@ -70,16 +70,16 @@ Attach_UE Attach OAI UE (Wait for IP) rfsim5g_ue - acamas + localhost Ping Ping ext-dn from NR-UE rfsim5g_ue - acamas + localhost rfsim5g_ext_dn - acamas + localhost -c 20 -i 0.25 5 @@ -88,9 +88,9 @@ Ping Ping NR-UE from ext-dn rfsim5g_ext_dn - acamas + localhost rfsim5g_ue - acamas + localhost -c 20 -i 0.25 5 @@ -100,9 +100,9 @@ Iperf (DL/3Mbps/UDP)(30 sec) -u -b 3M -t 30 -R rfsim5g_ue - acamas + localhost rfsim5g_ext_dn - acamas + localhost 5 90 @@ -112,9 +112,9 @@ Iperf (UL/3Mbps/UDP)(30 sec) -u -b 3M -t 30 rfsim5g_ue - acamas + localhost rfsim5g_ext_dn - acamas + localhost 5 90 diff --git a/ci-scripts/xml_files/container_5g_rfsim.xml b/ci-scripts/xml_files/container_5g_rfsim.xml index d7fb38ef8f..e2566bfd25 100644 --- a/ci-scripts/xml_files/container_5g_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_rfsim.xml @@ -125,16 +125,16 @@ Attach_UE Attach OAI UE (Wait for IP) rfsim5g_ue rfsim5g_ue2 rfsim5g_ue3 rfsim5g_ue4 rfsim5g_ue5 rfsim5g_ue6 rfsim5g_ue7 rfsim5g_ue8 rfsim5g_ue9 rfsim5g_ue10 - acamas acamas acamas acamas acamas acamas acamas acamas acamas acamas + localhost localhost localhost localhost localhost localhost localhost localhost localhost localhost Ping Ping ext-dn from NR-UE rfsim5g_ue - acamas + localhost rfsim5g_ext_dn - acamas + localhost -c 20 -i 0.25 5 @@ -143,9 +143,9 @@ Ping Ping NR-UE from ext-dn rfsim5g_ext_dn - acamas + localhost rfsim5g_ue - acamas + localhost -c 20 -i 0.25 5 @@ -154,9 +154,9 @@ Ping Ping ext-dn from Second NR-UE rfsim5g_ue2 - acamas + localhost rfsim5g_ext_dn - acamas + localhost -c 20 -i 0.25 5 @@ -165,9 +165,9 @@ Ping Ping Second NR-UE from ext-dn rfsim5g_ext_dn - acamas + localhost rfsim5g_ue2 - acamas + localhost -c 20 -i 0.25 5 @@ -176,9 +176,9 @@ Ping Ping ext-dn from both UEs rfsim5g_ue rfsim5g_ue2 - acamas acamas + localhost localhost rfsim5g_ext_dn - acamas + localhost -c 20 -i 0.25 5 @@ -187,9 +187,9 @@ Ping Ping ext-dn from all UEs rfsim5g_ue rfsim5g_ue2 rfsim5g_ue3 rfsim5g_ue4 rfsim5g_ue5 rfsim5g_ue6 rfsim5g_ue7 rfsim5g_ue8 rfsim5g_ue9 rfsim5g_ue10 - acamas acamas acamas acamas acamas acamas acamas acamas acamas acamas + localhost localhost localhost localhost localhost localhost localhost localhost localhost localhost rfsim5g_ext_dn - acamas + localhost -c 20 -i 0.25 -s 1016 5 @@ -199,9 +199,9 @@ Iperf (DL/3Mbps/UDP)(30 sec) -u -b 3M -t 20 -R rfsim5g_ue - acamas + localhost rfsim5g_ext_dn - acamas + localhost 5 90 @@ -211,9 +211,9 @@ Iperf (UL/1Mbps/UDP)(30 sec) -u -b 1M -t 20 rfsim5g_ue - acamas + localhost rfsim5g_ext_dn - acamas + localhost 5 90 @@ -222,21 +222,21 @@ Attach_UE Attach OAI UE 1 and 2 rfsim5g_ue rfsim5g_ue2 - acamas acamas + localhost localhost Detach_UE Detach OAI UE 1 and 2 rfsim5g_ue rfsim5g_ue2 - acamas acamas + localhost localhost Detach_UE Detach OAI UE 3 to 10 rfsim5g_ue3 rfsim5g_ue4 rfsim5g_ue5 rfsim5g_ue6 rfsim5g_ue7 rfsim5g_ue8 rfsim5g_ue9 rfsim5g_ue10 - acamas acamas acamas acamas acamas acamas acamas acamas + localhost localhost localhost localhost localhost localhost localhost localhost diff --git a/ci-scripts/xml_files/container_5g_rfsim_24prb.xml b/ci-scripts/xml_files/container_5g_rfsim_24prb.xml index 7db37d8e63..849c91a7b0 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_24prb.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_24prb.xml @@ -88,7 +88,7 @@ Attach_UE Attach OAI UE (Wait for IP) rfsim5g_ue - acamas + localhost @@ -101,9 +101,9 @@ Ping Ping ext-dn from NR-UE rfsim5g_ue - acamas + localhost rfsim5g_ext_dn - acamas + localhost -c 20 -i0.5 80 @@ -112,9 +112,9 @@ Ping Ping NR-UE from ext-dn rfsim5g_ext_dn - acamas + localhost rfsim5g_ue - acamas + localhost -c 20 -i0.2 5 @@ -124,9 +124,9 @@ Iperf (DL/3Mbps/UDP)(30 sec) -u -b 3M -t 20 -R rfsim5g_ue - acamas + localhost rfsim5g_ext_dn - acamas + localhost 5 90 @@ -136,9 +136,9 @@ Iperf (UL/1Mbps/UDP)(30 sec) -u -b 1M -t 20 rfsim5g_ue - acamas + localhost rfsim5g_ext_dn - acamas + localhost 5 90 @@ -146,14 +146,14 @@ Custom_Command Force Msg3 C-RNTI RA - acamas + localhost echo ciUE force_crnti_ra | ncat 192.168.71.150 8091 Custom_Command Force RRC_IDLE (UE ID 0) - acamas + localhost echo ciUE force_RRC_IDLE | ncat 192.168.71.150 8091 diff --git a/ci-scripts/xml_files/container_5g_rfsim_2x2.xml b/ci-scripts/xml_files/container_5g_rfsim_2x2.xml index 75924e1ca2..ed0e11807c 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_2x2.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_2x2.xml @@ -70,16 +70,16 @@ Attach_UE Attach OAI UE (Wait for IP) rfsim5g_ue - acamas + localhost Ping Ping ext-dn from NR-UE rfsim5g_ue - acamas + localhost rfsim5g_ext_dn - acamas + localhost -c 20 -i 0.25 5 @@ -88,9 +88,9 @@ Ping Ping NR-UE from ext-dn rfsim5g_ext_dn - acamas + localhost rfsim5g_ue - acamas + localhost -c 20 -i 0.25 5 @@ -100,9 +100,9 @@ Iperf (DL/10Mbps/UDP)(30 sec) -u -b 10M -t 20 -R rfsim5g_ue - acamas + localhost rfsim5g_ext_dn - acamas + localhost 5 90 @@ -112,9 +112,9 @@ Iperf (UL/3Mbps/UDP)(30 sec) -u -b 3M -t 20 rfsim5g_ue - acamas + localhost rfsim5g_ext_dn - acamas + localhost 5 90 diff --git a/ci-scripts/xml_files/container_5g_rfsim_fdd_phytest.xml b/ci-scripts/xml_files/container_5g_rfsim_fdd_phytest.xml index b376df99f4..4ff5dbedc8 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_fdd_phytest.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_fdd_phytest.xml @@ -49,7 +49,7 @@ Custom_Command Clean-Up any residual volume - acamas + localhost docker volume rm 5g_rfsimulator_fdd_phytest_rrc.config -f @@ -77,9 +77,9 @@ Ping Ping gNB from NR-UE rfsim5g_ue - acamas + localhost rfsim5g_gnb_nos1 - acamas + localhost -c20 -i0.2 0 @@ -88,9 +88,9 @@ Ping Ping NR-UE from gNB rfsim5g_gnb_nos1 - acamas + localhost rfsim5g_ue - acamas + localhost -c20 -i0.2 0 @@ -100,9 +100,9 @@ Iperf (DL/30kbps/UDP)(30 sec) -u -b 0.03M -t 20 -R -c 10.0.1.1 rfsim5g_ue - acamas + localhost rfsim5g_gnb_nos1 - acamas + localhost 5 90 @@ -112,9 +112,9 @@ Iperf (UL/30kbps/UDP)(30 sec) -u -b 0.03M -t 20 -c 10.0.1.1 rfsim5g_ue - acamas + localhost rfsim5g_gnb_nos1 - acamas + localhost 5 90 diff --git a/ci-scripts/xml_files/container_5g_rfsim_fr2_32prb.xml b/ci-scripts/xml_files/container_5g_rfsim_fr2_32prb.xml index 6a47da0ff9..37b90f2385 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_fr2_32prb.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_fr2_32prb.xml @@ -70,16 +70,16 @@ Attach_UE Attach OAI UE (Wait for IP) rfsim5g_ue - acamas + localhost Ping Ping ext-dn from NR-UE rfsim5g_ue - acamas + localhost rfsim5g_ext_dn - acamas + localhost -c 20 -i0.2 0 @@ -88,9 +88,9 @@ Ping Ping NR-UE from ext-dn rfsim5g_ext_dn - acamas + localhost rfsim5g_ue - acamas + localhost -c 20 -i0.2 0 diff --git a/ci-scripts/xml_files/container_5g_rfsim_multiue.xml b/ci-scripts/xml_files/container_5g_rfsim_multiue.xml index 79d85e154c..215f58c2a7 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_multiue.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_multiue.xml @@ -48,56 +48,52 @@ Pull_Local_Registry Pull Images from Local Registry - 0 + localhost oai-gnb-asan oai-nr-ue Create_Workspace Create new Workspace - 0 - 0 + localhost Deploy_Object Deploy OAI 5G CoreNetwork + localhost ci-scripts/yaml_files/5g_rfsimulator_multiue mysql oai-amf oai-smf oai-upf oai-ext-dn - 0 - 0 Deploy_Object Deploy OAI 5G gNB RF sim SA + localhost ci-scripts/yaml_files/5g_rfsimulator_multiue oai-gnb - 0 - 0 Deploy_Object Deploy OAI 5G NR-UE RF sim SA + localhost ci-scripts/yaml_files/5g_rfsimulator_multiue oai-nr-ue - 0 - 0 Attach_UE Attach OAI UE (Wait for IP) rfsim5g_multiue1 rfsim5g_multiue2 rfsim5g_multiue3 rfsim5g_multiue4 rfsim5g_multiue5 rfsim5g_multiue6 rfsim5g_multiue7 rfsim5g_multiue8 rfsim5g_multiue9 rfsim5g_multiue10 - acamas acamas acamas acamas acamas acamas acamas acamas acamas acamas + localhost localhost localhost localhost localhost localhost localhost localhost localhost localhost Ping Ping ext-dn from NR-UE rfsim5g_multiue1 - acamas + localhost rfsim5g_ext_dn - acamas + localhost -c 20 -i 0.25 5 @@ -106,9 +102,9 @@ Ping Ping NR-UE from ext-dn rfsim5g_ext_dn - acamas + localhost rfsim5g_multiue1 - acamas + localhost -c 20 -i 0.25 5 @@ -117,9 +113,9 @@ Ping Ping ext-dn from Second NR-UE rfsim5g_multiue2 - acamas + localhost rfsim5g_ext_dn - acamas + localhost -c 20 -i 0.25 5 @@ -128,9 +124,9 @@ Ping Ping Second NR-UE from ext-dn rfsim5g_ext_dn - acamas + localhost rfsim5g_multiue2 - acamas + localhost -c 20 -i 0.25 5 @@ -139,9 +135,9 @@ Ping Ping ext-dn from both UEs rfsim5g_multiue1 rfsim5g_multiue2 - acamas acamas + localhost localhost rfsim5g_ext_dn - acamas + localhost -c 20 -i 0.25 5 @@ -150,9 +146,9 @@ Ping Ping ext-dn from all UEs rfsim5g_multiue1 rfsim5g_multiue2 rfsim5g_multiue3 rfsim5g_multiue4 rfsim5g_multiue5 rfsim5g_multiue6 rfsim5g_multiue7 rfsim5g_multiue8 rfsim5g_multiue9 rfsim5g_multiue10 - acamas acamas acamas acamas acamas acamas acamas acamas acamas acamas + localhost localhost localhost localhost localhost localhost localhost localhost localhost localhost rfsim5g_ext_dn - acamas + localhost -c 20 -i 0.25 -s 1016 5 @@ -162,9 +158,9 @@ Iperf (DL/3Mbps/UDP)(30 sec) -u -b 3M -t 20 -R rfsim5g_multiue1 - acamas + localhost rfsim5g_ext_dn - acamas + localhost 5 90 @@ -174,9 +170,9 @@ Iperf (UL/1Mbps/UDP)(30 sec) -u -b 1M -t 20 rfsim5g_multiue1 - acamas + localhost rfsim5g_ext_dn - acamas + localhost 5 90 @@ -185,7 +181,7 @@ Detach_UE Detach OAI UEs rfsim5g_multiue1 - acamas + localhost @@ -195,15 +191,14 @@ ci-scripts/yaml_files/5g_rfsimulator_multiue 1,0,0,0 1,0,0,0 - 0 - 0 + localhost Clean_Test_Server_Images true Clean Test Images on Test Server - 0 + localhost oai-gnb-asan oai-nr-ue diff --git a/ci-scripts/xml_files/container_5g_rfsim_n2_ho.xml b/ci-scripts/xml_files/container_5g_rfsim_n2_ho.xml index feffaedf05..5da417c284 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_n2_ho.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_n2_ho.xml @@ -55,58 +55,54 @@ Pull_Local_Registry Pull Images from Local Registry - 0 + localhost oai-gnb-asan oai-nr-cuup-asan oai-nr-ue-asan Create_Workspace Create new Workspace - 0 - 0 + localhost Deploy_Object Deploy OAI 5G CoreNetwork + localhost ci-scripts/yaml_files/5g_rfsimulator_n2_ho mysql oai-amf oai-smf oai-upf oai-ext-dn - 0 - 0 Deploy_Object Deploy OAI 5G CU-CP/CU-UP/DU 0 + UE RFsim SA + localhost ci-scripts/yaml_files/5g_rfsimulator_n2_ho oai-cucp-0 oai-cuup-0 oai-du-0 oai-nr-ue - 0 - 0 Attach_UE Attach OAI UE (Wait for IP) rfsim5g_ue - acamas + localhost Deploy_Object Deploy OAI 5G CU-CP/CU-UP/DU 1 RFsim SA + localhost ci-scripts/yaml_files/5g_rfsimulator_n2_ho oai-cucp-1 oai-cuup-1 oai-du-1 - 0 - 0 Ping Ping NR-UE from ext-dn rfsim5g_ext_dn - acamas + localhost rfsim5g_ue - acamas + localhost -c 50 -i 0.25 5 @@ -115,9 +111,9 @@ Ping Ping ext-dn from NR-UE rfsim5g_ue - acamas + localhost rfsim5g_ext_dn - acamas + localhost -c 50 -i 0.25 10 @@ -127,9 +123,9 @@ Iperf (DL/10Mbps/UDP)(30 sec) -u -b 3M -t 20 -R rfsim5g_ue - acamas + localhost rfsim5g_ext_dn - acamas + localhost 5 90 @@ -139,9 +135,9 @@ Iperf (UL/4Mbps/UDP)(30 sec) -u -b 1M -t 20 rfsim5g_ue - acamas + localhost rfsim5g_ext_dn - acamas + localhost 5 90 @@ -155,7 +151,7 @@ Custom_Command Trigger N2 Handover - acamas + localhost echo ci trigger_n2_ho 1,1 | ncat 192.168.71.150 9090 yes @@ -163,14 +159,14 @@ Custom_Command UE (1) connected to DU-PCI 1? - acamas + localhost echo ci fetch_du_by_ue_id 1 | ncat 192.168.71.180 9090 | grep "1234" Custom_Command Trigger N2 Handover - acamas + localhost echo ci trigger_n2_ho 0,1 | ncat 192.168.71.180 9090 yes @@ -178,7 +174,7 @@ Custom_Command UE (1) connected to DU-PCI 0? - acamas + localhost echo ci fetch_du_by_ue_id 1 | ncat 192.168.71.150 9090 | grep "3584" @@ -186,9 +182,8 @@ Undeploy_Object true Undeploy all OAI 5G stack + localhost ci-scripts/yaml_files/5g_rfsimulator_n2_ho - 0 - 0 10,100,100,100 10,100,100,100 @@ -197,7 +192,7 @@ Clean_Test_Server_Images true Clean Test Images on Test Server - 0 + localhost oai-gnb-asan oai-nr-cuup-asan oai-nr-ue-asan diff --git a/ci-scripts/xml_files/container_5g_rfsim_ntn_geo.xml b/ci-scripts/xml_files/container_5g_rfsim_ntn_geo.xml index 7107b7971b..32bbbc683d 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_ntn_geo.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_ntn_geo.xml @@ -74,16 +74,16 @@ Attach_UE Attach OAI UE (Wait for IP) rfsim5g_ue - acamas + localhost Ping Ping ext-dn from NR-UE rfsim5g_ue - acamas + localhost rfsim5g_ext_dn - acamas + localhost -c 20 -i 0.25 5 @@ -92,9 +92,9 @@ Ping Ping NR-UE from ext-dn rfsim5g_ext_dn - acamas + localhost rfsim5g_ue - acamas + localhost -c 20 -i 0.25 5 @@ -102,7 +102,7 @@ Custom_Command Trigger Reestablishment - acamas + localhost echo ci force_reestab | ncat 192.168.71.140 9090 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment' yes @@ -111,9 +111,9 @@ Ping Ping ext-dn from NR-UE rfsim5g_ue - acamas + localhost rfsim5g_ext_dn - acamas + localhost -c 20 -i0.5 -w25 80 @@ -121,7 +121,7 @@ Custom_Command Verify Reestablishment - acamas + localhost echo ci get_reestab_count | ncat 192.168.71.140 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1' yes diff --git a/ci-scripts/xml_files/container_5g_rfsim_ntn_leo.xml b/ci-scripts/xml_files/container_5g_rfsim_ntn_leo.xml index 63897cfb8b..dd9fb56067 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_ntn_leo.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_ntn_leo.xml @@ -69,16 +69,16 @@ Attach_UE Attach OAI UE (Wait for IP) rfsim5g_ue - acamas + localhost Ping Ping ext-dn from NR-UE rfsim5g_ue - acamas + localhost rfsim5g_ext_dn - acamas + localhost -c 20 -i 0.25 5 @@ -87,9 +87,9 @@ Ping Ping NR-UE from ext-dn rfsim5g_ext_dn - acamas + localhost rfsim5g_ue - acamas + localhost -c 20 -i 0.25 5 diff --git a/ci-scripts/xml_files/container_5g_rfsim_sidelink.xml b/ci-scripts/xml_files/container_5g_rfsim_sidelink.xml index 58bff964d4..6ddd6d13b7 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_sidelink.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_sidelink.xml @@ -74,7 +74,7 @@ Custom_Command Check that UE synched - acamas + localhost docker logs rfsim5g-oai-nr-ue-2 | grep -m 1 "PSBCH RX:OK" diff --git a/ci-scripts/xml_files/container_5g_rfsim_tdd_dora.xml b/ci-scripts/xml_files/container_5g_rfsim_tdd_dora.xml index 97730bd233..a9f7f2c3aa 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_tdd_dora.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_tdd_dora.xml @@ -49,7 +49,7 @@ Custom_Command Clean-Up any residual volume - acamas + localhost docker volume rm 5g_rfsimulator_tdd_dora_rrc.config -f @@ -83,9 +83,9 @@ Ping Ping gNB from NR-UE rfsim5g_ue - acamas + localhost rfsim5g_gnb_nos1 - acamas + localhost -c20 -i0.2 0 @@ -94,9 +94,9 @@ Ping Ping NR-UE from gNB rfsim5g_gnb_nos1 - acamas + localhost rfsim5g_ue - acamas + localhost -c20 -i0.2 0 diff --git a/ci-scripts/xml_files/container_5g_rfsim_u0_25prb.xml b/ci-scripts/xml_files/container_5g_rfsim_u0_25prb.xml index c5c76124d3..f70c81732e 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_u0_25prb.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_u0_25prb.xml @@ -72,16 +72,16 @@ Attach_UE Attach OAI UE (Wait for IP) rfsim5g_ue - acamas + localhost Ping Ping ext-dn from NR-UE rfsim5g_ue - acamas + localhost rfsim5g_ext_dn - acamas + localhost -c 20 -i 0.25 5 @@ -90,9 +90,9 @@ Ping Ping NR-UE from ext-dn rfsim5g_ext_dn - acamas + localhost rfsim5g_ue - acamas + localhost -c 20 -i 0.25 5 @@ -101,16 +101,16 @@ Attach_UE Verify 2nd PDU session is up rfsim5g_ue_pdu_2 - acamas + localhost Ping Ping ext-dn from NR-UE on PDU session ID 2 rfsim5g_ue_pdu_2 - acamas + localhost rfsim5g_ext_dn - acamas + localhost -c 20 -i 0.25 5 @@ -120,9 +120,9 @@ Iperf (DL/3Mbps/UDP)(30 sec) -u -b 3M -t 20 -R rfsim5g_ue - acamas + localhost rfsim5g_ext_dn - acamas + localhost 5 90 @@ -132,9 +132,9 @@ Iperf (UL/1Mbps/UDP)(30 sec) -u -b 1M -t 20 rfsim5g_ue - acamas + localhost rfsim5g_ext_dn - acamas + localhost 5 90 diff --git a/ci-scripts/xml_files/container_sa_n2_ho_b210_quectel.xml b/ci-scripts/xml_files/container_sa_n2_ho_b210_quectel.xml new file mode 100644 index 0000000000..b67522b220 --- /dev/null +++ b/ci-scripts/xml_files/container_sa_n2_ho_b210_quectel.xml @@ -0,0 +1,230 @@ + + + TEST-MONO-N2-HO-B210 + Monolithic N2 Handover 20 MHz TDD SA + tasks + + 000001 + 000002 + 000023 + 000003 + 000004 + 000005 + 000006 + 000007 + 000008 + 000009 + 000010 + 000011 + 000012 + 000013 + 000014 + 000015 + 000017 + 000018 + 000019 + 000016 + 000020 + 000021 + 000022 + + + + + DeployCoreNetwork + Initialize 5G Core + oc-cn5g-00103-ho + + + + Pull_Local_Registry + Pull Images from Local Registry + oai-gnb + groot + + + + Pull_Local_Registry + Pull Images from Local Registry + oai-gnb + rocket + + + + Create_Workspace + Create new Workspace for groot + groot + + + + Create_Workspace + Create new Workspace on rocket + rocket + + + + Custom_Command + Set initial attenuation on target gNB + rocket + python3 %%workspace%%/ci-scripts/attenuatorctl.py -s 1,2 0 -s 3,4 15 + + + + Deploy_Object + Deploy Monolithic gNB-PCI0 (TDD/Band77/20MHz/B210) in a container + ci-scripts/yaml_files/5g_sa_n2_ho_b210 + groot + oai-gnb-pci0 + + + + Deploy_Object + Deploy Monolithic gNB-PCI1 (TDD/Band77/20MHz/B210) in a container + ci-scripts/yaml_files/5g_sa_n2_ho_b210 + rocket + oai-gnb-pci1 + + + + Attach_UE + Attach Quectel + raspix + + + + Ping + Ping: 100pings in 20sec + raspix + oc-cn5g-00103-ho + -c 100 -i 0.2 + 5 + + + + IdleSleep + Sleep + 5 + + + + Custom_Command + Gradually attenuate gNB-PCI0 (ch1-2=15dB) and gNB-PCI1 (ch3-4=0dB) over 5s to trigger N2 Handover to gNB-PCI1 + rocket + python3 %%workspace%%/ci-scripts/attenuatorctl.py -r 1,2 15 -r 3,4 0 -d 5 + + + + Ping + Ping: 50pings in 10sec + raspix + oc-cn5g-00103-ho + -c 50 -i 0.2 + 5 + + + + Custom_Command + UE connected to gNB-PCI1? + rocket + echo ci fetch_du_by_ue_id 1 | ncat 127.0.0.1 9090 | grep "3585" + + + + Custom_Command + Gradually attenuate gNB-PCI0 (ch1-2=0dB) and gNB-PCI1 (ch3-4=15dB) over 5s to trigger N2 Handover back to gNB-PCI0 + rocket + python3 %%workspace%%/ci-scripts/attenuatorctl.py -r 1,2 0 -r 3,4 15 -d 5 + + + + Ping + Ping: 50pings in 10sec + raspix + oc-cn5g-00103-ho + -c 50 -i 0.2 + 5 + + + + Custom_Command + UE connected to gNB-PCI0? + groot + echo ci fetch_du_by_ue_id 1 | ncat 127.0.0.1 9090 | grep "3584" + + + + Custom_Command + true + Reset all attenuators to 0dB + rocket + python3 %%workspace%%/ci-scripts/attenuatorctl.py -s 1-4 0 + + + + Detach_UE + true + Detach Quectel + raspix + + + + Undeploy_Object + true + Undeploy Monolithic gNB-PCI0 + groot + ci-scripts/yaml_files/5g_sa_n2_ho_b210 + + + + Undeploy_Object + true + Undeploy Monolithic gNB-PCI1 + rocket + ci-scripts/yaml_files/5g_sa_n2_ho_b210 + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + groot + oai-gnb + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + rocket + oai-gnb + + + + UndeployCoreNetwork + true + Terminate 5G Core + oc-cn5g-00103-ho + + + diff --git a/ci-scripts/yaml_files/5g_rfsimulator_n2_ho/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator_n2_ho/docker-compose.yaml index 6c03a02443..f3b75c1471 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator_n2_ho/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_rfsimulator_n2_ho/docker-compose.yaml @@ -150,7 +150,6 @@ services: --telnetsrv --telnetsrv.listenaddr 192.168.71.171 --telnetsrv.shrmod ci --rfsimulator.serveraddr 192.168.71.190 - --gNBs.[0].servingCellConfigCommon.[0].ra_ResponseWindow 5 ASAN_OPTIONS: detect_leaks=0:detect_odr_violation=0 depends_on: - oai-cucp-0 diff --git a/ci-scripts/yaml_files/5g_sa_n2_ho_b210/docker-compose.yml b/ci-scripts/yaml_files/5g_sa_n2_ho_b210/docker-compose.yml new file mode 100644 index 0000000000..6704b434db --- /dev/null +++ b/ci-scripts/yaml_files/5g_sa_n2_ho_b210/docker-compose.yml @@ -0,0 +1,61 @@ +services: + oai-gnb-pci0: + image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + container_name: oai-gnb-pci0 + cap_drop: + - ALL + cap_add: + - SYS_NICE + - IPC_LOCK + ulimits: + core: -1 # for core dumps + environment: + USE_B2XX: 'yes' + USE_ADDITIONAL_OPTIONS: --RUs.[0].sdr_addrs serial=30AD30F + --telnetsrv --telnetsrv.shrmod ci + --log_config.global_log_options level,nocolor,utc_time,line_num,function + ASAN_OPTIONS: detect_leaks=0:detect_odr_violation=0 + devices: + - /dev/bus/usb/:/dev/bus/usb/ + volumes: + - ../../conf_files/neighbour-config-ho.conf:/opt/oai-gnb/etc/neighbour-config-ho.conf + - ../../conf_files/gnb.sa.band77.51prb.usrpb200.n2-ho.conf:/opt/oai-gnb/etc/gnb.conf + network_mode: "host" + healthcheck: + test: /bin/bash -c "ps aux | grep -v grep | grep -c softmodem" + interval: 10s + timeout: 5s + retries: 5 + + oai-gnb-pci1: + image: ${REGISTRY:-oaisoftwarealliance}/${GNB_IMG:-oai-gnb}:${TAG:-develop} + container_name: oai-gnb-pci1 + cap_drop: + - ALL + cap_add: + - SYS_NICE + - IPC_LOCK + ulimits: + core: -1 # for core dumps + environment: + USE_B2XX: 'yes' + USE_ADDITIONAL_OPTIONS: --RUs.[0].sdr_addrs serial=31F8010 + --gNBs.[0].nr_cellid 11111111 + --gNBs.[0].gNB_ID 0xe01 + --gNBs.[0].servingCellConfigCommon.[0].physCellId 1 + --gNBs.[0].servingCellConfigCommon.[0].ssb_PositionsInBurst_Bitmap 2 + --gNBs.[0].NETWORK_INTERFACES.GNB_IPV4_ADDRESS_FOR_NG_AMF 172.21.19.99 + --gNBs.[0].NETWORK_INTERFACES.GNB_IPV4_ADDRESS_FOR_NGU 172.21.19.99 + --telnetsrv --telnetsrv.shrmod ci + --log_config.global_log_options level,nocolor,utc_time,line_num,function + devices: + - /dev/bus/usb/:/dev/bus/usb/ + volumes: + - ../../conf_files/neighbour-config-ho.conf:/opt/oai-gnb/etc/neighbour-config-ho.conf + - ../../conf_files/gnb.sa.band77.51prb.usrpb200.n2-ho.conf:/opt/oai-gnb/etc/gnb.conf + network_mode: "host" + healthcheck: + test: /bin/bash -c "ps aux | grep -v grep | grep -c softmodem" + interval: 10s + timeout: 5s + retries: 5 diff --git a/ci-scripts/yaml_files/5g_sa_n310_nrue/docker-compose.yml b/ci-scripts/yaml_files/5g_sa_n310_nrue/docker-compose.yml index aac787a916..9fb80ad065 100644 --- a/ci-scripts/yaml_files/5g_sa_n310_nrue/docker-compose.yml +++ b/ci-scripts/yaml_files/5g_sa_n310_nrue/docker-compose.yml @@ -17,7 +17,7 @@ services: #entrypoint: /bin/bash -c "sleep infinity" environment: TZ: Europe/Paris - USE_ADDITIONAL_OPTIONS: --usrp-args type=n3xx,name=ni-n3xx-31641B9,addr=192.168.10.2 -r 106 --numerology 1 --band 78 -C 3425010000 --ssb 509 --ue-fo-compensation --ue-rxgain 65 --tune-offset 20000000 -A 90 --log_config.global_log_options level,nocolor,time --uicc0.imsi 001020000000111 --uicc0.nssai_sd 16777215 + USE_ADDITIONAL_OPTIONS: --usrp-args type=n3xx,name=ni-n3xx-31641B9,addr=192.168.10.2 -r 106 --numerology 1 --band 78 -C 3425010000 --ssb 509 --ue-fo-compensation --ue-rxgain 65 --tune-offset 20000000 -A 90 --log_config.global_log_options level,nocolor,time --uicc0.imsi 001020000000111 volumes: - ../../conf_files/ue.sa.conf:/opt/oai-nr-ue/etc/nr-ue.conf healthcheck: diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 658b0b858a..6f61196e7e 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -92,7 +92,7 @@ Options: USRP, BLADERF, LMSSDR, IRIS, SIMU, AW2SORI, AERIAL, None (Default) Adds this RF board support (in external packages installation and in compilation) -t | --transport - Selects the transport protocol type, options: None, Ethernet, benetel4g, benetel5g, oran_fhlib_5g, oran_fhlib_5g_mplane, WLS + Selects the transport protocol type, options: None, Ethernet, oran_fhlib_5g, oran_fhlib_5g_mplane, WLS -P | --phy_simulators Makes the unitary tests Layer 1 simulators -V | --vcd @@ -278,10 +278,6 @@ function main() { TARGET_LIST="$TARGET_LIST oai_eth_transpro" CMAKE_CMD="$CMAKE_CMD -DOAI_${2^^}=ON" # ^^ makes uppercase ;; - "benetel4g" | "benetel5g" | "oran_fhlib_4g") - TARGET_LIST="$TARGET_LIST $2" - CMAKE_CMD="$CMAKE_CMD -DOAI_${2^^}=ON" # ^^ makes uppercase - ;; "oran_fhlib_5g") TARGET_LIST="$TARGET_LIST $2" CMAKE_CMD="$CMAKE_CMD -DOAI_FHI72=ON" diff --git a/cmake_targets/tools/oran_fhi_integration_patches/F/oaioran_F.patch b/cmake_targets/tools/oran_fhi_integration_patches/F/oaioran_F.patch index bec423b95e..3f953b36d9 100644 --- a/cmake_targets/tools/oran_fhi_integration_patches/F/oaioran_F.patch +++ b/cmake_targets/tools/oran_fhi_integration_patches/F/oaioran_F.patch @@ -1,5 +1,5 @@ diff --git a/fhi_lib/app/src/common.h b/fhi_lib/app/src/common.h -index ac5f471..5efcce3 100644 +index ac5f471..b0f7ed1 100644 --- a/fhi_lib/app/src/common.h +++ b/fhi_lib/app/src/common.h @@ -28,7 +28,7 @@ @@ -7,7 +7,7 @@ index ac5f471..5efcce3 100644 #include -#define VERSIONX "oran_f_release_v1.0" -+#define VERSIONX "oran_f_release_v1.4" ++#define VERSIONX "oran_f_release_v1.5" #define APP_O_DU 0 #define APP_O_RU 1 @@ -919,7 +919,7 @@ index 4acade1..c939edc 100644 for(i = 0; i < xran_ports_num; i++){ g_xran_dev_ctx[i] = pCtx; diff --git a/fhi_lib/lib/src/xran_main.c b/fhi_lib/lib/src/xran_main.c -index 7c472d7..216c7f5 100644 +index 7c472d7..9da3621 100644 --- a/fhi_lib/lib/src/xran_main.c +++ b/fhi_lib/lib/src/xran_main.c @@ -35,7 +35,11 @@ @@ -969,7 +969,29 @@ index 7c472d7..216c7f5 100644 print_dbg("PRACH eAxC_offset %d\n", pPrachCPConfig->eAxC_offset); /* Save some configs for app */ -@@ -1570,6 +1593,7 @@ int32_t handle_ecpri_ethertype(struct rte_mbuf* pkt_q[], uint16_t xport_id, stru +@@ -1169,6 +1192,10 @@ xran_prepare_cp_ul_slot(uint16_t xran_port_id, uint32_t nSlotIdx, uint32_t nCcS + uint8_t seqid = xran_get_cp_seqid(pHandle, XRAN_DIR_UL, cc_id, port_id); + + beam_id = xran_get_beamid(pHandle, XRAN_DIR_UL, cc_id, port_id, slot_id); ++ pBufList = &(p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[buf_id][cc_id][ant_id].sBufferList); ++ struct xran_prb_map *prbMap = pBufList->pBuffers->pData; ++ struct xran_prb_elm *pPrbElm = &prbMap->prbMap[0]; //mjoang ++ beam_id = pPrbElm->nBeamIndex; + ret = generate_cpmsg_prach(pHandle, ¶ms, sect_geninfo, mbuf, p_xran_dev_ctx, + frame_id, subframe_id, slot_id, tti, + beam_id, cc_id, port_id, occasionid, seqid); +@@ -1338,6 +1365,10 @@ tx_cp_ul_cb(struct rte_timer *tim, void *arg) + uint8_t seqid = xran_get_cp_seqid(pHandle, XRAN_DIR_UL, cc_id, port_id); + + beam_id = xran_get_beamid(pHandle, XRAN_DIR_UL, cc_id, port_id, slot_id); ++ pBufList = &(p_xran_dev_ctx->sFrontHaulRxPrbMapBbuIoBufCtrl[buf_id][cc_id][ant_id].sBufferList); ++ struct xran_prb_map *prbMap = pBufList->pBuffers->pData; ++ struct xran_prb_elm *pPrbElm = &prbMap->prbMap[0]; //mjoang ++ beam_id = pPrbElm->nBeamIndex; + ret = generate_cpmsg_prach(pHandle, ¶ms, sect_geninfo, mbuf, p_xran_dev_ctx, + frame_id, subframe_id, slot_id, tti, + beam_id, cc_id, port_id, occasionid, seqid); +@@ -1570,6 +1601,7 @@ int32_t handle_ecpri_ethertype(struct rte_mbuf* pkt_q[], uint16_t xport_id, stru { case ECPRI_IQ_DATA: pkt_data[num_data++] = pkt; @@ -977,7 +999,7 @@ index 7c472d7..216c7f5 100644 break; // For RU emulation case ECPRI_RT_CONTROL_DATA: -@@ -1587,7 +1611,7 @@ int32_t handle_ecpri_ethertype(struct rte_mbuf* pkt_q[], uint16_t xport_id, stru +@@ -1587,7 +1619,7 @@ int32_t handle_ecpri_ethertype(struct rte_mbuf* pkt_q[], uint16_t xport_id, stru break; default: if (p_dev_ctx->fh_init.io_cfg.id == O_DU) { @@ -986,7 +1008,7 @@ index 7c472d7..216c7f5 100644 } break; } -@@ -1876,7 +1900,7 @@ xran_sector_get_instances (uint32_t xran_port, void * pDevHandle, uint16_t nNumI +@@ -1876,7 +1908,7 @@ xran_sector_get_instances (uint32_t xran_port, void * pDevHandle, uint16_t nNumI for (i = 0; i < nNumInstances; i++) { /* Allocate Memory for CC handles */ @@ -995,7 +1017,7 @@ index 7c472d7..216c7f5 100644 if(pCcHandle == NULL) return XRAN_STATUS_RESOURCE; -@@ -2347,8 +2371,7 @@ ring_processing_func_per_port(void* args) +@@ -2347,8 +2379,7 @@ ring_processing_func_per_port(void* args) for (i = 0; i < ctx->io_cfg.num_vfs && i < XRAN_VF_MAX; i = i+1) { if (ctx->vf2xran_port[i] == port_id) { for(qi = 0; qi < ctx->rxq_per_port[port_id]; qi++){ @@ -1005,7 +1027,7 @@ index 7c472d7..216c7f5 100644 } } } -@@ -2414,9 +2437,6 @@ xran_spawn_workers(void) +@@ -2414,9 +2445,6 @@ xran_spawn_workers(void) nWorkerCore = nWorkerCore << 1; } @@ -1015,7 +1037,7 @@ index 7c472d7..216c7f5 100644 printf("O-XU %d\n", eth_ctx->io_cfg.id); printf("HW %d\n", icx_cpu); printf("Num cores %d\n", total_num_cores); -@@ -2453,7 +2473,7 @@ xran_spawn_workers(void) +@@ -2453,7 +2481,7 @@ xran_spawn_workers(void) eth_ctx->time_wrk_cfg.arg = NULL; eth_ctx->time_wrk_cfg.state = 1; @@ -1024,7 +1046,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -2475,7 +2495,7 @@ xran_spawn_workers(void) +@@ -2475,7 +2503,7 @@ xran_spawn_workers(void) /* workers */ /** 0 **/ @@ -1033,7 +1055,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -2502,7 +2522,7 @@ xran_spawn_workers(void) +@@ -2502,7 +2530,7 @@ xran_spawn_workers(void) } /** 1 - CP GEN **/ @@ -1042,7 +1064,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -2536,7 +2556,7 @@ xran_spawn_workers(void) +@@ -2536,7 +2564,7 @@ xran_spawn_workers(void) else p_dev->tx_sym_gen_func = xran_process_tx_sym_cp_on_opt; @@ -1051,7 +1073,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -2559,7 +2579,7 @@ xran_spawn_workers(void) +@@ -2559,7 +2587,7 @@ xran_spawn_workers(void) /* workers */ /** 0 **/ @@ -1060,7 +1082,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -2586,7 +2606,7 @@ xran_spawn_workers(void) +@@ -2586,7 +2614,7 @@ xran_spawn_workers(void) } /** 1 - CP GEN **/ @@ -1069,7 +1091,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -2613,7 +2633,7 @@ xran_spawn_workers(void) +@@ -2613,7 +2641,7 @@ xran_spawn_workers(void) /* workers */ /** 0 **/ @@ -1078,7 +1100,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -2628,7 +2648,7 @@ xran_spawn_workers(void) +@@ -2628,7 +2656,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** 1 - CP GEN **/ @@ -1087,7 +1109,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -2643,7 +2663,7 @@ xran_spawn_workers(void) +@@ -2643,7 +2671,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** 2 UP GEN **/ @@ -1096,7 +1118,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -2682,7 +2702,7 @@ xran_spawn_workers(void) +@@ -2682,7 +2710,7 @@ xran_spawn_workers(void) /* workers */ /** 0 **/ @@ -1105,7 +1127,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -2697,7 +2717,7 @@ xran_spawn_workers(void) +@@ -2697,7 +2725,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** 1 - CP GEN **/ @@ -1114,7 +1136,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -2712,7 +2732,7 @@ xran_spawn_workers(void) +@@ -2712,7 +2740,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** 2 UP GEN **/ @@ -1123,7 +1145,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -2727,7 +2747,7 @@ xran_spawn_workers(void) +@@ -2727,7 +2755,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** 3 UP GEN **/ @@ -1132,7 +1154,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -2766,7 +2786,7 @@ xran_spawn_workers(void) +@@ -2766,7 +2794,7 @@ xran_spawn_workers(void) /* workers */ /** 0 **/ @@ -1141,7 +1163,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -2781,7 +2801,7 @@ xran_spawn_workers(void) +@@ -2781,7 +2809,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** 1 Eth Tx **/ @@ -1150,7 +1172,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); -@@ -2797,7 +2817,7 @@ xran_spawn_workers(void) +@@ -2797,7 +2825,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** 2 - CP GEN **/ @@ -1159,7 +1181,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -2812,7 +2832,7 @@ xran_spawn_workers(void) +@@ -2812,7 +2840,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** 3 UP GEN **/ @@ -1168,7 +1190,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -2827,7 +2847,7 @@ xran_spawn_workers(void) +@@ -2827,7 +2855,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** 4 UP GEN **/ @@ -1177,7 +1199,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -2861,7 +2881,7 @@ xran_spawn_workers(void) +@@ -2861,7 +2889,7 @@ xran_spawn_workers(void) /* workers */ /** 0 Eth RX */ @@ -1186,7 +1208,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -2876,7 +2896,7 @@ xran_spawn_workers(void) +@@ -2876,7 +2904,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** 1 FH RX and BBDEV */ @@ -1195,7 +1217,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -2891,7 +2911,7 @@ xran_spawn_workers(void) +@@ -2891,7 +2919,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** 2 FH RX and BBDEV */ @@ -1204,7 +1226,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -2906,7 +2926,7 @@ xran_spawn_workers(void) +@@ -2906,7 +2934,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** 3 FH RX and BBDEV */ @@ -1213,7 +1235,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -2921,7 +2941,7 @@ xran_spawn_workers(void) +@@ -2921,7 +2949,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** FH TX and BBDEV */ @@ -1222,7 +1244,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -2969,7 +2989,7 @@ xran_spawn_workers(void) +@@ -2969,7 +2997,7 @@ xran_spawn_workers(void) /* p_dev->tx_sym_gen_func = xran_process_tx_sym_cp_on_opt; */ @@ -1231,7 +1253,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3004,7 +3024,7 @@ xran_spawn_workers(void) +@@ -3004,7 +3032,7 @@ xran_spawn_workers(void) /* workers */ /** 0 **/ @@ -1240,7 +1262,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3031,7 +3051,7 @@ xran_spawn_workers(void) +@@ -3031,7 +3059,7 @@ xran_spawn_workers(void) } /** 1 - CP GEN **/ @@ -1249,7 +1271,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3062,7 +3082,7 @@ xran_spawn_workers(void) +@@ -3062,7 +3090,7 @@ xran_spawn_workers(void) /* workers */ /** 0 **/ @@ -1258,7 +1280,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3089,7 +3109,7 @@ xran_spawn_workers(void) +@@ -3089,7 +3117,7 @@ xran_spawn_workers(void) } /** 1 - CP GEN **/ @@ -1267,7 +1289,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3115,7 +3135,7 @@ xran_spawn_workers(void) +@@ -3115,7 +3143,7 @@ xran_spawn_workers(void) /* workers */ /** 0 **/ @@ -1276,7 +1298,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3130,7 +3150,7 @@ xran_spawn_workers(void) +@@ -3130,7 +3158,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** 1 - CP GEN **/ @@ -1285,7 +1307,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3145,7 +3165,7 @@ xran_spawn_workers(void) +@@ -3145,7 +3173,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** 2 UP GEN **/ @@ -1294,7 +1316,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3184,7 +3204,7 @@ xran_spawn_workers(void) +@@ -3184,7 +3212,7 @@ xran_spawn_workers(void) /* workers */ /** 0 FH RX and BBDEV */ @@ -1303,7 +1325,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3199,7 +3219,7 @@ xran_spawn_workers(void) +@@ -3199,7 +3227,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** 1 - CP GEN **/ @@ -1312,7 +1334,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3214,7 +3234,7 @@ xran_spawn_workers(void) +@@ -3214,7 +3242,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** 2 UP GEN **/ @@ -1321,7 +1343,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3229,7 +3249,7 @@ xran_spawn_workers(void) +@@ -3229,7 +3257,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** 3 UP GEN **/ @@ -1330,7 +1352,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3266,7 +3286,7 @@ xran_spawn_workers(void) +@@ -3266,7 +3294,7 @@ xran_spawn_workers(void) /* workers */ /** 0 **/ @@ -1339,7 +1361,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3281,7 +3301,7 @@ xran_spawn_workers(void) +@@ -3281,7 +3309,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** 1 - CP GEN **/ @@ -1348,7 +1370,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3296,7 +3316,7 @@ xran_spawn_workers(void) +@@ -3296,7 +3324,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** 2 UP GEN **/ @@ -1357,7 +1379,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3311,7 +3331,7 @@ xran_spawn_workers(void) +@@ -3311,7 +3339,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** 3 UP GEN **/ @@ -1366,7 +1388,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3326,7 +3346,7 @@ xran_spawn_workers(void) +@@ -3326,7 +3354,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** 4 UP GEN **/ @@ -1375,7 +1397,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3348,7 +3368,7 @@ xran_spawn_workers(void) +@@ -3348,7 +3376,7 @@ xran_spawn_workers(void) /* workers */ /** 0 Eth RX */ @@ -1384,7 +1406,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3363,7 +3383,7 @@ xran_spawn_workers(void) +@@ -3363,7 +3391,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** 1 FH RX and BBDEV */ @@ -1393,7 +1415,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3378,7 +3398,7 @@ xran_spawn_workers(void) +@@ -3378,7 +3406,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** 2 FH RX and BBDEV */ @@ -1402,7 +1424,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3393,7 +3413,7 @@ xran_spawn_workers(void) +@@ -3393,7 +3421,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** 3 FH RX and BBDEV */ @@ -1411,7 +1433,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3408,7 +3428,7 @@ xran_spawn_workers(void) +@@ -3408,7 +3436,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** FH TX and BBDEV */ @@ -1420,7 +1442,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3435,7 +3455,7 @@ xran_spawn_workers(void) +@@ -3435,7 +3463,7 @@ xran_spawn_workers(void) /* workers */ /** 0 Eth RX */ @@ -1429,7 +1451,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3450,7 +3470,7 @@ xran_spawn_workers(void) +@@ -3450,7 +3478,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** 1 FH RX and BBDEV */ @@ -1438,7 +1460,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3465,7 +3485,7 @@ xran_spawn_workers(void) +@@ -3465,7 +3493,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** 2 FH RX and BBDEV */ @@ -1447,7 +1469,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3480,7 +3500,7 @@ xran_spawn_workers(void) +@@ -3480,7 +3508,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** 3 FH RX and BBDEV */ @@ -1456,7 +1478,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3495,7 +3515,7 @@ xran_spawn_workers(void) +@@ -3495,7 +3523,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** 4 FH RX and BBDEV */ @@ -1465,7 +1487,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3510,7 +3530,7 @@ xran_spawn_workers(void) +@@ -3510,7 +3538,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** FH TX and BBDEV */ @@ -1474,7 +1496,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3537,7 +3557,7 @@ xran_spawn_workers(void) +@@ -3537,7 +3565,7 @@ xran_spawn_workers(void) /* workers */ /** 0 **/ @@ -1483,7 +1505,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3562,7 +3582,7 @@ xran_spawn_workers(void) +@@ -3562,7 +3590,7 @@ xran_spawn_workers(void) } /** 1 - CP GEN **/ @@ -1492,7 +1514,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3577,7 +3597,7 @@ xran_spawn_workers(void) +@@ -3577,7 +3605,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** 2 UP GEN **/ @@ -1501,7 +1523,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3602,7 +3622,7 @@ xran_spawn_workers(void) +@@ -3602,7 +3630,7 @@ xran_spawn_workers(void) } /** 3 UP GEN **/ @@ -1510,7 +1532,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3627,7 +3647,7 @@ xran_spawn_workers(void) +@@ -3627,7 +3655,7 @@ xran_spawn_workers(void) } /** 4 UP GEN **/ @@ -1519,7 +1541,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -3642,7 +3662,7 @@ xran_spawn_workers(void) +@@ -3642,7 +3670,7 @@ xran_spawn_workers(void) eth_ctx->pkt_wrk_cfg[pThCtx->worker_id].arg = pThCtx; /** 5 UP GEN **/ @@ -1528,7 +1550,7 @@ index 7c472d7..216c7f5 100644 if(pThCtx == NULL){ print_err("pThCtx allocation error\n"); return XRAN_STATUS_FAIL; -@@ -4034,6 +4054,24 @@ xran_get_slot_idx (uint32_t PortId, uint32_t *nFrameIdx, uint32_t *nSubframeIdx, +@@ -4034,6 +4062,24 @@ xran_get_slot_idx (uint32_t PortId, uint32_t *nFrameIdx, uint32_t *nSubframeIdx, return tti; } diff --git a/common/5g_platform_types.h b/common/5g_platform_types.h index 4ed7f33e47..7cae0afde7 100644 --- a/common/5g_platform_types.h +++ b/common/5g_platform_types.h @@ -37,9 +37,7 @@ typedef struct nssai_s { // Globally Unique AMF Identifier typedef struct nr_guami_s { - uint16_t mcc; - uint16_t mnc; - uint8_t mnc_len; + plmn_id_t plmn; uint8_t amf_region_id; uint16_t amf_set_id; uint8_t amf_pointer; diff --git a/common/utils/T/tracer/ue.c b/common/utils/T/tracer/ue.c index f4ea38f980..6d7d9ce4c5 100644 --- a/common/utils/T/tracer/ue.c +++ b/common/utils/T/tracer/ue.c @@ -196,7 +196,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, view *v; logger *l; - main_window = new_toplevel_window(g, 1200, 900, "eNB tracer"); + main_window = new_toplevel_window(g, 1200, 900, "UE tracer"); top_container = new_container(g, VERTICAL); widget_add_child(g, main_window, top_container, -1); @@ -207,7 +207,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, /* logo */ widget_add_child(g, line, logo, -1); - input_signal_plot = new_xy_plot(g, 256, 55, "input signal", 20); + input_signal_plot = new_xy_plot(g, 512, 110, "input signal", 20); widget_add_child(g, line, input_signal_plot, -1); xy_plot_set_range(g, input_signal_plot, 0, 7680*10, 20, 70); input_signal_log = new_framelog(h, database, @@ -221,7 +221,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, logger_add_view(input_signal_log, input_signal_view); /* UE x PDSCH IQ data */ - w = new_xy_plot(g, 55, 55, "", 50); + w = new_xy_plot(g, 110, 110, "", 50); e->pdsch_iq_ue_xy_plot = w; widget_add_child(g, line, w, -1); xy_plot_set_range(g, w, -500, 500, -500, 500); @@ -232,7 +232,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, e->pdsch_iq_ue_logger = l; /* UE x estimated DL channel */ - w = new_xy_plot(g, 280, 55, "", 50); + w = new_xy_plot(g, 560, 110, "", 50); e->dl_estimate_ue_xy_plot = w; widget_add_child(g, line, w, -1); xy_plot_set_range(g, w, 0, 512*10, -10, 80); @@ -245,7 +245,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, e->dl_estimate_ue_logger = l; /* PHY Meas */ - w = new_xy_plot(g, 128, 55, "", 50); + w = new_xy_plot(g, 256, 110, "", 50); e->phy_meas_xy_plot = w; widget_add_child(g, line, w, -1); xy_plot_set_range(g, w, 0, 1024*10, -130, 35); @@ -271,7 +271,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, /* UE x DL mcs */ line = new_container(g, HORIZONTAL); widget_add_child(g, top_container, line, -1); - w = new_xy_plot(g, 128, 55, "", 20); + w = new_xy_plot(g, 192, 110, "", 20); xy_plot_set_range(g, w, 0, 1024*10, -2, 30); e->dl_mcs_xy_plot = w; widget_add_child(g, line, w, -1); @@ -282,7 +282,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, e->dl_mcs_logger = l; /* UE x UL mcs */ - w = new_xy_plot(g, 128, 55, "", 20); + w = new_xy_plot(g, 192, 110, "", 20); xy_plot_set_range(g, w, 0, 1024*10, -2, 30); e->ul_mcs_xy_plot = w; widget_add_child(g, line, w, -1); @@ -295,7 +295,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, /* UE x PUSCH TX Power */ // line = new_container(g, HORIZONTAL); // widget_add_child(g, top_container, line, -1); - w = new_xy_plot(g, 128, 55, "", 20); + w = new_xy_plot(g, 192, 110, "", 20); e->pusch_power_xy_plot = w; widget_add_child(g, line, w, -1); xy_plot_set_range(g, w, 0, 1024*10, -30, 50); @@ -313,7 +313,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, /* UE x PUCCH TX Power */ // line = new_container(g, HORIZONTAL); // widget_add_child(g, top_container, line, -1); - w = new_xy_plot(g, 128, 55, "", 20); + w = new_xy_plot(g, 192, 110, "", 20); e->pucch_power_xy_plot = w; widget_add_child(g, line, w, -1); xy_plot_set_range(g, w, 0, 1024*10, -30, 50); @@ -329,7 +329,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, e->pucch_ampl_logger = l; /* UE x PDSCH energy */ - w = new_xy_plot(g, 128, 55, "", 50); + w = new_xy_plot(g, 192, 110, "", 50); e->pdsch_energy_ue_xy_plot = w; widget_add_child(g, line, w, -1); xy_plot_set_range(g, w, 0, 1024*10, -10, 80); @@ -355,7 +355,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, e->pdsch_energy_logger = l; /* UE x PDCCH energy */ - w = new_xy_plot(g, 128, 55, "", 50); + w = new_xy_plot(g, 192, 110, "", 50); e->pdcch_energy_ue_xy_plot = w; widget_add_child(g, line, w, -1); xy_plot_set_range(g, w, 0, 1024*10, -10, 80); @@ -381,7 +381,7 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, e->pdcch_energy_logger = l; /* UE x PDCCH IQ data */ - w = new_xy_plot(g, 55, 55, "", 50); + w = new_xy_plot(g, 110, 110, "", 50); e->pdcch_iq_ue_xy_plot = w; widget_add_child(g, line, w, -1); xy_plot_set_range(g, w, -100, 100, -100, 100); @@ -544,16 +544,16 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, /* phy/mac/rlc/pdcp/rrc textlog */ line = new_container(g, HORIZONTAL); widget_add_child(g, top_container, line, -1); - container_set_child_growable(g, top_container, line, 1); + container_set_child_growable(g, top_container, line, 0); /* phy */ col = new_container(g, VERTICAL); widget_add_child(g, line, col, -1); container_set_child_growable(g, line, col, 1); widget_add_child(g, col, new_label(g, "PHY"), -1); - text = new_textlist(g, 100, 10, new_color(g, "#afa")); + text = new_textlist(g, 100, 5, new_color(g, "#afa")); widget_add_child(g, col, text, -1); - container_set_child_growable(g, col, text, 1); + container_set_child_growable(g, col, text, 0); textview = new_view_textlist(10000, 10, g, text); e->phyview = textview; @@ -562,24 +562,24 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, widget_add_child(g, line, col, -1); container_set_child_growable(g, line, col, 1); widget_add_child(g, col, new_label(g, "MAC"), -1); - text = new_textlist(g, 100, 10, new_color(g, "#adf")); + text = new_textlist(g, 100, 5, new_color(g, "#adf")); widget_add_child(g, col, text, -1); - container_set_child_growable(g, col, text, 1); + container_set_child_growable(g, col, text, 0); textview = new_view_textlist(10000, 10, g, text); e->macview = textview; line = new_container(g, HORIZONTAL); widget_add_child(g, top_container, line, -1); - container_set_child_growable(g, top_container, line, 1); + container_set_child_growable(g, top_container, line, 0); /* rlc */ col = new_container(g, VERTICAL); widget_add_child(g, line, col, -1); container_set_child_growable(g, line, col, 1); widget_add_child(g, col, new_label(g, "RLC"), -1); - text = new_textlist(g, 100, 10, new_color(g, "#aff")); + text = new_textlist(g, 100, 5, new_color(g, "#aff")); widget_add_child(g, col, text, -1); - container_set_child_growable(g, col, text, 1); + container_set_child_growable(g, col, text, 0); textview = new_view_textlist(10000, 10, g, text); e->rlcview = textview; @@ -588,24 +588,24 @@ static void ue_main_gui(ue_gui *e, gui *g, event_handler *h, void *database, widget_add_child(g, line, col, -1); container_set_child_growable(g, line, col, 1); widget_add_child(g, col, new_label(g, "PDCP"), -1); - text = new_textlist(g, 100, 10, new_color(g, "#ed9")); + text = new_textlist(g, 100, 5, new_color(g, "#ed9")); widget_add_child(g, col, text, -1); - container_set_child_growable(g, col, text, 1); + container_set_child_growable(g, col, text, 0); textview = new_view_textlist(10000, 10, g, text); e->pdcpview = textview; line = new_container(g, HORIZONTAL); widget_add_child(g, top_container, line, -1); - container_set_child_growable(g, top_container, line, 1); + container_set_child_growable(g, top_container, line, 0); /* rrc */ col = new_container(g, VERTICAL); widget_add_child(g, line, col, -1); container_set_child_growable(g, line, col, 1); widget_add_child(g, col, new_label(g, "RRC"), -1); - text = new_textlist(g, 100, 10, new_color(g, "#fdb")); + text = new_textlist(g, 100, 5, new_color(g, "#fdb")); widget_add_child(g, col, text, -1); - container_set_child_growable(g, col, text, 1); + container_set_child_growable(g, col, text, 0); textview = new_view_textlist(10000, 10, g, text); e->rrcview = textview; diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md index 43b8367e3b..c703899c16 100644 --- a/doc/FEATURE_SET.md +++ b/doc/FEATURE_SET.md @@ -29,9 +29,9 @@ The following features are valid for the gNB and the 5G-NR UE. * Static FDD * Normal CP * Subcarrier spacings: 15 and 30kHz (FR1), 120kHz (FR2) -* Bandwidths: 10, 20, 40, 60, 80, 100MHz +* Bandwidths: 5-100MHz (FR1), 100 and 200MHz (FR2) * Intermediate downlink and uplink frequencies to interface with IF equipment -* Procedures for 2-layer DL and UL MIMO +* Procedures for 4-layer DL and 2-layer UL SU-MIMO * Slot format: 14 OFDM symbols in UL or DL * Highly efficient 3GPP compliant LDPC encoder and decoder (BG1 and BG2 supported) * Highly efficient 3GPP compliant polar encoder and decoder @@ -47,7 +47,7 @@ These modes of operation are supported: * "noS1" mode (DL and UL, gNB, nrUE): - Connection setup stops after RA; RRC configuration is exchanged through files - - Creates TUN interface to PDCP to inject and receive user-place traffic + - Creates TUN interface to SDAP to inject and receive user-place traffic - No connection to the core network * Standalone (SA) mode (gNB, nrUE): - UE can register with the 5G Core Network through the gNB, establish a PDU @@ -73,7 +73,7 @@ These modes of operation are supported: - Single and multiple DMRS symbols - PTRS support - Support for up to 4 TX antennas - - Support for up to 2 layers + - Support for up to 4 layers - Support for 256 QAM * NR-CSIRS Generation of sequence at PHY * NR-PUSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc). @@ -104,7 +104,9 @@ These modes of operation are supported: ## gNB MAC - MAC -> PHY configuration using NR FAPI P5 interface -- MAC <-> PHY data interface using FAPI P7 interface for BCH PDU, DCI PDU, PDSCH PDU +- MAC <-> PHY data interface using FAPI P7 interface for DL_TTI.request, + UL_TTI.request, UL_DCI.request, TX_data.request, RX_Data.indication, + CRC.indication, UCI.indication, SRS.indication - Generation of and scheduler procedures for MIB/SIB1 - Scheduler procedures for RA - 4-Step RA @@ -123,13 +125,14 @@ These modes of operation are supported: - MAC downlink scheduler - phy-test scheduler (fixed allocation and usable also without UE) - regular scheduler with dynamic proportionally-fair allocation - - MCS adaptation from HARQ BLER + - MCS adaptation from HARQ BLER or SSB-SINR report - MAC header generation (including timing advance) -- ACK / NACK handling and HARQ procedures for downlink +- ACK/NACK handling and HARQ procedures for downlink - MAC uplink scheduler - phy-test scheduler (fixed allocation) - regular scheduler with dynamic proportionally-fair allocation - HARQ procedures for uplink + - MCS adaption from HARQ BLER or PUSCH SINR - Scheduler procedures for SRS reception - Periodic SRS reception - Channel rank computation up to 2x2 scenario @@ -144,7 +147,15 @@ These modes of operation are supported: neighbors include cells operating on different frequencies - DUs must be synchronized with each other for the measurements to be properly performed - Initial support for RedCap -- Scheduling of SIBs (2, 19) + - RedCap SIB1 v17 IEs supported + - Coexistence of RedCap and Normal UEs + - Handling of RedCap capability for small PDCP/RLC SN size +- Scheduling of other SIBs (2, 19) +- NTN + - Support downlinkHARQ-FeedbackDisabled-r17 + - Support for 32 PDSCH and PUSCH HARQ processes per UE + - Consider ntn-Config-r17.cellSpecificKoffset-r17 in scheduling + - Function-based interface for ntn-Config-r17 updates (used by NTN-LEO RFsimulator) ## gNB RLC @@ -180,7 +191,7 @@ These modes of operation are supported: - NR RRC (38.331) Rel 17 messages using new [asn1c](https://github.com/mouse07410/asn1c) - LTE RRC (36.331) also updated to Rel 15 - Generation of system information (SIB2) -- RRC can configure PDCP, RLC, MAC +- RRC can configure PDCP and SDAP (through E1), and RLC and MAC (through F1) - Interface with GTP-U (tunnel creation/handling for S1-U (NSA), N3 (SA), F1 interfaces) - Integration of RRC messages and procedures supporting UE 5G SA connection - RRCSetupRequest/RRCSetup/RRCSetupComplete @@ -190,8 +201,17 @@ These modes of operation are supported: - Support for MasterCellGroup configuration (from DU) - Interface with NGAP for the interactions with the AMF - Interface with F1AP for CU/DU split deployment option - - Periodic RRC measurements of serving cell (no A/B events) -- Initial support for RedCap + - Interface with E1AP for CU-CP/CU-CP split deployment option + - Periodic RRC measurements of serving/neighbour cells and A2/A3 event + handling +- RRC Mobility Management Procedures: + - Inter-DU Handover (F1-based handover within same CU) + - Inter-gNB Handover (N2-based handover between different gNBs) + - Handover Preparation Information generation and processing + - Handover Command generation and processing + - PDCP Status transfer procedures + - Support for handover decision triggers (A3 events, manual triggers) +- Initial support for RedCap (see MAC) ## gNB X2AP @@ -209,6 +229,16 @@ These modes of operation are supported: - NGAP UE context release request/complete - NGAP UE radio capability info indication - NGAP PDU session resource setup request/response + - NGAP Mobility Management Procedures: + * NGAP Handover Required + * NGAP Handover Request + * NGAP Handover Request Acknowledge + * NGAP Handover Command + * NGAP Handover Notify + * NGAP Handover Cancel + * NGAP Handover Cancel Acknowledge + * NGAP Uplink RAN Status Transfer + * NGAP Downlink RAN Status Transfer - Interface with RRC ## gNB F1AP @@ -226,7 +256,10 @@ These modes of operation are supported: * F1 UE Context modification required * F1 UE Context release req/cmd/complete - F1 gNB CU configuration update + - F1 gNB DU configuration update - F1 Reset (handled at DU only, full reset only) + - F1 Mobility Management Procedures: + * F1 Intra-CU Handover (Inter-DU mobility) - Interface with RRC - Interface with GTP-u (tunnel creation/handling for F1-U interface) - One CU(-CP) can handle multiple DUs @@ -245,7 +278,8 @@ These modes of operation are supported: - Bearer Context Modification (gNB-CU-CP initiated) - E1 Bearer Context Modification Request - E1 Bearer Context Modification Response -- Interface with RRC and PDCP + - E1 Reset +- Interface with RRC and PDCP/SDAP - One CU-CP can handle multiple CU-UPs ## gNB GTP-U @@ -268,7 +302,8 @@ These modes of operation are supported: - non-blind synchronization (information required: carrier frequency, bandwidth, numerology) - option to search SSB inside the bandwidth available * Time tracking based on PBCH DMRS -* Frequency offset estimation based on PSS and SSS +* Initial Frequency offset estimation based on PSS and SSS +* Continuous Frequency offset estimation and compensation based on PBCH DMRS * 15kHz and 30kHz SCS for FR1 and 120 kHz SCS for FR2 * Reception of NR-PSS/NR-SSS * NR-PBCH supports multiple SSBs and flexible periodicity @@ -299,6 +334,7 @@ These modes of operation are supported: - Support for 256 QAM - Support for up to 2 TX antenna - Support for up to 2 layers + - Support for UCI on PUSCH * NR-PUCCH - Format 0 (2 bits for ACK/NACK and SR) - Format 2 (mainly for CSI feedback) @@ -314,6 +350,10 @@ These modes of operation are supported: - Support for multiple gNB reception with gNBs synced via GPSDO * NR-PRACH - Formats 0,1,2,3, A1-A3, B1-B3 +* NTN + - TA adjustemt based on ntn-Config-r17 information + - Autonomous TA adjustemt between SIB19 receptions based on DL time tracking + - UL Doppler pre-compensation based on continuous DL FO estimation * Highly efficient 3GPP compliant LDPC encoder and decoder (BG1 and BG2 are supported) * Highly efficient 3GPP compliant polar encoder and decoder * Encoder and decoder for short block @@ -331,6 +371,8 @@ These modes of operation are supported: * Minimum system information (MSI) - MIB processing - Scheduling of system information block 1 (SIB1) reception +* Other system information + - Scheduling of other system information blocks reception * Random access procedure (needs improvement, there is still not a clear separation between MAC and PHY) - Mapping SSBs to multiple ROs - Scheduling of PRACH @@ -367,6 +409,10 @@ These modes of operation are supported: - Periodic and aperiodic SRS transmission * Bandwidth part (BWP) operation - Operation in configured dedicated BWP through RRCSetup or RRCReconfiguration +* NTN + - Support downlinkHARQ-FeedbackDisabled-r17 + - Support for 32 PDSCH and PUSCH HARQ processes + - Consider ntn-Config-r17.cellSpecificKoffset-r17 in scheduling ## UE RLC @@ -399,25 +445,41 @@ These modes of operation are supported: * Integration of RRC messages and procedures supporting UE 5G SA connection according to 38.331 Rel.16 - RRCSetupRequest/RRCSetup/RRCSetupComplete + - RRCReject + - RRCRelease/ RRC going to IDLE - RRC Uplink/Downlink Information transfer carrying NAS messages transparently - RRC Reconfiguration/Reconfiguration complete + - RRCSetup fallback (after reestablishment) - RRCReestablishmentRequest/RRC Reestablishment/Reestablishment complete - Support for master cell group configuration - Reception of UECapabilityEnquiry, encoding and transmission of UECapability +* NTN according to 38.331 Rel.17 + - Reception of ntn-Config-r17 from SIB19 or reconfigurationWithSync + - Handling of ntn-UlSyncValidityDuration-r17 in SIB19 * Interface with PDCP: configuration, DCCH and CCCH message handling * Interface with RLC and MAC for configuration -## UE NAS +## UE 5G NAS -* Transfer of NAS messages between the AMF and the UE supporting the UE registration with the core network and the PDU session establishment according to 24.501 Rel.16 +* Transfer of NAS messages between the AMF and the UE supporting the UE registration with the core network and the PDU session establishment according to 24.501 Rel.16 +* 5GMM (5G Mobility Management) messages: + - Service Request/Accept/Reject (enc/dec library only) - Identity Request/Response - Authentication Request/Response - Security Mode Command/Complete - Registration Request/Accept/Complete + - Deregistration Request (UE originating) + - Uplink NAS Transport +* 5GSM (5G Session Management) messages: - PDU Session Establishment Request/Accept - - NAS configuration and basic interfacing with RRC - +* Security Features: + - NAS message integrity protection and ciphering + - Security context establishment and management +* Integration: + - NAS configuration and interfacing with RRC + - Integration with SDAP for user plane data transfer +For detailed implementation status, encoding/decoding support, and unit test coverage, see [5G NAS Implementation Documentation](5Gnas.md). # OpenAirInterface 4G LTE eNB Feature Set # diff --git a/doc/MAC/mac-usage.md b/doc/MAC/mac-usage.md index f4583b7a23..54a30cdd5f 100644 --- a/doc/MAC/mac-usage.md +++ b/doc/MAC/mac-usage.md @@ -257,7 +257,7 @@ configuration](../RRC/rrc-usage.md) as well for SIB configuration. * `do_CSIRS` (default 0): flag whether to use channel-state information reference signal (CSI-RS) * `do_SRS` (default 0): flag whether to use sounding reference signal (SRS) -* `do_SINR` (default 0): flag whether to enable CSI reporting of SSB-SINR (introduced in rel16) +* `CSI_report_type` (default `ssb_rsrp`): parameter to enable different CSI reporting (options: `ssb_rsrp`, `ssb_sinr` and `cri_rsrp`) Default setting of CSI reporting quantity is SSB-RSRP. * `min_rxtxtime` (default 2): minimum feedback time for UE to respond to transmissions (k1 and k2 in 3GPP spec) @@ -281,14 +281,17 @@ configuration](../RRC/rrc-usage.md) as well for SIB configuration. - `du_sibs` (default `[]`): list of SIBs to transmit in the cell. Currently, SIB19 (for NTN) is supported. -| DL MIMO |`do_CSIRS`|`do_SINR`| CSI report Quantity | -| ---------------------------- | -------- | ------- | --------------------------------------------------| -| OFF (pdsch_AntennaPorts = 1) | 0 | 0 | SSB-RSRP | -| OFF (pdsch_AntennaPorts = 1) | 0 | 1 | SSB-SINR | -| OFF (pdsch_AntennaPorts = 1) | 1 | 0 | CSI-Reference signal RSRP | -| OFF (pdsch_AntennaPorts = 1) | 1 | 1 | CSI-Reference signal SINR (not supported yet) | -| ON (pdsch_AntennaPorts > 1) | 1 | 0 | cri-RI-PMI-CQI | +| DL MIMO |`do_CSIRS`|`CSI_report_type`| CSI report Quantity | +| ------------------------------ | -------- | --------------- | --------------------------------------------------| +| any | any | `ssb_rsrp` | SSB-RSRP | +| any | 0 | `cri_rsrp` | SSB-RSRP (no CSI-RS configured) | +| any | 1 | `cri_rsrp` | CRI-RSRP | +| any | any | `ssb_sinr` | SSB-SINR | +| ON (`pdsch_AntennaPorts` > 1) | 1 | any | cri-RI-PMI-CQI | + +Note that activating `cri-RI-PMI-CQI` will result in that report to be produced +in addition to either `SSB-SINR`, `SSB-RSRP` or `CRI-RSRP`. DL-MIMO is configured using following parameters: `pdsch_AntennaPorts_XP` , `pdsch_AntennaPorts_N1` , `pdsch_AntennaPorts_N2`, `maxMIMO_layers` (see also [`RUNMODEM.md`](../RUNMODEM.md)) diff --git a/doc/SW_archi.md b/doc/SW_archi.md index 9c3736ac2a..c47a3cbc91 100644 --- a/doc/SW_archi.md +++ b/doc/SW_archi.md @@ -325,7 +325,7 @@ The PDCP implementation is secured by a general mutex, akin to the design of the Initialization of the PDCP layer follows a structure similar to that of the RLC layer. The function `nr_pdcp_layer_init()` initializes PDCP, while a second initialization function, `pdcp_module_init()`, must also be invoked. -To manage UE connections, `nr_pdcp_add_srbs()` is employed for adding UE SRBs in PDCP, while `nr_pdcp_remove_UE()` is used for their removal. Similarly, `nr_pdcp_add_drbs()` adds UE DRBs in PDCP, with `nr_pdcp_remove_UE()` handling their removal. +To manage UE connections, `nr_pdcp_add_srbs()` is employed for adding UE SRBs in PDCP, while `nr_pdcp_remove_UE()` is used for their removal. Similarly, `nr_pdcp_add_drb()` adds UE DRB in PDCP, with `nr_pdcp_remove_UE()` handling their removal. ## PDCP Tx flow diff --git a/executables/lte-softmodem.c b/executables/lte-softmodem.c index 77fdb21eb4..80b532607e 100644 --- a/executables/lte-softmodem.c +++ b/executables/lte-softmodem.c @@ -151,7 +151,6 @@ double cpuf; bool sdap_data_req(protocol_ctxt_t *ctxt_p, const ue_id_t ue_id, const srb_flag_t srb_flag, - const rb_id_t rb_id, const mui_t mui, const confirm_t confirm, const sdu_size_t sdu_buffer_size, diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 505adf825c..16ad366a0e 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -114,7 +114,10 @@ static void tx_func(processingData_L1tx_t *info) pushNotifiedFIFO(&gNB->resp_L1, res); int tx_slot_type = nr_slot_select(cfg, frame_tx, slot_tx); - if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT || get_softmodem_params()->continuous_tx || IS_SOFTMODEM_RFSIM) { + // TODO check for analog_beam_list is a workaround while no beam API for beam + // selection is implemented + if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT || get_softmodem_params()->continuous_tx || IS_SOFTMODEM_RFSIM + || cfg->analog_beamforming_ve.analog_beam_list) { start_meas(&info->gNB->phy_proc_tx); phy_procedures_gNB_TX(info, frame_tx, slot_tx, 1); @@ -190,17 +193,17 @@ static void rx_func(processingData_L1_t *info) //WA: comment rotation in tx/rx if (gNB->phase_comp) { //apply the rx signal rotation here - int soffset = (slot_rx & 3) * gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size; + int soffset = (slot_rx % RU_RX_SLOT_DEPTH) * gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size; for (int bb = 0; bb < gNB->common_vars.num_beams_period; bb++) { for (int aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) { - apply_nr_rotation_RX(&gNB->frame_parms, - gNB->common_vars.rxdataF[bb][aa], - gNB->frame_parms.symbol_rotation[1], - slot_rx, - gNB->frame_parms.N_RB_UL, - soffset, - 0, - gNB->frame_parms.Ncp == EXTENDED ? 12 : 14); + const uint max_symb = (gNB->frame_parms.Ncp == EXTENDED) ? 12 : 14; + for (int sym = 0; sym < max_symb; sym++) + apply_nr_rotation_symbol_RX(&gNB->frame_parms, + gNB->common_vars.rxdataF[bb][aa] + soffset + sym * gNB->frame_parms.ofdm_symbol_size, + gNB->frame_parms.symbol_rotation[1], + gNB->frame_parms.N_RB_UL, + slot_rx, + sym); } } } diff --git a/executables/nr-ue.c b/executables/nr-ue.c index f789484465..e7132e15cf 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -564,7 +564,8 @@ static int UE_dl_preprocessing(PHY_VARS_NR_UE *UE, UE->if_inst->dl_indication(&dl_indication); } - sampleShift = pbch_pdcch_processing(UE, proc, phy_data); + sampleShift = pbch_processing(UE, proc, phy_data); + pdcch_processing(UE, proc, phy_data); if (phy_data->dlsch[0].active && (phy_data->dlsch[0].rnti_type == TYPE_C_RNTI_ || phy_data->dlsch[0].rnti_type == TYPE_RA_RNTI_)) { // indicate to tx thread to wait for DLSCH decoding diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index dc52f1de2a..faebaffc6f 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -73,6 +73,7 @@ typedef struct { /// frequency_domain_resource; uint8_t frequency_domain_resource[6]; uint8_t StartSymbolIndex; + uint16_t StartSymbolBitmap; uint8_t duration; uint8_t CceRegMappingType; // interleaved or noninterleaved uint8_t RegBundleSize; // valid if CCE to REG mapping type is interleaved type diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 60bc63dac4..778903be91 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -175,8 +175,10 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB) if (cfg->analog_beamforming_ve.analog_bf_vendor_ext.value) { common_vars->beam_id = (int **)malloc16(common_vars->num_beams_period * sizeof(int*)); - for (int i = 0; i < common_vars->num_beams_period; i++) - common_vars->beam_id[i] = (int*)malloc16_clear(fp->symbols_per_slot * fp->slots_per_frame * sizeof(int)); + for (int i = 0; i < common_vars->num_beams_period; i++) { + common_vars->beam_id[i] = (int*)malloc16(fp->symbols_per_slot * fp->slots_per_frame * sizeof(int)); + memset(common_vars->beam_id[i], -1, fp->symbols_per_slot * fp->slots_per_frame * sizeof(int)); + } } common_vars->txdataF = (c16_t ***)malloc16(common_vars->num_beams_period * sizeof(c16_t**)); for (int i = 0; i < common_vars->num_beams_period; i++) { diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c index a0766c348f..ca753938a6 100644 --- a/openair1/PHY/INIT/nr_init_ru.c +++ b/openair1/PHY/INIT/nr_init_ru.c @@ -53,8 +53,10 @@ void nr_phy_init_RU(RU_t *ru) int nb_rx_streams = ru->nb_rx * ru->num_beams_period; LOG_I(NR_PHY, "nb_tx_streams %d, nb_rx_streams %d, num_Beams_period %d\n", nb_tx_streams, nb_rx_streams, ru->num_beams_period); ru->common.beam_id = malloc16_clear(ru->num_beams_period * sizeof(int*)); - for(int i = 0; i < ru->num_beams_period; i++) - ru->common.beam_id[i] = malloc16_clear(fp->symbols_per_slot * fp->slots_per_frame * sizeof(int)); + for(int i = 0; i < ru->num_beams_period; i++) { + ru->common.beam_id[i] = malloc16(fp->symbols_per_slot * fp->slots_per_frame * sizeof(int)); + memset(ru->common.beam_id[i], -1, fp->symbols_per_slot * fp->slots_per_frame * sizeof(int)); + } if (ru->if_south <= REMOTE_IF5) { // this means REMOTE_IF5 or LOCAL_RF, so allocate memory for time-domain signals // Time-domain signals diff --git a/openair1/PHY/MODULATION/nr_modulation.h b/openair1/PHY/MODULATION/nr_modulation.h index 64886a2809..996a66b343 100644 --- a/openair1/PHY/MODULATION/nr_modulation.h +++ b/openair1/PHY/MODULATION/nr_modulation.h @@ -117,14 +117,12 @@ void init_symbol_rotation(NR_DL_FRAME_PARMS *fp); void init_timeshift_rotation(NR_DL_FRAME_PARMS *fp); -void apply_nr_rotation_RX(const NR_DL_FRAME_PARMS *frame_parms, - c16_t *rxdataF, - const c16_t *rot, - int slot, - int nb_rb, - int soffset, - int first_symbol, - int nsymb); +void apply_nr_rotation_symbol_RX(const NR_DL_FRAME_PARMS *frame_parms, + c16_t *rxdataF, + const c16_t *rot, + int nb_rb, + int slot, + int symbol); /*! \brief Perform NR precoding. TS 38.211 V15.4.0 subclause 6.3.1.5 @param[in] datatx_F_precoding, Pointer to n_layers*re data array diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index cad3f92c33..50e19d8563 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -28,6 +28,36 @@ #include "PHY/nr_phy_common/inc/nr_phy_common.h" #include +/* rxdataF should be 16 bytes aligned */ +void nr_symbol_fep(const NR_DL_FRAME_PARMS *frame_parms, + const int slot, + const unsigned char symbol, + const int link_type, + c16_t *rxdata[frame_parms->nb_antennas_rx], + c16_t *rxdataF[frame_parms->nb_antennas_rx], + time_stats_t* dft_stats) +{ + AssertFatal(symbol < frame_parms->symbols_per_slot, + "slot_fep: symbol must be between 0 and %d\n", + frame_parms->symbols_per_slot - 1); + AssertFatal(slot < frame_parms->slots_per_frame, "slot_fep: Ns must be between 0 and %d\n", frame_parms->slots_per_frame - 1); + + dft_size_idx_t dftsize = get_dft(frame_parms->ofdm_symbol_size); + for (unsigned char aa = 0; aa < frame_parms->nb_antennas_rx; aa++) { + if (dft_stats) start_meas(dft_stats); + dft(dftsize, (int16_t *)rxdata[aa], (int16_t *)rxdataF[aa], 1); + if (dft_stats) stop_meas(dft_stats); + + const bool is_sl = (link_type == link_type_sl); + apply_nr_rotation_symbol_RX(frame_parms, + rxdataF[aa], + frame_parms->symbol_rotation[link_type], + is_sl ? frame_parms->N_RB_SL : frame_parms->N_RB_DL, + slot, + symbol); + } +} + int nr_slot_fep(PHY_VARS_NR_UE *ue, const NR_DL_FRAME_PARMS *frame_parms, unsigned int slot, @@ -37,35 +67,23 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, uint32_t sample_offset, c16_t **rxdata) { - AssertFatal(symbol < frame_parms->symbols_per_slot, "slot_fep: symbol must be between 0 and %d\n", frame_parms->symbols_per_slot-1); + AssertFatal(symbol < frame_parms->symbols_per_slot, + "slot_fep: symbol must be between 0 and %d\n", + frame_parms->symbols_per_slot - 1); AssertFatal(slot < frame_parms->slots_per_frame, "slot_fep: Ns must be between 0 and %d\n", frame_parms->slots_per_frame - 1); - bool is_sl = (linktype == link_type_sl) ? true : false; + bool is_sl = (linktype == link_type_sl); bool is_synchronized = (ue) ? ue->is_synchronized : false; - unsigned int nb_prefix_samples; - unsigned int nb_prefix_samples0; + unsigned int nb_prefix_samples = frame_parms->nb_prefix_samples; + unsigned int nb_prefix_samples0 = (is_synchronized || is_sl) ? frame_parms->nb_prefix_samples0 : nb_prefix_samples; + // For Sidelink 16 frames worth of samples is processed to find SSB, for 5G-NR 2. - unsigned int total_samples = (is_sl) ? 16 * frame_parms->samples_per_frame : 2 * frame_parms->samples_per_frame; - - int N_RB = (is_sl) ? frame_parms->N_RB_SL : frame_parms->N_RB_DL; - - if (is_synchronized || is_sl) { - nb_prefix_samples = frame_parms->nb_prefix_samples; - nb_prefix_samples0 = frame_parms->nb_prefix_samples0; - } else { - nb_prefix_samples = frame_parms->nb_prefix_samples; - nb_prefix_samples0 = frame_parms->nb_prefix_samples; - AssertFatal(slot == 0, "Slot should be 0\n"); - } - - dft_size_idx_t dftsize = get_dft(frame_parms->ofdm_symbol_size); - // This is for misalignment issues - c16_t tmp_dft_in[frame_parms->ofdm_symbol_size] __attribute__ ((aligned (32))); + const unsigned int total_samples = (is_sl) ? 16 * frame_parms->samples_per_frame : 2 * frame_parms->samples_per_frame; unsigned int rx_offset = frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0); - unsigned int abs_symbol = slot * frame_parms->symbols_per_slot + symbol; + const unsigned int abs_symbol = slot * frame_parms->symbols_per_slot + symbol; for (int idx_symb = slot * frame_parms->symbols_per_slot; idx_symb <= abs_symbol; idx_symb++) - rx_offset += (idx_symb%(0x7<numerology_index)) ? nb_prefix_samples : nb_prefix_samples0; + rx_offset += (idx_symb % (0x7 << frame_parms->numerology_index)) ? nb_prefix_samples : nb_prefix_samples0; rx_offset += frame_parms->ofdm_symbol_size * symbol; rx_offset += sample_offset; @@ -73,48 +91,47 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, // use OFDM symbol from within 1/8th of the CP to avoid ISI rx_offset -= (nb_prefix_samples / frame_parms->ofdm_offset_divisor); - rx_offset %= total_samples; - - for (unsigned char aa=0; aanb_antennas_rx; aa++) { - c16_t *rxdata_ptr = &rxdata[aa][rx_offset]; + LOG_D(PHY, + "slot_fep: slot %d, symbol %d, nb_prefix_samples %u, nb_prefix_samples0 %u, rx_offset %u energy %d\n", + slot, + symbol, + nb_prefix_samples, + nb_prefix_samples0, + rx_offset, + dB_fixed(signal_energy((int32_t *)&rxdata[0][rx_offset], frame_parms->ofdm_symbol_size))); + c16_t tmp_dft_in[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size] __attribute__((aligned(32))); + c16_t *rxdata_symb_ptr[frame_parms->nb_antennas_rx]; + c16_t *rxdataF_symb_ptr[frame_parms->nb_antennas_rx]; + for (unsigned char aa = 0; aa < frame_parms->nb_antennas_rx; aa++) { + rxdataF_symb_ptr[aa] = &rxdataF[aa][frame_parms->ofdm_symbol_size * symbol]; // This happens only during initial sync if (rx_offset + frame_parms->ofdm_symbol_size > total_samples) { - // rxdata is 2 frames len // we have to wrap on the end - - memcpy((void *)&tmp_dft_in[0], (void *)&rxdata[aa][rx_offset], (total_samples - rx_offset) * sizeof(int32_t)); - memcpy((void *)&tmp_dft_in[total_samples - rx_offset], - (void *)&rxdata[aa][0], + memcpy(&tmp_dft_in[aa][0], &rxdata[aa][rx_offset], (total_samples - rx_offset) * sizeof(int32_t)); + memcpy(&tmp_dft_in[aa][total_samples - rx_offset], + &rxdata[aa][0], (frame_parms->ofdm_symbol_size - (total_samples - rx_offset)) * sizeof(int32_t)); - rxdata_ptr = tmp_dft_in; - - } else if ((rx_offset & 7) != 0) { // if input to dft is not 256-bit aligned - memcpy((void *)&tmp_dft_in[0], (void *)&rxdata[aa][rx_offset], frame_parms->ofdm_symbol_size * sizeof(int32_t)); - rxdata_ptr = tmp_dft_in; + rxdata_symb_ptr[aa] = tmp_dft_in[aa]; + } else { + rxdata_symb_ptr[aa] = &rxdata[aa][rx_offset]; } if (ue && ue->cont_fo_comp) { start_meas_nr_ue_phy(ue, RX_FO_COMPENSATION_STATS); - nr_fo_compensation(ue->freq_offset, frame_parms->samples_per_subframe, rx_offset, rxdata_ptr, tmp_dft_in, frame_parms->ofdm_symbol_size); - rxdata_ptr = tmp_dft_in; + nr_fo_compensation(ue->freq_offset, + frame_parms->samples_per_subframe, + rx_offset, + rxdata_symb_ptr[aa], + tmp_dft_in[aa], + frame_parms->ofdm_symbol_size); stop_meas_nr_ue_phy(ue, RX_FO_COMPENSATION_STATS); + rxdata_symb_ptr[aa] = tmp_dft_in[aa]; } - - if (ue) - start_meas_nr_ue_phy(ue, RX_DFT_STATS); - - dft(dftsize, - (int16_t *)rxdata_ptr, - (int16_t *)&rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], - 1); - - if (ue) - stop_meas_nr_ue_phy(ue, RX_DFT_STATS); - - apply_nr_rotation_RX(frame_parms, rxdataF[aa], frame_parms->symbol_rotation[linktype], slot, N_RB, 0, symbol, 1); } - + time_stats_t* dft_stats = NULL; + if (ue) dft_stats = &ue->phy_cpu_stats.cpu_time_stats[RX_DFT_STATS]; + nr_symbol_fep(frame_parms, slot, symbol, linktype, rxdata_symb_ptr, rxdataF_symb_ptr, dft_stats); return 0; } @@ -177,54 +194,46 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms, return 0; } -void apply_nr_rotation_RX(const NR_DL_FRAME_PARMS *frame_parms, - c16_t *rxdataF, - const c16_t *rot, - int slot, - int nb_rb, - int soffset, - int first_symbol, - int nsymb) +void apply_nr_rotation_symbol_RX(const NR_DL_FRAME_PARMS *frame_parms, + c16_t *rxdataF, + const c16_t *rot, + int nb_rb, + int slot, + int symbol) { - AssertFatal(first_symbol + nsymb <= NR_NUMBER_OF_SYMBOLS_PER_SLOT, - "First symbol %d and number of symbol %d not compatible with number of symbols in a slot %d\n", - first_symbol, nsymb, NR_NUMBER_OF_SYMBOLS_PER_SLOT); - int symb_offset = (slot % frame_parms->slots_per_subframe) * frame_parms->symbols_per_slot; + const int symb_offset = (slot % frame_parms->slots_per_subframe) * frame_parms->symbols_per_slot; - for (int symbol = first_symbol; symbol < first_symbol + nsymb; symbol++) { - - c16_t rot2 = rot[symbol + symb_offset]; - rot2.i = -rot2.i; - LOG_D(PHY,"slot %d, symb_offset %d rotating by %d.%d\n", slot, symb_offset, rot2.r, rot2.i); - const c16_t *shift_rot = frame_parms->timeshift_symbol_rotation; - c16_t *this_symbol = &rxdataF[soffset + (frame_parms->ofdm_symbol_size * symbol)]; + c16_t rot2 = rot[symbol + symb_offset]; + rot2.i = -rot2.i; + LOG_D(PHY,"slot %d, symb_offset %d rotating by %d.%d\n", slot, symb_offset, rot2.r, rot2.i); + const c16_t *shift_rot = frame_parms->timeshift_symbol_rotation; + c16_t *this_symbol = rxdataF; - if (nb_rb & 1) { - rotate_cpx_vector(this_symbol, &rot2, this_symbol, - (nb_rb + 1) * 6, 15); - rotate_cpx_vector(this_symbol + frame_parms->first_carrier_offset - 6, - &rot2, - this_symbol + frame_parms->first_carrier_offset - 6, - (nb_rb + 1) * 6, 15); - mult_cpx_vector(this_symbol, shift_rot, this_symbol, (nb_rb + 1) * 6, 15); - mult_cpx_vector(this_symbol + frame_parms->first_carrier_offset - 6, - shift_rot + frame_parms->first_carrier_offset - 6, + if (nb_rb & 1) { + rotate_cpx_vector(this_symbol, &rot2, this_symbol, (nb_rb + 1) * 6, 15); + rotate_cpx_vector(this_symbol + frame_parms->first_carrier_offset - 6, + &rot2, this_symbol + frame_parms->first_carrier_offset - 6, (nb_rb + 1) * 6, 15); - } else { - rotate_cpx_vector(this_symbol, &rot2, this_symbol, - nb_rb * 6, 15); - rotate_cpx_vector(this_symbol + frame_parms->first_carrier_offset, - &rot2, - this_symbol + frame_parms->first_carrier_offset, - nb_rb * 6, 15); - mult_cpx_vector(this_symbol, shift_rot, this_symbol, nb_rb * 6, 15); - mult_cpx_vector(this_symbol + frame_parms->first_carrier_offset, - shift_rot + frame_parms->first_carrier_offset, + mult_cpx_vector(this_symbol, shift_rot, this_symbol, (nb_rb + 1) * 6, 15); + mult_cpx_vector(this_symbol + frame_parms->first_carrier_offset - 6, + shift_rot + frame_parms->first_carrier_offset - 6, + this_symbol + frame_parms->first_carrier_offset - 6, + (nb_rb + 1) * 6, + 15); + } else { + rotate_cpx_vector(this_symbol, &rot2, this_symbol, nb_rb * 6, 15); + rotate_cpx_vector(this_symbol + frame_parms->first_carrier_offset, + &rot2, this_symbol + frame_parms->first_carrier_offset, nb_rb * 6, 15); - } + mult_cpx_vector(this_symbol, shift_rot, this_symbol, nb_rb * 6, 15); + mult_cpx_vector(this_symbol + frame_parms->first_carrier_offset, + shift_rot + frame_parms->first_carrier_offset, + this_symbol + frame_parms->first_carrier_offset, + nb_rb * 6, + 15); } } diff --git a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c index 2e6e4a54a6..a1fde35b00 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c +++ b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c @@ -136,7 +136,7 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_sy // TODO modify the measurements to take into account concurrent beams for (int s = first_symb; s < first_symb + num_symb; s++) { - int offset0 = ((slot&3)*frame_parms->symbols_per_slot + s) * frame_parms->ofdm_symbol_size; + int offset0 = ((slot % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot + s) * frame_parms->ofdm_symbol_size; for (int rb = 0; rb < frame_parms->N_RB_UL; rb++) { if ((rb_mask_ul[s][rb >> 5] & (1U << (rb & 31))) == 0 && // check that rb was not used in this subframe !(I0_SKIP_DC && rb == frame_parms->N_RB_UL >> 1)) { // skip middle PRB because of artificial noise possibly created by FFT @@ -188,74 +188,3 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_sy } } } - -// Scope: This function computes the UL SNR from the UL channel estimates -// -// Todo: -// - averaging IIR filter for RX power and noise -void nr_gnb_measurements(PHY_VARS_gNB *gNB, - NR_gNB_ULSCH_t *ulsch, - NR_gNB_PUSCH *pusch_vars, - unsigned char symbol, - uint8_t nrOfLayers) -{ - uint32_t rx_power_tot = 0; - unsigned short rx_power_avg_dB; - unsigned short rx_power_tot_dB; - RU_t *ru = gNB->RU_list[0]; - double rx_gain, rx_gain_offset; - if (ru && ru->rfdevice.openair0_cfg) { - rx_gain = ru->rfdevice.openair0_cfg->rx_gain[0]; - rx_gain_offset = ru->rfdevice.openair0_cfg->rx_gain_offset[0]; - } else if (ru && ru->ifdevice.openair0_cfg) { - rx_gain = ru->ifdevice.openair0_cfg->rx_gain[0]; - rx_gain_offset = ru->ifdevice.openair0_cfg->rx_gain_offset[0]; - } else { - LOG_W(NR_PHY, "no device for rx gain, take arbitrary gain = 1)\n"); - rx_gain = 1; - rx_gain_offset = 0; - } - PHY_MEASUREMENTS_gNB *meas = &gNB->measurements; - NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; - int ch_offset = fp->ofdm_symbol_size * symbol; - int N_RB_UL = ulsch->harq_process->ulsch_pdu.rb_size; - ulsch_measurements_gNB *ulsch_measurements = &ulsch->ulsch_measurements; - - int rx_power[fp->nb_antennas_rx]; - int rx_spatial_power[nrOfLayers][fp->nb_antennas_rx]; - for (int aarx = 0; aarx < fp->nb_antennas_rx; aarx++){ - rx_power[aarx] = 0; - - for (int aatx = 0; aatx < nrOfLayers; aatx++){ - rx_spatial_power[aatx][aarx] = - (signal_energy_nodc((c16_t*)&pusch_vars->ul_ch_estimates[aatx * fp->nb_antennas_rx + aarx][ch_offset], - N_RB_UL * NR_NB_SC_PER_RB)); - - if (rx_spatial_power[aatx][aarx] < 0) { - rx_spatial_power[aatx][aarx] = 0; - } - - rx_power[aarx] += rx_spatial_power[aatx][aarx]; - } - LOG_D(PHY, "[RNTI %04x] RX power in antenna %d = %d\n", ulsch->rnti, aarx, rx_power[aarx]); - - rx_power_tot += rx_power[aarx]; - } - - rx_power_tot_dB = (unsigned short)dB_fixed(rx_power_tot); - rx_power_avg_dB = rx_power_tot_dB; - - ulsch_measurements->wideband_cqi_tot = dB_fixed2(rx_power_tot, meas->n0_power_tot); - ulsch_measurements->rx_rssi_dBm = - rx_power_avg_dB + 30 - SQ15_SQUARED_NORM_FACTOR_DB - (rx_gain - rx_gain_offset) - dB_fixed(fp->ofdm_symbol_size); - - LOG_D(PHY, - "[RNTI %04x] RSSI %d dBm/RE, RSSI (digital) %d dB (N_RB_UL %d), WBand CQI tot %d dB, N0 Power tot %d, RX Power tot %d\n", - ulsch->rnti, - ulsch_measurements->rx_rssi_dBm, - rx_power_avg_dB, - N_RB_UL, - ulsch_measurements->wideband_cqi_tot, - meas->n0_power_tot, - rx_power_tot); -} diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 93d7feebe0..d73a315354 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -111,7 +111,7 @@ static void nr_pusch_antenna_processing(void *arg) c16_t **ul_ch_estimates = (c16_t **)pusch_vars->ul_ch_estimates; NR_DL_FRAME_PARMS *frame_parms = rdata->frame_parms; const int symbolSize = frame_parms->ofdm_symbol_size; - const int slot_offset = (Ns & 3) * frame_parms->symbols_per_slot * symbolSize; + const int slot_offset = (Ns % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot * symbolSize; const int delta = get_delta(p, pusch_pdu->dmrs_config_type); const int symbol_offset = symbolSize * symbol; const int k0 = bwp_start_subcarrier; diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h index 04377db1b8..7e0a2a97bd 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h @@ -59,12 +59,6 @@ void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB); void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_symb, uint32_t rb_mask_ul[14][9]); -void nr_gnb_measurements(PHY_VARS_gNB *gNB, - NR_gNB_ULSCH_t *ulsch, - NR_gNB_PUSCH *pusch_vars, - unsigned char symbol, - uint8_t nrOfLayers); - int nr_est_timing_advance_srs(const NR_DL_FRAME_PARMS *frame_parms, const c16_t srs_estimated_channel_time[][frame_parms->ofdm_symbol_size]); diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c index 7fd703ea30..e25d9700da 100644 --- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c +++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c @@ -150,9 +150,7 @@ int nr_pdsch_dmrs_rx(const PHY_VARS_NR_UE *ue, return(0); } -int nr_pdcch_dmrs_rx(const PHY_VARS_NR_UE *ue, - unsigned int Ns, - const unsigned int *nr_gold_pdcch, +int nr_pdcch_dmrs_rx(const unsigned int *nr_gold_pdcch, c16_t *output, unsigned short p, unsigned short nb_rb_coreset) diff --git a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h index 1d2d4b87ae..414dae9976 100644 --- a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h +++ b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h @@ -35,9 +35,7 @@ void nr_pbch_dmrs_rx(int dmrss, const unsigned int *nr_gold_pbch, c16_t *output, /*!\brief This function generates the NR Gold sequence (38-211, Sec 5.2.1) for the PDCCH DMRS. @param PHY_VARS_NR_UE* ue structure provides configuration, frame parameters and the pointers to the 32 bits sequence storage tables */ -int nr_pdcch_dmrs_rx(const PHY_VARS_NR_UE *ue, - unsigned int Ns, - const unsigned int *nr_gold_pdcch, +int nr_pdcch_dmrs_rx(const unsigned int *nr_gold_pdcch, c16_t *output, unsigned short p, unsigned short nb_rb_corset); diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index 28f3e2cc67..316a16c459 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -1188,12 +1188,7 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB, pusch_ch_est_dmrs_pos_slot_mem); nvar += nvar_tmp; } - // measure the SNR from the channel estimation - nr_gnb_measurements(gNB, - &gNB->ulsch[ulsch_id], - pusch_vars, - symbol, - rel15_ul->nrOfLayers); + allocCast2D(n0_subband_power, unsigned int, gNB->measurements.n0_subband_power, @@ -1212,7 +1207,7 @@ int nr_rx_pusch_tp(PHY_VARS_gNB *gNB, int end_sc = (start_sc + rel15_ul->rb_size * NR_NB_SC_PER_RB - 1) % frame_parms->ofdm_symbol_size; for (int s = rel15_ul->start_symbol_index; s < (rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols); s++) { - int offset0 = ((slot & 3) * frame_parms->symbols_per_slot + s) * frame_parms->ofdm_symbol_size; + int offset0 = ((slot % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot + s) * frame_parms->ofdm_symbol_size; int offset = offset0 + (frame_parms->first_carrier_offset + start_sc) % frame_parms->ofdm_symbol_size; c16_t *ul_ch = &gNB->common_vars.rxdataF[beam_nb][aarx][offset]; if (end_sc < start_sc) { diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index ddf16a0541..2a3987e755 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -161,7 +161,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, nfapi_nr_pucch_pdu_t *pucch_pdu) { NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; - int soffset = (slot & 3) * frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size; + int soffset = (slot % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size; AssertFatal(pucch_pdu->bit_len_harq > 0 || pucch_pdu->sr_flag > 0, "Either bit_len_harq (%d) or sr_flag (%d) must be > 0\n", diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index 296606a426..6a49a17608 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -805,17 +805,12 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, uint16_t BWPStart, int32_t pdcch_est_size, c16_t pdcch_dl_ch_estimates[][pdcch_est_size], - c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) + c16_t rxdataF[ue->frame_parms.nb_antennas_rx][ue->frame_parms.ofdm_symbol_size]) { int slot = proc->nr_slot_rx; unsigned char aarx; unsigned short k; unsigned int pilot_cnt; - int ch_offset,symbol_offset; - - ch_offset = ue->frame_parms.ofdm_symbol_size*symbol; - - symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol; int nb_rb_coreset=0; int coreset_start_rb=0; @@ -830,8 +825,7 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, unsigned short coreset_start_subcarrier = first_carrier_offset+(BWPStart + coreset_start_rb)*12; #ifdef DEBUG_PDCCH - printf("PDCCH Channel Estimation : ch_offset %d, OFDM size %d, Ncp=%d, slot=%d, symbol %d\n", - ch_offset, + printf("PDCCH Channel Estimation : OFDM size %d, Ncp=%d, slot=%d, symbol %d\n", ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp, slot, @@ -852,14 +846,14 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, c16_t pilot[(nb_rb_coreset + dmrs_ref) * 3] __attribute__((aligned(16))); // Note: pilot returned by the following function is already the complex conjugate of the transmitted DMRS const uint32_t *gold = nr_gold_pdcch(ue->frame_parms.N_RB_DL, ue->frame_parms.symbols_per_slot, scrambling_id, slot, symbol); - nr_pdcch_dmrs_rx(ue, slot, gold, pilot, 2000, (nb_rb_coreset + dmrs_ref)); + nr_pdcch_dmrs_rx(gold, pilot, 2000, (nb_rb_coreset + dmrs_ref)); for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { k = coreset_start_subcarrier; c16_t *pil = &pilot[dmrs_ref * 3]; - c16_t *rxF = &rxdataF[aarx][symbol_offset + k + 1]; - c16_t *dl_ch = &pdcch_dl_ch_estimates[aarx][ch_offset]; + c16_t *rxF = &rxdataF[aarx][k + 1]; + c16_t *dl_ch = &pdcch_dl_ch_estimates[aarx][0]; memset(dl_ch, 0, sizeof(c16_t) * ue->frame_parms.ofdm_symbol_size); @@ -879,29 +873,29 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, if (k >= ue->frame_parms.ofdm_symbol_size) { k -= ue->frame_parms.ofdm_symbol_size; - rxF = &rxdataF[aarx][(symbol_offset + k + 1)]; + rxF = &rxdataF[aarx][k + 1]; } multadd_real_vector_complex_scalar(fm, c16mulShift(*pil++, *rxF, 15), dl_ch, 16); k = (k + 4) % ue->frame_parms.ofdm_symbol_size; - rxF = (c16_t *)&rxdataF[aarx][(symbol_offset + k + 1)]; + rxF = (c16_t *)&rxdataF[aarx][k + 1)]; multadd_real_vector_complex_scalar(fr, c16mulShift(*pil++, *rxF, 15), dl_ch, 16); dl_ch += 12; k = (k + 4) % ue->frame_parms.ofdm_symbol_size; - rxF = (c16_t *)&rxdataF[aarx][(symbol_offset + k + 1)]; + rxF = (c16_t *)&rxdataF[aarx][k + 1]; for (pilot_cnt=3; pilot_cnt<(3*nb_rb_coreset); pilot_cnt += 3) { multadd_real_vector_complex_scalar(fl, c16mulShift(*pil++, *rxF, 15), dl_ch, 16); k = (k + 4) % ue->frame_parms.ofdm_symbol_size; - rxF = (c16_t *)&rxdataF[aarx][(symbol_offset + k + 1)]; + rxF = (c16_t *)&rxdataF[aarx][k + 1]; multadd_real_vector_complex_scalar(fm, c16mulShift(*pil++, *rxF, 15), dl_ch, 16); k = (k + 4) % ue->frame_parms.ofdm_symbol_size; - rxF = (c16_t *)&rxdataF[aarx][(symbol_offset + k + 1)]; + rxF = (c16_t *)&rxdataF[aarx][k + 1]; multadd_real_vector_complex_scalar(fr, c16mulShift(*pil++, *rxF, 15), dl_ch, 16); dl_ch += 12; k = (k + 4) % ue->frame_parms.ofdm_symbol_size; - rxF = (c16_t *)&rxdataF[aarx][(symbol_offset + k + 1)]; + rxF = (c16_t *)&rxdataF[aarx][k + 1]; } #else //ELSE CH_INTERP c32_t ch_sum = {0, 0}; @@ -915,7 +909,7 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, ch_sum.r += ch.r; ch_sum.i += ch.i; k = (k + 4) % ue->frame_parms.ofdm_symbol_size; - rxF = (c16_t *)&rxdataF[aarx][(symbol_offset + k + 1)]; + rxF = (c16_t *)&rxdataF[aarx][k + 1]; if (pilot_cnt % 3 == 2) { ch.r = ch_sum.r / 3; diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h index 66339e25a2..85b8999118 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h @@ -52,7 +52,7 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, uint16_t BWPStart, int32_t pdcch_est_size, c16_t pdcch_dl_ch_estimates[][pdcch_est_size], - c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); + c16_t rxdataF[ue->frame_parms.nb_antennas_rx][ue->frame_parms.ofdm_symbol_size]); c32_t nr_pbch_dmrs_correlation(const NR_DL_FRAME_PARMS *fp, const UE_nr_rxtx_proc_t *proc, diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c index 36b8d8a673..7d6ab8e6f2 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c @@ -125,8 +125,9 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue, for (gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) { ue->measurements.rx_power_avg_dB[gNB_id] = dB_fixed( ue->measurements.rx_power_avg[gNB_id]); + ue->measurements.n0_power_avg_dB = dB_fixed(ue->measurements.n0_power_avg); ue->measurements.wideband_cqi_tot[gNB_id] = ue->measurements.rx_power_tot_dB[gNB_id] - ue->measurements.n0_power_tot_dB; - ue->measurements.wideband_cqi_avg[gNB_id] = ue->measurements.rx_power_avg_dB[gNB_id] - dB_fixed(ue->measurements.n0_power_avg); + ue->measurements.wideband_cqi_avg[gNB_id] = ue->measurements.rx_power_avg_dB[gNB_id] - ue->measurements.n0_power_avg_dB; ue->measurements.rx_rssi_dBm[gNB_id] = ue->measurements.rx_power_avg_dB[gNB_id] + 30 - SQ15_SQUARED_NORM_FACTOR_DB - ((int)ue->openair0_cfg[0].rx_gain[0] - (int)ue->openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(ue->frame_parms.ofdm_symbol_size); diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index 43b27e3932..9e48f52a03 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -41,6 +41,7 @@ #include "common/utils/nr/nr_common.h" #include #include "openair1/PHY/NR_REFSIG/nr_refsig_common.h" +#include "PHY/NR_UE_ESTIMATION/nr_estimation.h" #include "assertions.h" #include "T.h" @@ -72,10 +73,10 @@ #define RE_PER_RB_OUT_DMRS 9 static void nr_pdcch_demapping_deinterleaving(uint32_t coreset_nbr_rb, - c16_t llr[][coreset_nbr_rb * RE_PER_RB_OUT_DMRS], + c16_t *llr, c16_t *e_rx, uint8_t coreset_time_dur, - uint8_t reg_bundle_size_L, + uint8_t reg_bundle_size_L_in, uint8_t coreset_interleaver_size_R, uint8_t n_shift, uint8_t number_of_candidates, @@ -118,17 +119,11 @@ static void nr_pdcch_demapping_deinterleaving(uint32_t coreset_nbr_rb, | REG 0 (bundle 0) bundle 0 bundle 0 */ - - uint32_t coreset_C = 0; - int coreset_interleaved = 0; const int N_regs = coreset_nbr_rb * coreset_time_dur; - - if (reg_bundle_size_L != 0) { // interleaving will be done only if reg_bundle_size_L != 0 - coreset_interleaved = 1; - coreset_C = (uint32_t)(N_regs / (coreset_interleaver_size_R * reg_bundle_size_L)); - } else { - reg_bundle_size_L = 6; - } + /* interleaving will be done only if reg_bundle_size_L != 0 */ + const int coreset_C = (reg_bundle_size_L_in != 0) ? (uint32_t)(N_regs / (coreset_interleaver_size_R * reg_bundle_size_L_in)) : 0; + const int coreset_interleaved = (reg_bundle_size_L_in != 0) ? 1 : 0; + const int reg_bundle_size_L = (reg_bundle_size_L_in != 0) ? reg_bundle_size_L_in : 6; int B_rb = reg_bundle_size_L / coreset_time_dur; // nb of RBs occupied by each REG bundle int num_bundles_per_cce = 6 / reg_bundle_size_L; @@ -173,7 +168,7 @@ static void nr_pdcch_demapping_deinterleaving(uint32_t coreset_nbr_rb, for (int cce_count = 0; cce_count < L[c_id]; cce_count++) { for (int k = 0; k < NR_NB_REG_PER_CCE / reg_bundle_size_L; k++) { // loop over REG bundles int f = f_bundle_j_list_ord[c_id][k + NR_NB_REG_PER_CCE * cce_count / reg_bundle_size_L]; - c16_t *in = llr[symbol_idx] + f * B_rb * RE_PER_RB_OUT_DMRS; + c16_t *in = llr + (f * B_rb + symbol_idx * coreset_nbr_rb) * RE_PER_RB_OUT_DMRS; // loop over the RBs of the bundle memcpy(e_rx + RE_PER_RB_OUT_DMRS * rb_count, in, B_rb * RE_PER_RB_OUT_DMRS * sizeof(*e_rx)); rb_count += B_rb; @@ -200,16 +195,15 @@ static void nr_pdcch_llr(uint32_t sz, c16_t *rxF, c16_t *llr) // This function will extract the mapped DM-RS PDCCH REs as per 38.211 Section 7.4.1.3.2 (Mapping to physical resources) static void nr_pdcch_extract_rbs_single(uint32_t rxdataF_sz, - uint32_t coreset_nbr_rb, c16_t rxdataF[][rxdataF_sz], int32_t est_size, c16_t dl_ch_estimates[][est_size], int arraySz, c16_t rxdataF_ext[][arraySz], c16_t dl_ch_estimates_ext[][arraySz], - int symbol, NR_DL_FRAME_PARMS *frame_parms, uint8_t *coreset_freq_dom, + uint32_t coreset_nbr_rb, uint32_t n_BWP_start) { /* @@ -224,8 +218,8 @@ static void nr_pdcch_extract_rbs_single(uint32_t rxdataF_sz, */ for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { - const c16_t *dl_ch0 = dl_ch_estimates[aarx] + frame_parms->ofdm_symbol_size * symbol; - c16_t *rxFbase = rxdataF[aarx] + frame_parms->ofdm_symbol_size * symbol; + c16_t *dl_ch0 = dl_ch_estimates[aarx]; + c16_t *rxFbase = rxdataF[aarx]; LOG_DDD("dl_ch0 = &dl_ch_estimates[aarx = (%d)][0]\n", aarx); c16_t *dl_ch0_ext = dl_ch_estimates_ext[aarx]; @@ -249,44 +243,52 @@ static void nr_pdcch_extract_rbs_single(uint32_t rxdataF_sz, * the position 0+c_rb-N_RB_DL/2 in rxdataF and we have to point the pointer at (1+c_rb-N_RB_DL/2) in rxdataF */ - int c_rb = 0; - for (int rb = 0; rb < coreset_nbr_rb; rb++, c_rb++) { - int c_rb_by6 = c_rb / 6; + c16_t middle_prb_buffer[RE_PER_RB]; + for (int rb_group = 0; rb_group < coreset_nbr_rb / 6; rb_group++) { + if ((coreset_freq_dom[rb_group / 8] & (1 << (7 - (rb_group & 7)))) == 0) { + continue; + } + for (int rb = 0; rb < 6; rb++) { + int c_rb = rb_group * 6 + rb; + c16_t *rxF = NULL; + if ((frame_parms->N_RB_DL & 1) == 0) { + if ((c_rb + n_BWP_start) < frame_parms->N_RB_DL / 2) + // if RB to be treated is lower than middle system bandwidth then rxdataF pointed + // at (offset + c_br + symbol * ofdm_symbol_size): even case + rxF = rxFbase + frame_parms->first_carrier_offset + RE_PER_RB * (c_rb + n_BWP_start); + else + // number of RBs is even and c_rb is higher than half system bandwidth (we don't skip DC) + // if these conditions are true the pointer has to be situated at the 1st part of the rxdataF + // we point at the 1st part of the rxdataF in symbol + rxF = rxFbase + RE_PER_RB * (c_rb + n_BWP_start - frame_parms->N_RB_DL / 2); + } else { + if ((c_rb + n_BWP_start) <= frame_parms->N_RB_DL / 2) + // if RB to be treated is lower than middle system bandwidth then rxdataF pointed + // at (offset + c_br + symbol * ofdm_symbol_size): odd case + // Reassemble the middle PRB + if (c_rb + n_BWP_start == frame_parms->N_RB_DL / 2) { + memcpy(middle_prb_buffer, rxFbase + frame_parms->ofdm_symbol_size - RE_PER_RB / 2, sizeof(c16_t) * RE_PER_RB / 2); + memcpy(middle_prb_buffer + RE_PER_RB / 2, rxFbase, sizeof(c16_t) * RE_PER_RB / 2); + rxF = middle_prb_buffer; + } else { + rxF = rxFbase + frame_parms->first_carrier_offset + RE_PER_RB * (c_rb + n_BWP_start); + } - // skip zeros in frequency domain bitmap - while ((coreset_freq_dom[c_rb_by6 / 8] & (1 << (7 - (c_rb_by6 & 7)))) == 0) { - c_rb += 6; - c_rb_by6 = c_rb / 6; + else + // number of RBs is odd and c_rb is higher than half system bandwidth + 1 + // if these conditions are true the pointer has to be situated at the 1st part of + // the rxdataF just after the first IQ symbols of the RB containing DC + // we point at the 1st part of the rxdataF in symbol + rxF = rxFbase + RE_PER_RB * (c_rb + n_BWP_start - frame_parms->N_RB_DL / 2) - 6; + } + + const int valid_re[RE_PER_RB_OUT_DMRS] = {0, 2, 3, 4, 6, 7, 8, 10, 11}; + for (int i = 0; i < sizeofArray(valid_re); i++) { + *rxF_ext++ = rxF[valid_re[i]]; + *dl_ch0_ext++ = dl_ch0[valid_re[i]]; + } + dl_ch0 += RE_PER_RB; } - c16_t *rxF = NULL; - if ((frame_parms->N_RB_DL & 1) == 0) { - if ((c_rb + n_BWP_start) < frame_parms->N_RB_DL / 2) - // if RB to be treated is lower than middle system bandwidth then rxdataF pointed - // at (offset + c_br + symbol * ofdm_symbol_size): even case - rxF = rxFbase + frame_parms->first_carrier_offset + RE_PER_RB * (c_rb + n_BWP_start); - else - // number of RBs is even and c_rb is higher than half system bandwidth (we don't skip DC) - // if these conditions are true the pointer has to be situated at the 1st part of the rxdataF - // we point at the 1st part of the rxdataF in symbol - rxF = rxFbase + RE_PER_RB * (c_rb + n_BWP_start - frame_parms->N_RB_DL / 2); - } else { - if ((c_rb + n_BWP_start) <= frame_parms->N_RB_DL / 2) - // if RB to be treated is lower than middle system bandwidth then rxdataF pointed - // at (offset + c_br + symbol * ofdm_symbol_size): odd case - rxF = rxFbase + frame_parms->first_carrier_offset + RE_PER_RB * (c_rb + n_BWP_start); - else - // number of RBs is odd and c_rb is higher than half system bandwidth + 1 - // if these conditions are true the pointer has to be situated at the 1st part of - // the rxdataF just after the first IQ symbols of the RB containing DC - // we point at the 1st part of the rxdataF in symbol - rxF = rxFbase + RE_PER_RB * (c_rb + n_BWP_start - frame_parms->N_RB_DL / 2) - 6; - } - const int valid_re[RE_PER_RB_OUT_DMRS] = {0, 2, 3, 4, 6, 7, 8, 10, 11}; - for (int i = 0; i < sizeofArray(valid_re); i++) { - *rxF_ext++ = rxF[valid_re[i]]; - *dl_ch0_ext++ = dl_ch0[valid_re[i]]; - } - dl_ch0 += RE_PER_RB; } } } @@ -318,92 +320,222 @@ static void nr_pdcch_detection_mrc(int sz, c16_t rxdataF_comp[][sz]) } } -void nr_rx_pdcch(PHY_VARS_NR_UE *ue, - const UE_nr_rxtx_proc_t *proc, - int32_t pdcch_est_size, - c16_t pdcch_dl_ch_estimates[][pdcch_est_size], - c16_t *pdcch_e_rx, - fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15, - c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) +/* Produce LLRs from received PDCCH signal */ +static void nr_rx_pdcch_symbol(PHY_VARS_NR_UE *ue, + const UE_nr_rxtx_proc_t *proc, + int symbol, + int rel_symb_monOcc, + int ss_idx, + nr_phy_data_t *phy_data, + int llr_size_symbol, + c16_t rxdataF[ue->frame_parms.nb_antennas_rx][ue->frame_parms.ofdm_symbol_size], + c16_t llr[llr_size_symbol]) { - NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + NR_DL_FRAME_PARMS *fp = &ue->frame_parms; + NR_UE_PDCCH_CONFIG *phy_pdcch_config = &phy_data->phy_pdcch_config; + fapi_nr_coreset_t *coreset = &phy_pdcch_config->pdcch_config[ss_idx].coreset; + int32_t pdcch_est_size = ((((fp->ofdm_symbol_size + LTE_CE_FILTER_LENGTH) + 15) / 16) * 16); + __attribute__((aligned(16))) c16_t pdcch_dl_ch_estimates[fp->nb_antennas_rx][pdcch_est_size]; - int n_rb,rb_offset; - get_coreset_rballoc(rel15->coreset.frequency_domain_resource,&n_rb,&rb_offset); - const int antRx = frame_parms->nb_antennas_rx; + nr_pdcch_channel_estimation(ue, + proc, + symbol, + coreset, + fp->first_carrier_offset, + phy_pdcch_config->pdcch_config[ss_idx].BWPStart, + pdcch_est_size, + pdcch_dl_ch_estimates, + rxdataF); - // Pointer to llrs - const int symb_size = n_rb * RE_PER_RB_OUT_DMRS; - c16_t llr[rel15->coreset.duration][symb_size]; + const int32_t rx_size = ((4 * fp->N_RB_DL * 12 + 31) >> 5) << 5; + __attribute__((aligned(32))) c16_t rxdataF_ext[fp->nb_antennas_rx][rx_size]; + __attribute__((aligned(32))) c16_t rxdataF_comp[fp->nb_antennas_rx][rx_size]; + __attribute__((aligned(32))) c16_t pdcch_dl_ch_estimates_ext[fp->nb_antennas_rx][rx_size]; + memset(rxdataF_comp, 0, sizeof(rxdataF_comp)); - LOG_D(NR_PHY_DCI, - "pdcch coreset: freq %x, n_rb %d, rb_offset %d\n", - rel15->coreset.frequency_domain_resource[0], - n_rb, - rb_offset); - for (int s = 0; s < rel15->coreset.duration; s++) { - LOG_D(NR_PHY_DCI, "in nr_pdcch_extract_rbs_single(rxdataF -> rxdataF_ext || dl_ch_estimates -> dl_ch_estimates_ext)\n"); - const int arraySz = ceil_mod(symb_size, 32); - __attribute__((aligned(32))) c16_t rxdataF_ext[antRx][arraySz]; - __attribute__((aligned(32))) c16_t pdcch_dl_ch_estimates_ext[antRx][arraySz]; - nr_pdcch_extract_rbs_single(ue->frame_parms.samples_per_slot_wCP, - n_rb, - rxdataF, - pdcch_est_size, - pdcch_dl_ch_estimates, - arraySz, + int n_rb; + int rb_offset; + get_coreset_rballoc(coreset->frequency_domain_resource, &n_rb, &rb_offset); + + nr_pdcch_extract_rbs_single(ue->frame_parms.ofdm_symbol_size, + rxdataF, + pdcch_est_size, + pdcch_dl_ch_estimates, + rx_size, + rxdataF_ext, + pdcch_dl_ch_estimates_ext, + fp, + coreset->frequency_domain_resource, + n_rb, + phy_pdcch_config->pdcch_config[ss_idx].BWPStart); + + LOG_D(NR_PHY_DCI, "in channel level function (dl_ch_estimates_ext -> dl_ch_estimates_ext)\n"); + int avg[fp->nb_antennas_rx]; + nr_channel_level(0, rx_size, pdcch_dl_ch_estimates_ext, fp->nb_antennas_rx, 1, avg, n_rb * RE_PER_RB_OUT_DMRS); + int avgs = avg[0]; + for (int i = 1; i < fp->nb_antennas_rx; i++) + avgs = cmax(avgs, avg[i]); + const int log2_maxh = (log2_approx(avgs) / 2) + 5; //+frame_parms->nb_antennas_rx; + + nr_pdcch_channel_compensation(rx_size, rxdataF_ext, pdcch_dl_ch_estimates_ext, - rel15->coreset.StartSymbolIndex + s, - frame_parms, - rel15->coreset.frequency_domain_resource, - rel15->BWPStart); + rxdataF_comp, + fp->nb_antennas_rx, + log2_maxh); // log2_maxh+I0_shift - LOG_D(NR_PHY_DCI, "in channel level function (dl_ch_estimates_ext -> dl_ch_estimates_ext)\n"); - // compute channel level based on ofdm symbol 0 - int avg[antRx]; - nr_channel_level(0, arraySz, pdcch_dl_ch_estimates_ext, antRx, 1, avg, n_rb); - int avgs = avg[0]; - for (int i = 1; i < antRx; i++) - avgs = cmax(avgs, avg[i]); - uint8_t log2_maxh = (log2_approx(avgs) / 2) + 5; //+antRx; + UEscopeCopy(ue, pdcchRxdataF_comp, rxdataF_comp, sizeof(struct complex16), fp->nb_antennas_rx, rx_size, 0); -#ifdef UE_DEBUG_TRACE - LOG_D(NR_PHY_DCI, "slot %d: pdcch log2_maxh = %d (%d,%d)\n", proc->nr_slot_rx, log2_maxh, avgP[0], avgs); -#endif -#if T_TRACER - T(T_UE_PHY_PDCCH_ENERGY, T_INT(0), T_INT(0), T_INT(proc->frame_rx % 1024), T_INT(proc->nr_slot_rx), T_INT(avgs)); -#endif - LOG_D(NR_PHY_DCI, "we enter nr_pdcch_channel_compensation(log2_maxh=%d)\n", log2_maxh); - LOG_D(NR_PHY_DCI, "in nr_pdcch_channel_compensation(rxdataF_ext x dl_ch_estimates_ext -> rxdataF_comp)\n"); - // compute LLRs for ofdm symbol 0 only - __attribute__((aligned(32))) c16_t rxdataF_comp[antRx][arraySz]; - nr_pdcch_channel_compensation(arraySz, - rxdataF_ext, - pdcch_dl_ch_estimates_ext, - rxdataF_comp, - antRx, - log2_maxh); // log2_maxh+I0_shift - - UEscopeCopy(ue, pdcchRxdataF_comp, rxdataF_comp, sizeof(struct complex16), antRx, symb_size, 0); - - if (antRx > 1) - nr_pdcch_detection_mrc(arraySz, rxdataF_comp); - - nr_pdcch_llr(symb_size, rxdataF_comp[0], llr[s]); + if (fp->nb_antennas_rx > 1) { + nr_pdcch_detection_mrc(rx_size, rxdataF_comp); } - UEscopeCopy(ue, pdcchLlr, llr, sizeof(c16_t), 1, rel15->coreset.duration * symb_size, 0); - nr_pdcch_demapping_deinterleaving(n_rb, - llr, - pdcch_e_rx, - rel15->coreset.duration, - rel15->coreset.RegBundleSize, - rel15->coreset.InterleaverSize, - rel15->coreset.ShiftIndex, - rel15->number_of_candidates, - rel15->CCE, - rel15->L); + nr_pdcch_llr(llr_size_symbol, rxdataF_comp[0], llr); +} + +bool is_start_symbol_in_ss(const fapi_nr_dl_config_dci_dl_pdu_rel15_t *ss, const int symbol) +{ + return ((ss->coreset.StartSymbolBitmap >> (NR_SYMBOLS_PER_SLOT - 1 - symbol)) & 1); +} + +int get_pdcch_mon_occasions_slot(const fapi_nr_dl_config_dci_dl_pdu_rel15_t *ss, uint8_t start_symb[NR_SYMBOLS_PER_SLOT]) +{ + int sum = 0; + for (int s = 0; s < NR_SYMBOLS_PER_SLOT; s++) { + if (is_start_symbol_in_ss(ss, s)) { + if (start_symb != NULL) + start_symb[sum] = s; + sum++; + } + } + + return sum; +} + +int get_max_pdcch_monOcc(const NR_UE_PDCCH_CONFIG *phy_pdcch_config) +{ + int monOcc = 0; + for (int ss = 0; ss < phy_pdcch_config->nb_search_space; ss++) { + monOcc = max(monOcc, get_pdcch_mon_occasions_slot(&phy_pdcch_config->pdcch_config[ss], NULL)); + } + return monOcc; +} + +static void nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue, + const UE_nr_rxtx_proc_t *proc, + c16_t *pdcch_e_rx, + fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15, + fapi_nr_dci_indication_t *dci_ind); + +void set_first_last_pdcch_symb(const NR_UE_PDCCH_CONFIG *phy_pdcch_config, int *first_symb, int *last_symb) +{ + *first_symb = NR_SYMBOLS_PER_SLOT; // max first pdcch symbol + *last_symb = 0; // min last pdcch symbol + for (int ss = 0; ss < phy_pdcch_config->nb_search_space; ss++) { + for (int symb = 0; symb < NR_SYMBOLS_PER_SLOT; symb++) { + if (is_start_symbol_in_ss(&phy_pdcch_config->pdcch_config[ss], symb)) { + const int duration = phy_pdcch_config->pdcch_config[ss].coreset.duration; + *first_symb = min(*first_symb, symb); + *last_symb = max(*last_symb, symb + duration - 1); + } + } + } +} + +/* Generates PDCCH LLRs from received symbol for each Search-Space */ +void nr_pdcch_generate_llr(PHY_VARS_NR_UE *ue, + const UE_nr_rxtx_proc_t *proc, + int symbol, + nr_phy_data_t *phy_data, + int llr_size_symbol, + int num_monitoring_occ, + int max_symb, + c16_t rxdataF[ue->frame_parms.nb_antennas_rx][ue->frame_parms.ofdm_symbol_size], + c16_t pdcch_llr[phy_data->phy_pdcch_config.nb_search_space][num_monitoring_occ][max_symb * llr_size_symbol]) +{ + const NR_UE_PDCCH_CONFIG *phy_pdcch_config = &phy_data->phy_pdcch_config; + + // Loop over search spaces + for (int ss_idx = 0; ss_idx < phy_pdcch_config->nb_search_space; ss_idx++) { + uint8_t start_symb[NR_SYMBOLS_PER_SLOT] = {0}; + const int num_monOcc = get_pdcch_mon_occasions_slot(&phy_pdcch_config->pdcch_config[ss_idx], start_symb); + // Loop over monitoring occations within the slot in this ss + for (int occ = 0; occ < num_monOcc; occ++) { + const int first_symb = start_symb[occ]; + const int last_symb = first_symb + phy_pdcch_config->pdcch_config[ss_idx].coreset.duration; + // Decode PDCCH and generate LLR for each ss in this OFDM symbol + if ((symbol >= first_symb) && (symbol < last_symb)) { + const int rel_symb_monOcc = symbol - first_symb; + nr_rx_pdcch_symbol(ue, + proc, + symbol, + rel_symb_monOcc, + ss_idx, + phy_data, + llr_size_symbol, + rxdataF, + &pdcch_llr[ss_idx][occ][rel_symb_monOcc * llr_size_symbol]); + } + } + } +} + +/* Decode DCI from LLRs for each Search-Space and send to MAC */ +void nr_pdcch_dci_indication(const UE_nr_rxtx_proc_t *proc, + int llr_size, + int max_monOcc, + PHY_VARS_NR_UE *ue, + nr_phy_data_t *phy_data, + c16_t llr[phy_data->phy_pdcch_config.nb_search_space][max_monOcc][llr_size]) +{ + NR_UE_PDCCH_CONFIG *phy_pdcch_config = &phy_data->phy_pdcch_config; + + nr_downlink_indication_t dl_indication; + fapi_nr_dci_indication_t dci_ind = {.SFN = proc->frame_rx, .slot = proc->nr_slot_rx}; + + for (int ss_idx = 0; ss_idx < phy_pdcch_config->nb_search_space; ss_idx++) { + fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &phy_pdcch_config->pdcch_config[ss_idx]; + uint8_t unused_start_symb[NR_SYMBOLS_PER_SLOT] = {0}; + const int num_monitoring_occ = get_pdcch_mon_occasions_slot(rel15, unused_start_symb); + + int n_rb; + int rb_offset; + get_coreset_rballoc(rel15->coreset.frequency_domain_resource, &n_rb, &rb_offset); + + for (int m = 0; m < num_monitoring_occ; m++) { + /// PDCCH/DCI e-sequence (input to rate matching). + c16_t pdcch_e_rx[NR_MAX_PDCCH_SIZE]; + + nr_pdcch_demapping_deinterleaving(n_rb, + llr[ss_idx][m], + pdcch_e_rx, + rel15->coreset.duration, + rel15->coreset.RegBundleSize, + rel15->coreset.InterleaverSize, + rel15->coreset.ShiftIndex, + rel15->number_of_candidates, + rel15->CCE, + rel15->L); + + nr_dci_decoding_procedure(ue, proc, pdcch_e_rx, rel15, &dci_ind); + } + } + + for (int i = 0; i < dci_ind.number_of_dcis; i++) { + LOG_D(PHY, + "Frame.slot: %d.%d: DCI %i of %d total DCIs found --> rnti %x : format %d\n", + proc->frame_rx, + proc->nr_slot_rx, + i + 1, + dci_ind.number_of_dcis, + dci_ind.dci_list[i].rnti, + dci_ind.dci_list[i].dci_format); + } + + /* Send to MAC */ + nr_fill_dl_indication(&dl_indication, &dci_ind, NULL, proc, ue, phy_data); + ue->if_inst->dl_indication(&dl_indication); + phy_pdcch_config->nb_search_space = 0; } static void nr_pdcch_unscrambling(c16_t *e_rx, @@ -425,14 +557,13 @@ static void nr_pdcch_unscrambling(c16_t *e_rx, } } -void nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue, - const UE_nr_rxtx_proc_t *proc, - c16_t *pdcch_e_rx, - fapi_nr_dci_indication_t *dci_ind, - fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15) +static void nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue, + const UE_nr_rxtx_proc_t *proc, + c16_t *pdcch_e_rx, + fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15, + fapi_nr_dci_indication_t *dci_ind) { int e_rx_cand_idx = 0; - *dci_ind = (fapi_nr_dci_indication_t){.SFN = proc->frame_rx, .slot = proc->nr_slot_rx}; // if DCI for SIB we don't break after finding 1st DCI with that RNTI // there might be SIB1 and otherSIB in the same slot with the same length bool is_SI = rel15->rnti == SI_RNTI; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 5e677b542b..ab73bedb4f 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -540,6 +540,16 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, } *log2_maxh = (log2_approx(avgs) / 2) + 1; LOG_D(PHY, "[DLSCH] AbsSubframe %d.%d log2_maxh = %d (%d)\n", frame % 1024, nr_slot_rx, *log2_maxh, avgs); +#if T_TRACER + T(T_UE_PHY_PDSCH_ENERGY, + T_INT(gNB_id), + T_INT(frame % 1024), + T_INT(nr_slot_rx), + T_INT(avg[0]), // layer 0, antenna 0 + T_INT(n_rx > 1 ? avg[1] : 0), // layer 0, antenna 1 + T_INT(nl > 1 ? avg[n_rx] : 0), // layer 1, antenna 0 + T_INT(nl > 1 && n_rx > 1 ? avg[n_rx + 1] : 0)); // layer 1, antenna 1 +#endif } stop_meas_nr_ue_phy(ue, DLSCH_CHANNEL_LEVEL_STATS); if (meas_enabled) { @@ -552,9 +562,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, first_symbol_flag, ue->phy_cpu_stats.cpu_time_stats[DLSCH_CHANNEL_LEVEL_STATS].p_time / (cpuf * 1000.0)); } -#if T_TRACER - T(T_UE_PHY_PDSCH_ENERGY, T_INT(gNB_id), T_INT(0), T_INT(frame % 1024), T_INT(nr_slot_rx)); -#endif //---------------------------------------------------------- //--------------------- channel compensation --------------- @@ -746,13 +753,12 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, #if T_TRACER T(T_UE_PHY_PDSCH_IQ, T_INT(gNB_id), - T_INT(ue->Mod_id), T_INT(frame % 1024), T_INT(nr_slot_rx), T_INT(nb_rb_pdsch), T_INT(fp->N_RB_UL), T_INT(fp->symbols_per_slot), - T_BUFFER(&rxdataF_comp[gNB_id][0], 2 * /* ulsch[UE_id]->harq_processes[harq_pid]->nb_rb */ fp->N_RB_UL * 12 * 2)); + T_BUFFER(&rxdataF_comp[gNB_id][0], 2 * fp->N_RB_UL * 12 * fp->symbols_per_slot * 2)); #endif if (ue->phy_sim_pdsch_rxdataF_comp) 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 41747a9ef1..ed348986e8 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -69,6 +69,12 @@ typedef struct pdsch_scope_req_s { void nr_ue_dlsch_init(NR_UE_DLSCH_t *dlsch_list, int num_dlsch, uint8_t max_ldpc_iterations); void nr_conjch0_mult_ch1(c16_t *ch0, c16_t *ch1, c16_t *ch0conj_ch1, unsigned short nb_rb, unsigned char output_shift0); +void set_first_last_pdcch_symb(const NR_UE_PDCCH_CONFIG *phy_pdcch_config, int *first_symb, int *last_symb); + +int get_pdcch_mon_occasions_slot(const fapi_nr_dl_config_dci_dl_pdu_rel15_t *ss, uint8_t start_symb[NR_SYMBOLS_PER_SLOT]); + +int get_max_pdcch_monOcc(const NR_UE_PDCCH_CONFIG *phy_pdcch_config); + /** \brief This is the alternative top-level entry point for DLSCH decoding in UE. It handles all the HARQ processes in only one call. The routine first computes the segmentation information and then call LDPC decoder on the @@ -180,14 +186,6 @@ void nr_dlsch_unscrambling(int16_t* llr, uint32_t Nid, uint32_t n_RNTI); -void nr_rx_pdcch(PHY_VARS_NR_UE *ue, - const UE_nr_rxtx_proc_t *proc, - int32_t pdcch_est_size, - c16_t pdcch_dl_ch_estimates[][pdcch_est_size], - c16_t *pdcch_e_rx, - fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15, - c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); - /*! \brief Performs detection of SSS to find cell ID and other framing parameters (FDD/TDD, normal/extended prefix) @param phy_vars_ue Pointer to UE variables @param tot_metric Pointer to variable containing maximum metric under framing hypothesis (to be compared to other hypotheses @@ -279,12 +277,6 @@ void nr_sl_rf_card_config_freq(PHY_VARS_NR_UE *ue, openair0_config_t *openair0_cfg, int freq_offset); -void nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue, - const UE_nr_rxtx_proc_t *proc, - c16_t *pdcch_e_rx, - fapi_nr_dci_indication_t *dci_ind, - fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15); - /** \brief This function is the top-level entry point to PDSCH demodulation, after frequency-domain transformation and channel estimation. It performs - RB extraction (signal and channel estimates) diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index fb549d4734..ebf459402e 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -215,13 +215,6 @@ static inline int crcType(int nbSeg, int len) return len > NR_MAX_PDSCH_TBS ? CRC24_A : CRC16; } -typedef struct { - //! estimated rssi (dBm) - int rx_rssi_dBm; - /// Wideband CQI (sum of all RX antennas, in dB) - char wideband_cqi_tot; -} ulsch_measurements_gNB; - typedef struct { uint32_t frame; uint32_t slot; @@ -243,7 +236,6 @@ typedef struct { /// Flag to indicate that the UL configuration has been handled. Used to remove a stale ULSCH when frame wraps around uint8_t handled; delay_t delay; - ulsch_measurements_gNB ulsch_measurements; } NR_gNB_ULSCH_t; typedef struct { diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index 0546455e36..f121914f11 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -185,9 +185,6 @@ void nr_feptx_prec(RU_t *ru, int frame_tx, int slot_tx) int txdataF_offset = slot_tx * fp->samples_per_slot_wCP; start_meas(&ru->precoding_stats); - if (nr_slot_select(cfg,frame_tx,slot_tx) == NR_UPLINK_SLOT) - return; - if (gNB->common_vars.analog_bf) { for (int i = 0; i < ru->num_beams_period; i++) { memcpy((void*) &ru->common.beam_id[i][slot_tx * fp->symbols_per_slot], @@ -196,6 +193,9 @@ void nr_feptx_prec(RU_t *ru, int frame_tx, int slot_tx) } } + if (nr_slot_select(cfg,frame_tx,slot_tx) == NR_UPLINK_SLOT) + return; + // If there is no digital beamforming we just need to copy the data to RU if (ru->config.dbt_config.num_dig_beams == 0 || ru->gNB_list[0]->common_vars.analog_bf) { for (int b = 0; b < ru->num_beams_period; b++) { diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h index c7f0deb118..3ba5226542 100644 --- a/openair1/SCHED_NR_UE/defs.h +++ b/openair1/SCHED_NR_UE/defs.h @@ -92,7 +92,8 @@ */ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data, c16_t **txp); -int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data); +int pbch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data); +void pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data); void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data); @@ -137,13 +138,22 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, void *typeSpecific, uint8_t *b); -int nr_ue_pdcch_procedures(PHY_VARS_NR_UE *ue, +void nr_pdcch_generate_llr(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, - int32_t pdcch_est_size, - c16_t pdcch_dl_ch_estimates[][pdcch_est_size], + int symbol, nr_phy_data_t *phy_data, - int n_ss, - c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); + int llr_size_symbol, + int num_monitoring_occ, + int max_symb, + c16_t rxdataF[ue->frame_parms.nb_antennas_rx][ue->frame_parms.ofdm_symbol_size], + c16_t pdcch_llr[phy_data->phy_pdcch_config.nb_search_space][num_monitoring_occ][max_symb * llr_size_symbol]); + +void nr_pdcch_dci_indication(const UE_nr_rxtx_proc_t *proc, + int llr_size, + int max_monOcc, + PHY_VARS_NR_UE *ue, + nr_phy_data_t *phy_data, + c16_t llr[phy_data->phy_pdcch_config.nb_search_space][max_monOcc][llr_size]); void nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index f22d13c5fc..cbef1dc62a 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -372,6 +372,9 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, n AssertFatal(ue->CC_id == 0, "Transmission on secondary CCs is not supported yet\n"); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX,VCD_FUNCTION_IN); +#if T_TRACER + T(T_UE_PHY_UL_TICK, T_INT(ue->Mod_id), T_INT(frame_tx % 1024), T_INT(slot_tx)); +#endif const int samplesF_per_slot = NR_SYMBOLS_PER_SLOT * ue->frame_parms.ofdm_symbol_size; c16_t txdataF_buf[ue->frame_parms.nb_antennas_tx * samplesF_per_slot] __attribute__((aligned(32))); @@ -440,7 +443,6 @@ static void nr_ue_measurement_procedures(uint16_t l, if(nr_slot_rx == 0) T(T_UE_PHY_MEAS, T_INT(gNB_id), - T_INT(ue->Mod_id), T_INT(proc->frame_rx % 1024), T_INT(nr_slot_rx), T_INT((int)(10 * log10(ue->measurements.rsrp[0]) - ue->rx_total_gain_dB)), @@ -448,7 +450,8 @@ static void nr_ue_measurement_procedures(uint16_t l, T_INT((int)(ue->measurements.rx_power_avg_dB[0] - ue->measurements.n0_power_avg_dB)), T_INT((int)ue->measurements.rx_power_avg_dB[0]), T_INT((int)ue->measurements.n0_power_avg_dB), - T_INT((int)ue->measurements.wideband_cqi_avg[0])); + T_INT((int)ue->measurements.wideband_cqi_avg[0]), + T_INT((int)ue->common_vars.freq_offset)); #endif } @@ -527,53 +530,6 @@ static int nr_ue_pbch_procedures(PHY_VARS_NR_UE *ue, return ret; } -int nr_ue_pdcch_procedures(PHY_VARS_NR_UE *ue, - const UE_nr_rxtx_proc_t *proc, - int32_t pdcch_est_size, - c16_t pdcch_dl_ch_estimates[][pdcch_est_size], - nr_phy_data_t *phy_data, - int n_ss, - c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) -{ - int frame_rx = proc->frame_rx; - int nr_slot_rx = proc->nr_slot_rx; - NR_UE_PDCCH_CONFIG *phy_pdcch_config = &phy_data->phy_pdcch_config; - - fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &phy_pdcch_config->pdcch_config[n_ss]; - - start_meas_nr_ue_phy(ue, DLSCH_RX_PDCCH_STATS); - - /// PDCCH/DCI e-sequence (input to rate matching). - int32_t pdcch_e_rx_size = NR_MAX_PDCCH_SIZE; - c16_t pdcch_e_rx[pdcch_e_rx_size]; - - nr_rx_pdcch(ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, pdcch_e_rx, rel15, rxdataF); - - fapi_nr_dci_indication_t dci_ind; - nr_dci_decoding_procedure(ue, proc, pdcch_e_rx, &dci_ind, rel15); - - for (int i = 0; i < dci_ind.number_of_dcis; i++) { - LOG_D(PHY, - "[UE %d] AbsSubFrame %d.%d: DCI %i of %d total DCIs found --> rnti %x : format %d\n", - ue->Mod_id, - frame_rx % 1024, - nr_slot_rx, - i + 1, - dci_ind.number_of_dcis, - dci_ind.dci_list[i].rnti, - dci_ind.dci_list[i].dci_format); - } - - nr_downlink_indication_t dl_indication; - // fill dl_indication message - nr_fill_dl_indication(&dl_indication, &dci_ind, NULL, proc, ue, phy_data); - // send to mac - ue->if_inst->dl_indication(&dl_indication); - stop_meas_nr_ue_phy(ue, DLSCH_RX_PDCCH_STATS); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_OUT); - return (dci_ind.number_of_dcis); -} - static freq_alloc_bitmap_t set_start_end_from_bitmap(int size, int alloc_size, const uint8_t bitmap[alloc_size]) { freq_alloc_bitmap_t alloc = { @@ -1027,18 +983,87 @@ static bool is_ssb_index_transmitted(const PHY_VARS_NR_UE *ue, const int index) return ue->frame_parms.ssb_index == index; } -int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data) +static int get_pdcch_max_rbs(NR_UE_PDCCH_CONFIG *phy_pdcch_config) +{ + int nb_rb = 0; + int rb_offset = 0; + for (int i = 0; i < phy_pdcch_config->nb_search_space; i++) { + int tmp = 0; + get_coreset_rballoc(phy_pdcch_config->pdcch_config[i].coreset.frequency_domain_resource, &tmp, &rb_offset); + if (tmp > nb_rb) + nb_rb = tmp; + } + return nb_rb; +} + +static int get_max_pdcch_symb(const NR_UE_PDCCH_CONFIG *phy_pdcch_config) +{ + int max_pdcch_symb = 0; + for (int i = 0; i < phy_pdcch_config->nb_search_space; i++) + if (phy_pdcch_config->pdcch_config[i].coreset.duration > max_pdcch_symb) + max_pdcch_symb = phy_pdcch_config->pdcch_config[i].coreset.duration; + + return max_pdcch_symb; +} + +void pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data) +{ + NR_UE_PDCCH_CONFIG *phy_pdcch_config = &phy_data->phy_pdcch_config; + if (phy_pdcch_config->nb_search_space == 0) + return; + + TracyCZone(ctx, true); + /* process PDCCH */ + LOG_D(PHY, " ------ --> PDCCH ChannelComp/LLR Frame.slot %d.%d ------ \n", proc->frame_rx % 1024, proc->nr_slot_rx); + start_meas_nr_ue_phy(ue, DLSCH_RX_PDCCH_STATS); + int num_monitoring_occ = get_max_pdcch_monOcc(phy_pdcch_config); + int max_nb_symb_pdcch = get_max_pdcch_symb(phy_pdcch_config); + int llr_size_symbol = get_pdcch_max_rbs(phy_pdcch_config) * 9; + c16_t pdcch_llr[phy_pdcch_config->nb_search_space][num_monitoring_occ][max_nb_symb_pdcch * llr_size_symbol]; + + int start_symb_pdcch, last_symb_pdcch; + set_first_last_pdcch_symb(phy_pdcch_config, &start_symb_pdcch, &last_symb_pdcch); + + /* Temporarily loop over symbols in the slot, perform OFDM demod and process PDCCH. + When symbol based proc design is fully merged, this function will be called to process only one symbol + and OFDM demod will be removed from here. */ + const uint32_t rxdataF_sz = ue->frame_parms.samples_per_slot_wCP; + __attribute__((aligned(32))) c16_t rxdataF[ue->frame_parms.nb_antennas_rx][rxdataF_sz]; + + for (int symbol = start_symb_pdcch; symbol <= last_symb_pdcch; symbol++) { + NR_DL_FRAME_PARMS *fp = &ue->frame_parms; + nr_slot_fep(ue, fp, proc->nr_slot_rx, symbol, rxdataF, link_type_dl, 0, ue->common_vars.rxdata); + __attribute__((aligned(32))) c16_t rxdataF_symb[fp->nb_antennas_rx][((fp->ofdm_symbol_size + 7) / 8) * 8]; + + for (int ant = 0; ant < fp->nb_antennas_rx; ant++) + memcpy(rxdataF_symb[ant], &rxdataF[ant][symbol * fp->ofdm_symbol_size], sizeof(c16_t) * fp->ofdm_symbol_size); + + nr_pdcch_generate_llr(ue, proc, symbol, phy_data, llr_size_symbol, num_monitoring_occ, max_nb_symb_pdcch, rxdataF_symb, pdcch_llr); + if (symbol == last_symb_pdcch) { + nr_pdcch_dci_indication(proc, llr_size_symbol * max_nb_symb_pdcch, num_monitoring_occ, ue, phy_data, pdcch_llr); + UEscopeCopy(ue, pdcchLlr, pdcch_llr, sizeof(c16_t), 1, sizeof(pdcch_llr), 0); + } + } + stop_meas_nr_ue_phy(ue, DLSCH_RX_PDCCH_STATS); + TracyCZoneEnd(ctx); + if (ue->phy_sim_rxdataF) + memcpy(ue->phy_sim_rxdataF, rxdataF[0], sizeof(int32_t) * max_nb_symb_pdcch * ue->frame_parms.ofdm_symbol_size); +} + +int pbch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data) { TracyCZone(ctx, true); int frame_rx = proc->frame_rx; int nr_slot_rx = proc->nr_slot_rx; int gNB_id = proc->gNB_id; NR_DL_FRAME_PARMS *fp = &ue->frame_parms; - NR_UE_PDCCH_CONFIG *phy_pdcch_config = &phy_data->phy_pdcch_config; int sampleShift = INT_MAX; nr_ue_dlsch_init(phy_data->dlsch, NR_MAX_NB_LAYERS>4 ? 2:1, ue->max_ldpc_iterations); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN); +#if T_TRACER + T(T_UE_PHY_DL_TICK, T_INT(ue->Mod_id), T_INT(frame_rx % 1024), T_INT(nr_slot_rx)); +#endif LOG_D(PHY," ****** start RX-Chain for Frame.Slot %d.%d ****** \n", frame_rx%1024, nr_slot_rx); @@ -1163,43 +1188,7 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_ } // for i } // for rsc_id } // for gNB_id - - LOG_D(PHY," ------ --> PDCCH ChannelComp/LLR Frame.slot %d.%d ------ \n", frame_rx%1024, nr_slot_rx); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH, VCD_FUNCTION_IN); - - uint8_t nb_symb_pdcch = phy_pdcch_config->nb_search_space > 0 ? phy_pdcch_config->pdcch_config[0].coreset.duration : 0; - int first_symb_pdcch = phy_pdcch_config->nb_search_space > 0 ? phy_pdcch_config->pdcch_config[0].coreset.StartSymbolIndex : 0; - int last_symb_pdcch = first_symb_pdcch + nb_symb_pdcch; - for (int l = first_symb_pdcch; l < last_symb_pdcch; l++) { - nr_slot_fep(ue, fp, proc->nr_slot_rx, l, rxdataF, link_type_dl, 0, ue->common_vars.rxdata); - } - - // 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))) c16_t pdcch_dl_ch_estimates[4 * fp->nb_antennas_rx][pdcch_est_size]; - - uint8_t dci_cnt = 0; - for(int n_ss = 0; n_ssnb_search_space; n_ss++) { - for (int l = first_symb_pdcch; l < last_symb_pdcch; l++) { - // note: this only works if RBs for PDCCH are contigous! - 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); - } - dci_cnt = dci_cnt + nr_ue_pdcch_procedures(ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, phy_data, n_ss, rxdataF); - } - LOG_D(PHY, "[UE %d] Frame %d, nr_slot_rx %d: found %d DCIs\n", ue->Mod_id, frame_rx, nr_slot_rx, dci_cnt); - phy_pdcch_config->nb_search_space = 0; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH, VCD_FUNCTION_OUT); TracyCZoneEnd(ctx); - if (ue->phy_sim_rxdataF) - memcpy(ue->phy_sim_rxdataF, rxdataF[0], sizeof(int32_t) * nb_symb_pdcch * ue->frame_parms.ofdm_symbol_size); return sampleShift; } diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 6329d5849f..752211fa10 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -1216,9 +1216,8 @@ int main(int argc, char **argv) ue_dci_configuration(UE_mac, &dl_config, frame, slot); nr_ue_scheduled_response(&scheduled_response); - pbch_pdcch_processing(UE, - &UE_proc, - &phy_data); + pbch_processing(UE, &UE_proc, &phy_data); + pdcch_processing(UE, &UE_proc, &phy_data); pdsch_processing(UE, &UE_proc, &phy_data); diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index 6279663e74..4b44b34091 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -110,17 +110,6 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, { } -int nr_ue_pdcch_procedures(PHY_VARS_NR_UE *ue, - const UE_nr_rxtx_proc_t *proc, - int32_t pdcch_est_size, - c16_t pdcch_dl_ch_estimates[][pdcch_est_size], - nr_phy_data_t *phy_data, - int n_ss, - c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) -{ - return 0; -} - configmodule_interface_t *uniqCfg = NULL; int main(int argc, char **argv) { diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index c4b2f854c2..b7f93cdf3a 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -1468,14 +1468,14 @@ int main(int argc, char *argv[]) } int offset = (slot & 3) * gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size; for (int aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) { - apply_nr_rotation_RX(&gNB->frame_parms, - gNB->common_vars.rxdataF[0][aa], - gNB->frame_parms.symbol_rotation[1], - slot, - gNB->frame_parms.N_RB_UL, - offset, - 0, - gNB->frame_parms.Ncp == EXTENDED ? 12 : 14); + const unsigned int max_symb = (gNB->frame_parms.Ncp == EXTENDED) ? 12 : 14; + for (int sym = 0; sym < max_symb; sym++) + apply_nr_rotation_symbol_RX(&gNB->frame_parms, + gNB->common_vars.rxdataF[0][aa] + offset + sym * gNB->frame_parms.ofdm_symbol_size, + gNB->frame_parms.symbol_rotation[1], + gNB->frame_parms.N_RB_UL, + slot, + sym); } ul_proc_error = phy_procedures_gNB_uespec_RX(gNB, frame, slot, &UL_INFO); diff --git a/openair2/COMMON/ngap_messages_types.h b/openair2/COMMON/ngap_messages_types.h index 2c4b0f8a0a..5be5e316ef 100644 --- a/openair2/COMMON/ngap_messages_types.h +++ b/openair2/COMMON/ngap_messages_types.h @@ -421,6 +421,8 @@ typedef struct ngap_nas_first_req_s { /* PLMN: Selected PLMN Identity (optional) * User Location Information (mandatory) */ plmn_id_t plmn; + // NR Cell ID for NR CGI (mandatory) + uint32_t nr_cell_id; // RRC Establishment Cause (mandatory) ngap_rrc_establishment_cause_t establishment_cause; // NAS-PDU (mandatory) @@ -434,6 +436,10 @@ typedef struct ngap_uplink_nas_s { uint32_t gNB_ue_ngap_id; /* NAS pdu */ byte_array_t nas_pdu; + /* UserLocationInformation (mandatory) */ + plmn_id_t plmn; // CGI and TAI + uint32_t nr_cell_id; // CGI + uint32_t tac; // TAI } ngap_uplink_nas_t; typedef struct target_cell_id_s { diff --git a/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_e2sm_ue_id.c b/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_e2sm_ue_id.c index a81a01d394..5d725f1df6 100644 --- a/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_e2sm_ue_id.c +++ b/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_e2sm_ue_id.c @@ -38,13 +38,11 @@ ue_id_e2sm_t fill_e2sm_gnb_ue_id_data(const gNB_RRC_UE_t *rrc_ue_context, __attr ue_id.gnb.amf_ue_ngap_id = auni < (1LL << 40) ? auni : 0; // Mandatory - //GUAMI 6.2.3.17 - ue_id.gnb.guami.plmn_id = (e2sm_plmn_t) { - .mcc = rrc_ue_context->ue_guami.mcc, - .mnc = rrc_ue_context->ue_guami.mnc, - .mnc_digit_len = rrc_ue_context->ue_guami.mnc_len - }; - + //GUAMI 6.2.3.17 + ue_id.gnb.guami.plmn_id = (e2sm_plmn_t){.mcc = rrc_ue_context->ue_guami.plmn.mcc, + .mnc = rrc_ue_context->ue_guami.plmn.mnc, + .mnc_digit_len = rrc_ue_context->ue_guami.plmn.mnc_digit_length}; + ue_id.gnb.guami.amf_region_id = rrc_ue_context->ue_guami.amf_region_id; ue_id.gnb.guami.amf_set_id = rrc_ue_context->ue_guami.amf_set_id; ue_id.gnb.guami.amf_ptr = rrc_ue_context->ue_guami.amf_pointer; diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 45532572cd..056387de92 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -707,7 +707,7 @@ void RCconfig_verify(configmodule_interface_t *cfg, ngran_node_t node_type) verify_gnb_param_notset(gnbp, GNB_DISABLE_HARQ_IDX, GNB_CONFIG_STRING_DISABLE_HARQ); verify_gnb_param_notset(gnbp, GNB_NUM_DL_HARQ_IDX, GNB_CONFIG_STRING_NUM_DL_HARQPROCESSES); verify_gnb_param_notset(gnbp, GNB_NUM_UL_HARQ_IDX, GNB_CONFIG_STRING_NUM_UL_HARQPROCESSES); - verify_gnb_param_notset(gnbp, GNB_DO_SINR_IDX, GNB_CONFIG_STRING_DOSINR); + verify_gnb_param_notset(gnbp, GNB_CONFIG_REP_IDX, GNB_CONFIG_STRING_CONFIG_REP); // check for some general sections verify_section_notset(cfg, NULL, CONFIG_STRING_L1_LIST); @@ -1432,7 +1432,8 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg) config.do_CSIRS = *GNBParamList.paramarray[0][GNB_DO_CSIRS_IDX].iptr; config.do_SRS = *GNBParamList.paramarray[0][GNB_DO_SRS_IDX].iptr; config.max_num_rsrp = *GNBParamList.paramarray[0][GNB_LIMIT_RSRP_REPORT_IDX].iptr; - config.do_SINR = *GNBParamList.paramarray[0][GNB_DO_SINR_IDX].iptr; + const char *report_type_s = *GNBParamList.paramarray[0][GNB_CONFIG_REP_IDX].strptr; + config.report_type = config_get_processedint(cfg, &GNBParamList.paramarray[0][GNB_CONFIG_REP_IDX]); config.force_256qam_off = *GNBParamList.paramarray[0][GNB_FORCE256QAMOFF_IDX].iptr; config.force_UL256qam_off = *GNBParamList.paramarray[0][GNB_FORCEUL256QAMOFF_IDX].iptr; config.use_deltaMCS = *GNBParamList.paramarray[0][GNB_USE_DELTA_MCS_IDX].iptr != 0; @@ -1443,10 +1444,11 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg) if (config.disable_harq) LOG_W(GNB_APP, "\"disable_harq\" is a REL17 feature and is incompatible with REL15 and REL16 UEs!\n"); LOG_I(GNB_APP, - "CSI-RS %d, SRS %d, SINR:%d, 256 QAM %s, delta_MCS %s, maxMIMO_Layers %d, HARQ feedback %s, num DLHARQ:%d, num ULHARQ:%d\n", + "CSI-RS %d, SRS %d, report type %d (%s), 256 QAM %s, delta_MCS %s, maxMIMO_Layers %d, HARQ feedback %s, num DLHARQ:%d, num ULHARQ:%d\n", config.do_CSIRS, config.do_SRS, - config.do_SINR, + config.report_type, + report_type_s, config.force_256qam_off ? "force off" : "may be on", config.use_deltaMCS ? "on" : "off", config.maxMIMO_layers, diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h index e4e4bc3d2a..4ec09d06f0 100644 --- a/openair2/GNB_APP/gnb_paramdef.h +++ b/openair2/GNB_APP/gnb_paramdef.h @@ -137,7 +137,7 @@ typedef enum { #define GNB_CONFIG_STRING_UESS_AGG_LEVEL_LIST "uess_agg_levels" #define GNB_CONFIG_STRING_CU_SIB_LIST "cu_sibs" #define GNB_CONFIG_STRING_DU_SIB_LIST "du_sibs" -#define GNB_CONFIG_STRING_DOSINR "do_SINR" +#define GNB_CONFIG_STRING_CONFIG_REP "CSI_report_type" #define GNB_CONFIG_STRING_1ST_ACTIVE_BWP "first_active_bwp" #define GNB_CONFIG_STRING_LIMIT_RSRP_REPORT "max_num_RSRP_reported" @@ -153,7 +153,7 @@ typedef enum { #define GNB_CONFIG_HLP_UESS_AGG_LEVEL_LIST "List of aggregation levels with number of candidates per level. Element 0 - aggregation level 1" #define GNB_CONFIG_HLP_CU_SIBS "List of CU generated SIBs to be transmitted" #define GNB_CONFIG_HLP_DU_SIBS "List of DU generated SIBs to be transmitted" -#define GNB_CONFIG_HLP_DOSINR "Enable CSI feedback using SINR measurements on SSB" +#define GNB_CONFIG_HLP_CONFIG_REP "Define quantity for CSI report (options: ssb_rsrp, ssb_sinr and cri_rsrp)" /*-----------------------------------------------------------------------------------------------------------------------------------------*/ @@ -201,7 +201,7 @@ typedef enum { GNB_CONFIG_HLP_UESS_AGG_LEVEL_LIST, 0, .iptr=NULL, .defintarrayval=NULL, TYPE_INTARRAY, 0}, \ {GNB_CONFIG_STRING_CU_SIB_LIST, GNB_CONFIG_HLP_CU_SIBS, 0, .iptr=NULL, .defintarrayval=0, TYPE_INTARRAY, 0}, \ {GNB_CONFIG_STRING_DU_SIB_LIST, GNB_CONFIG_HLP_DU_SIBS, 0, .iptr=NULL, .defintarrayval=0, TYPE_INTARRAY, 0}, \ -{GNB_CONFIG_STRING_DOSINR, GNB_CONFIG_HLP_DOSINR, 0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \ +{GNB_CONFIG_STRING_CONFIG_REP, GNB_CONFIG_HLP_CONFIG_REP, 0, .strptr=NULL, .defstrval="ssb_rsrp", TYPE_STRING, 0}, \ {GNB_CONFIG_STRING_1ST_ACTIVE_BWP, NULL, 0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \ {GNB_CONFIG_STRING_LIMIT_RSRP_REPORT, NULL, 0, .iptr=NULL, .defintval=0, TYPE_INT, 0}, \ } @@ -246,7 +246,7 @@ typedef enum { #define GNB_UESS_AGG_LEVEL_LIST_IDX 35 #define GNB_CU_SIBS_IDX 36 #define GNB_DU_SIBS_IDX 37 -#define GNB_DO_SINR_IDX 38 +#define GNB_CONFIG_REP_IDX 38 #define GNB_1ST_ACTIVE_BWP_IDX 39 #define GNB_LIMIT_RSRP_REPORT_IDX 40 @@ -293,7 +293,10 @@ typedef enum { { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ - { .s5 = { NULL } }, \ + { .s3a = { config_checkstr_assign_integer, \ + {"ssb_rsrp", "ssb_sinr", "cri_rsrp"}, \ + {SSB_RSRP, SSB_SINR, CRI_RSRP}, \ + 3 } }, \ { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ } diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index b7ebd5a651..f8b9f18c11 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -431,6 +431,14 @@ typedef struct { float_t ssb_sinr_dB; } NR_SSB_meas_t; +typedef struct { + int rsrp_dBm; + uint8_t ri; + uint16_t i1; + uint8_t i2; + uint8_t cqi; +} NR_CSIRS_meas_t; + typedef enum ta_type { no_ta = 0, adjustment_ta, @@ -601,9 +609,6 @@ typedef struct NR_UE_MAC_INST_s { nr_csi_report_t csi_report_template[MAX_CSI_REPORTCONFIG]; - /// measurements from SS or CSI-RS - fapi_nr_l1_measurements_t l1_measurements; - //// FAPI-like interface message fapi_nr_ul_config_request_t *ul_config_request; fapi_nr_dl_config_request_t *dl_config_request; @@ -633,6 +638,7 @@ typedef struct NR_UE_MAC_INST_s { int ssb_start_subcarrier; NR_SSB_meas_t ssb_measurements[MAX_NB_SSB]; + NR_CSIRS_meas_t csirs_measurements; dci_pdu_rel15_t def_dci_pdu_rel15[NR_MAX_SLOTS_PER_FRAME][8]; diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index 1f35df5c4b..c78d2217b4 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -307,7 +307,7 @@ void release_mac_configuration(NR_UE_MAC_INST_t *mac, NR_UE_MAC_reset_cause_t ca release_ul_BWP(mac, i); memset(&mac->ssb_measurements, 0, sizeof(mac->ssb_measurements)); - memset(&mac->l1_measurements, 0, sizeof(mac->l1_measurements)); + memset(&mac->csirs_measurements, 0, sizeof(mac->csirs_measurements)); memset(&mac->ul_time_alignment, 0, sizeof(mac->ul_time_alignment)); for (int i = mac->TAG_list.count; i > 0 ; i--) asn_sequence_del(&mac->TAG_list, i - 1, 1); 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 218a513ec7..8a2074422e 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -307,12 +307,7 @@ static void config_dci_pdu(NR_UE_MAC_INST_t *mac, break; } - for (int i = 0; i < sps; i++) { - if ((monitoringSymbolsWithinSlot >> (sps - 1 - i)) & 1) { - rel15->coreset.StartSymbolIndex = i; - break; - } - } + rel15->coreset.StartSymbolBitmap = monitoringSymbolsWithinSlot; uint32_t Y = 0; if (ss->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific) Y = get_Y(ss, slot, rel15->rnti); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 7818b08362..aeb15fe864 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -1508,13 +1508,18 @@ nr_dci_format_t nr_ue_process_dci_indication_pdu(NR_UE_MAC_INST_t *mac, frame_t void nr_ue_process_l1_measurements(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, fapi_nr_l1_measurements_t *l1_measurements) { - LOG_D(NR_MAC, "(%d.%d) Received CSI-RS measurements\n", frame, slot); - memcpy(&mac->l1_measurements, l1_measurements, sizeof(*l1_measurements)); + LOG_D(NR_MAC, "(%d.%d) Received measurements from L1\n", frame, slot); bool csi_meas = l1_measurements->meas_type == NFAPI_NR_CSI_MEAS; if (!csi_meas && !l1_measurements->is_neighboring_cell) { int ssb_index = l1_measurements->ssb_index; mac->ssb_measurements[ssb_index].ssb_rsrp_dBm = l1_measurements->rsrp_dBm; mac->ssb_measurements[ssb_index].ssb_sinr_dB = l1_measurements->sinr_dB; + } else if (csi_meas) { + mac->csirs_measurements.rsrp_dBm = l1_measurements->rsrp_dBm; + mac->csirs_measurements.i1 = l1_measurements->i1; + mac->csirs_measurements.i2 = l1_measurements->i2; + mac->csirs_measurements.cqi = l1_measurements->cqi; + mac->csirs_measurements.ri = l1_measurements->rank_indicator; } nr_mac_rrc_meas_ind_ue(mac->ue_id, l1_measurements->gNB_index, @@ -2790,13 +2795,13 @@ static csi_payload_t get_ssb_sinr_payload(NR_UE_MAC_INST_t *mac, } else nb_meas = 2; - struct NR_CSI_SSB_ResourceSet__csi_SSB_ResourceList SSB_resource; + struct NR_CSI_SSB_ResourceSet__csi_SSB_ResourceList *SSB_resource = NULL; for (int csi_ssb_idx = 0; csi_ssb_idx < csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.count; csi_ssb_idx++) { if (csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceSetId == *(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.array[0])) { - SSB_resource = csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceList; + SSB_resource = &csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceList; /// only one SSB resource set from spec 38.331 IE CSI-ResourceConfig - nb_ssb = SSB_resource.list.count; + nb_ssb = SSB_resource->list.count; break; } } @@ -2811,7 +2816,7 @@ static csi_payload_t get_ssb_sinr_payload(NR_UE_MAC_INST_t *mac, for (int measured_ssb_idx = 0; measured_ssb_idx < MAX_NB_SSB; measured_ssb_idx++) { // searching for the SSB index in the SSB resource table for (int ssb_resource = 0; ssb_resource < nb_ssb; ssb_resource++) { - if (*SSB_resource.list.array[ssb_resource] == measured_ssb_idx) { + if (*SSB_resource->list.array[ssb_resource] == measured_ssb_idx) { sorted_sinr_measurements[sorted_idx].ssb_index = ssb_resource; sorted_sinr_measurements[sorted_idx].ssb_rsrp_dBm = mac->ssb_measurements[measured_ssb_idx].ssb_rsrp_dBm; sorted_sinr_measurements[sorted_idx].ssb_sinr_dB = mac->ssb_measurements[measured_ssb_idx].ssb_sinr_dB; @@ -2822,25 +2827,20 @@ static csi_payload_t get_ssb_sinr_payload(NR_UE_MAC_INST_t *mac, } qsort(sorted_sinr_measurements, nb_ssb, sizeof(NR_RSRP_meas_t), compare_ssb_sinr); - uint8_t ssbi; - // TS38.212 v16.5.0: Table 6.3.1.1.2-8A - if (ssbri_bits > 0) { - ssbi = sorted_sinr_measurements[0].ssb_index; - temp_payload = reverse_bits(ssbi, ssbri_bits); - bits += ssbri_bits; + for (int i = 0; i < nb_meas; i++) { + if (ssbri_bits > 0) { + uint8_t ssbi = sorted_sinr_measurements[i].ssb_index; + temp_payload |= (reverse_bits(ssbi, ssbri_bits) << bits); + bits += ssbri_bits; + } } uint8_t sinr_idx = get_sinr_index(sorted_sinr_measurements[0].ssb_sinr_dB); temp_payload |= (reverse_bits(sinr_idx, 7) << bits); bits += 7; // 7 bits for highest SINR - // from the second SSB, differential report for (int i = 1; i < nb_meas; i++) { - ssbi = sorted_sinr_measurements[i].ssb_index; - temp_payload |= (reverse_bits(ssbi, ssbri_bits) << bits); - bits += ssbri_bits; - sinr_idx = get_sinr_diff_index(sorted_sinr_measurements[0].ssb_sinr_dB, sorted_sinr_measurements[i].ssb_sinr_dB); temp_payload |= (reverse_bits(sinr_idx, 4) << bits); bits += 4; // 4 bits for differential SINR @@ -2931,13 +2931,13 @@ static csi_payload_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac, } else nb_meas = 2; - struct NR_CSI_SSB_ResourceSet__csi_SSB_ResourceList SSB_resource; + struct NR_CSI_SSB_ResourceSet__csi_SSB_ResourceList *SSB_resource = NULL; for (int csi_ssb_idx = 0; csi_ssb_idx < csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.count; csi_ssb_idx++) { if (csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceSetId == *(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.array[0])){ - SSB_resource = csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceList; + SSB_resource = &csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_ssb_idx]->csi_SSB_ResourceList; ///only one SSB resource set from spec 38.331 IE CSI-ResourceConfig - nb_ssb = SSB_resource.list.count; + nb_ssb = SSB_resource->list.count; break; } } @@ -2952,7 +2952,7 @@ static csi_payload_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac, for (int measured_ssb_idx = 0; measured_ssb_idx < MAX_NB_SSB; measured_ssb_idx++) { // searching for the SSB index in the SSB resource table for (int ssb_resource = 0; ssb_resource < nb_ssb; ssb_resource++) { - if (*SSB_resource.list.array[ssb_resource] == measured_ssb_idx) { + if (*SSB_resource->list.array[ssb_resource] == measured_ssb_idx) { sorted_rsrp_measurements[sorted_idx].ssb_index = ssb_resource; sorted_rsrp_measurements[sorted_idx].ssb_rsrp_dBm = mac->ssb_measurements[measured_ssb_idx].ssb_rsrp_dBm; sorted_rsrp_measurements[sorted_idx].ssb_sinr_dB = mac->ssb_measurements[measured_ssb_idx].ssb_sinr_dB; @@ -2963,12 +2963,12 @@ static csi_payload_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac, } qsort(sorted_rsrp_measurements, nb_ssb, sizeof(NR_RSRP_meas_t), compare_ssb_rsrp); - uint32_t ssbi; - - if (ssbri_bits > 0) { - ssbi = sorted_rsrp_measurements[0].ssb_index; - temp_payload = reverse_bits(ssbi, ssbri_bits); - bits += ssbri_bits; + for (int i = 0; i < nb_meas; i++) { + if (ssbri_bits > 0) { + uint32_t ssbi = sorted_rsrp_measurements[i].ssb_index; + temp_payload |= (reverse_bits(ssbi, ssbri_bits) << bits); + bits += ssbri_bits; + } } uint8_t rsrp_idx = get_rsrp_index(sorted_rsrp_measurements[0].ssb_rsrp_dBm); @@ -2977,15 +2977,11 @@ static csi_payload_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac, // from the second SSB, differential report for (int i = 1; i < nb_meas; i++) { - ssbi = sorted_rsrp_measurements[i].ssb_index; - temp_payload |= (reverse_bits(ssbi, ssbri_bits) << bits); - bits += ssbri_bits; - rsrp_idx = get_rsrp_diff_index(sorted_rsrp_measurements[0].ssb_rsrp_dBm,sorted_rsrp_measurements[i].ssb_rsrp_dBm); temp_payload |= (reverse_bits(rsrp_idx, 4) << bits); bits += 4; // 4 bits for subsequent RSRP } - break; // resorce found + break; // resource found } } int max_bits = sizeof(((csi_payload_t *)0)->part1_payload) * 8; @@ -3026,28 +3022,28 @@ static csi_payload_t get_csirs_RI_PMI_CQI_payload(NR_UE_MAC_INST_t *mac, AssertFatal(csi_report, "Couldn't find CSI report with ID %ld\n", csi_reportconfig->reportConfigId); int cri_bitlen = csi_report->csi_meas_bitlen.cri_bitlen; int ri_bitlen = csi_report->csi_meas_bitlen.ri_bitlen; - int pmi_x1_bitlen = csi_report->csi_meas_bitlen.pmi_x1_bitlen[mac->l1_measurements.rank_indicator]; - int pmi_x2_bitlen = csi_report->csi_meas_bitlen.pmi_x2_bitlen[mac->l1_measurements.rank_indicator]; - int cqi_bitlen = csi_report->csi_meas_bitlen.cqi_bitlen[mac->l1_measurements.rank_indicator]; + int pmi_x1_bitlen = csi_report->csi_meas_bitlen.pmi_x1_bitlen[mac->csirs_measurements.ri]; + int pmi_x2_bitlen = csi_report->csi_meas_bitlen.pmi_x2_bitlen[mac->csirs_measurements.ri]; + int cqi_bitlen = csi_report->csi_meas_bitlen.cqi_bitlen[mac->csirs_measurements.ri]; int padding_bitlen = 0; // TODO: Improvements will be needed to cri_bitlen>0 and pmi_x1_bitlen>0 if (mapping_type == ON_PUSCH) { p1_bits = cri_bitlen + ri_bitlen + cqi_bitlen; p2_bits = pmi_x1_bitlen + pmi_x2_bitlen; temp_payload_1 = (0/*mac->csi_measurements.cri*/ << (cqi_bitlen + ri_bitlen)) | - (mac->l1_measurements.rank_indicator << cqi_bitlen) | - (mac->l1_measurements.cqi); - temp_payload_2 = (mac->l1_measurements.i1 << pmi_x2_bitlen) | - mac->l1_measurements.i2; + (mac->csirs_measurements.ri << cqi_bitlen) | + (mac->csirs_measurements.cqi); + temp_payload_2 = (mac->csirs_measurements.i1 << pmi_x2_bitlen) | + mac->csirs_measurements.i2; } else { p1_bits = nr_get_csi_bitlen(csi_report); padding_bitlen = p1_bits - (cri_bitlen + ri_bitlen + pmi_x1_bitlen + pmi_x2_bitlen + cqi_bitlen); temp_payload_1 = (0/*mac->csi_measurements.cri*/ << (cqi_bitlen + pmi_x2_bitlen + pmi_x1_bitlen + padding_bitlen + ri_bitlen)) | - (mac->l1_measurements.rank_indicator << (cqi_bitlen + pmi_x2_bitlen + pmi_x1_bitlen + padding_bitlen)) | - (mac->l1_measurements.i1 << (cqi_bitlen + pmi_x2_bitlen)) | - (mac->l1_measurements.i2 << (cqi_bitlen)) | - (mac->l1_measurements.cqi); + (mac->csirs_measurements.ri << (cqi_bitlen + pmi_x2_bitlen + pmi_x1_bitlen + padding_bitlen)) | + (mac->csirs_measurements.i1 << (cqi_bitlen + pmi_x2_bitlen)) | + (mac->csirs_measurements.i2 << (cqi_bitlen)) | + (mac->csirs_measurements.cqi); } temp_payload_1 = reverse_bits(temp_payload_1, p1_bits); @@ -3106,7 +3102,7 @@ static csi_payload_t get_csirs_RSRP_payload(NR_UE_MAC_INST_t *mac, } // TODO: Improvements will be needed to cri_ssbri_bitlen>0 - temp_payload = get_rsrp_index(mac->l1_measurements.rsrp_dBm); + temp_payload = get_rsrp_index(mac->csirs_measurements.rsrp_dBm); temp_payload = reverse_bits(temp_payload, n_bits); LOG_D(NR_MAC, "cri_ssbri_bitlen = %d\n", cri_ssbri_bitlen); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index f3de970683..e689a8a978 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -589,11 +589,13 @@ static void evaluate_rsrp_report(gNB_MAC_INST *nrmac, rsrp_report->nr_reports = csi_report->CSI_report_bitlen.nb_ssbri_cri; int bitlen = csi_report->CSI_report_bitlen.cri_ssbri_bitlen; - uint8_t curr_payload = pickandreverse_bits(payload, bitlen, *cumul_bits); - rsrp_report->resource_id[0] = *(index_list[bitlen > 0 ? ((curr_payload) & ~(~1U << (bitlen - 1))) : bitlen]); - *cumul_bits += bitlen; + for (int i = 0; i < rsrp_report->nr_reports; i++) { + uint8_t idx_payload = pickandreverse_bits(payload, bitlen, *cumul_bits); + rsrp_report->resource_id[i] = *(index_list[bitlen > 0 ? ((idx_payload) & ~(~1U << (bitlen - 1))) : bitlen]); + *cumul_bits += bitlen; + } - curr_payload = pickandreverse_bits(payload, 7, *cumul_bits); + uint8_t curr_payload = pickandreverse_bits(payload, 7, *cumul_bits); int rsrp = curr_payload & 0x7f; *cumul_bits += 7; csi_report->nb_of_csi_ssb_report++; @@ -605,10 +607,6 @@ static void evaluate_rsrp_report(gNB_MAC_INST *nrmac, } for (int i = 1; i < rsrp_report->nr_reports; i++) { - curr_payload = pickandreverse_bits(payload, bitlen, *cumul_bits); - rsrp_report->resource_id[i] = *(index_list[bitlen > 0 ? ((curr_payload) & ~(~1U << (bitlen - 1))) : bitlen]); - *cumul_bits += bitlen; - curr_payload = pickandreverse_bits(payload, 4, *cumul_bits); csi_report->nb_of_csi_ssb_report++; rsrp_report->RSRP[i] = get_diff_rsrp(curr_payload & 0x0f, rsrp_report->RSRP[0]); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index debc0d5530..064857a8e3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -967,6 +967,8 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc) ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup); UE->CellGroup = oldUE->CellGroup; oldUE->CellGroup = NULL; + UE->capability = oldUE->capability; + oldUE->capability = NULL; UE->mac_stats = oldUE->mac_stats; UE->measgap_config = oldUE->measgap_config; /* 38.331 5.3.7.2 says that the UE releases the spCellConfig, so we drop it diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 026d8d563e..dfad999e76 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -179,6 +179,12 @@ typedef struct { int location_and_bw; } nr_bwp_config_t; +typedef enum { + SSB_RSRP, + CRI_RSRP, + SSB_SINR, +} nr_config_report_type_t; + typedef struct nr_mac_config_t { int sib1_tda; nr_pdsch_AntennaPorts_t pdsch_AntennaPorts; @@ -207,7 +213,7 @@ typedef struct nr_mac_config_t { int num_agg_level_candidates[NUM_PDCCH_AGG_LEVELS]; nr_redcap_config_t *redcap; nr_ptrs_config_t *ptrs; - bool do_SINR; + nr_config_report_type_t report_type; } nr_mac_config_t; typedef struct NR_preamble_ue { diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c index a2b7c26678..99bf846d4d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c +++ b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.c @@ -2144,7 +2144,7 @@ static void config_rsrp_meas_report(NR_CSI_MeasConfig_t *csi_MeasConfig, for (int csi_list = 0; csi_list < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count; csi_list++) { NR_CSI_ResourceConfig_t *csires = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_list]; if (csires->csi_RS_ResourceSetList.present == NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB) { - if (configuration->do_CSIRS && num_antenna_ports < 4) { + if (configuration->report_type == CRI_RSRP && configuration->do_CSIRS && num_antenna_ports < 4) { if (csires->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList) resource_id = csires->csi_ResourceConfigId; } else { @@ -2166,20 +2166,19 @@ static void config_rsrp_meas_report(NR_CSI_MeasConfig_t *csi_MeasConfig, csirep->reportConfigType.choice.periodic = calloc(1, sizeof(*csirep->reportConfigType.choice.periodic)); set_csi_meas_periodicity(servingcellconfigcommon, csirep, uid, curr_bwp, true); asn1cSeqAdd(&csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list, pucchcsires); - if (configuration->do_CSIRS && num_antenna_ports < 4) { + if (configuration->report_type == SSB_SINR) { + csirep->reportQuantity.present = NR_CSI_ReportConfig__reportQuantity_PR_none; + csirep->reportQuantity.choice.none = (NULL_t)0; + csirep->ext2 = calloc(1, sizeof(*csirep->ext2)); + csirep->ext2->reportQuantity_r16 = calloc(1, sizeof(*csirep->ext2->reportQuantity_r16)); + csirep->ext2->reportQuantity_r16->present = NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_ssb_Index_SINR_r16; + csirep->ext2->reportQuantity_r16->choice.ssb_Index_SINR_r16 = (NULL_t)0; + } else if (configuration->report_type == CRI_RSRP && configuration->do_CSIRS && num_antenna_ports < 4) { csirep->reportQuantity.present = NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP; csirep->reportQuantity.choice.cri_RSRP = (NULL_t)0; } else { csirep->reportQuantity.present = NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP; csirep->reportQuantity.choice.ssb_Index_RSRP = (NULL_t)0; - if (configuration->do_SINR) { - csirep->reportQuantity.present = NR_CSI_ReportConfig__reportQuantity_PR_none; - csirep->reportQuantity.choice.none = (NULL_t)0; - csirep->ext2 = calloc(1, sizeof(*csirep->ext2)); - csirep->ext2->reportQuantity_r16 = calloc(1, sizeof(*csirep->ext2->reportQuantity_r16)); - csirep->ext2->reportQuantity_r16->present = NR_CSI_ReportConfig__ext2__reportQuantity_r16_PR_ssb_Index_SINR_r16; - csirep->ext2->reportQuantity_r16->choice.ssb_Index_SINR_r16 = (NULL_t)0; - } } csirep->groupBasedBeamReporting.present = NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled; csirep->groupBasedBeamReporting.choice.disabled = calloc(1, sizeof(*csirep->groupBasedBeamReporting.choice.disabled)); @@ -3867,8 +3866,15 @@ void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, NR_CSI_MeasConfig_t *csi_MeasConfig = spCellConfigDedicated->csi_MeasConfig->choice.setup; for (int report = 0; report < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; report++) { NR_CSI_ReportConfig_t *csirep = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[report]; - if(csirep->codebookConfig) + if (csirep->codebookConfig) config_csi_codebook(&configuration->pdsch_AntennaPorts, *pdsch_servingcellconfig->ext1->maxMIMO_Layers, csirep->codebookConfig); + if (csirep->groupBasedBeamReporting.present == NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled + && csirep->groupBasedBeamReporting.choice.disabled + && csirep->groupBasedBeamReporting.choice.disabled->nrofReportedRS) + *csirep->groupBasedBeamReporting.choice.disabled->nrofReportedRS = config_nrofReportedRS(uecap, + get_ssb_bitmap(scc), + scc, + configuration->max_num_rsrp); } NR_UplinkConfig_t *uplinkConfig = spCellConfigDedicated->uplinkConfig; diff --git a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c index b19ccceb22..ed9cc37c18 100644 --- a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c +++ b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c @@ -141,6 +141,24 @@ static instance_t get_f1_gtp_instance(void) return inst->gtpInst; } +/** @brief Add bearer in PDCP/SDAP for 5GC association (SA) */ +static void e1_add_bearers(const int ue_id, const NR_DRB_ToAddModList_t *addMod, const nr_pdcp_entity_security_keys_and_algos_t *sp) +{ + for (int i = 0; i < addMod->list.count; i++) { + NR_DRB_ToAddMod_t *drb = addMod->list.array[i]; + DevAssert(drb->cnAssociation); + DevAssert(drb->cnAssociation->present != NR_DRB_ToAddMod__cnAssociation_PR_NOTHING); + DevAssert(drb->cnAssociation->present == NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config); + DevAssert(drb->cnAssociation->choice.sdap_Config); + // get SDAP config + sdap_config_t sdap = nr_sdap_get_config(GNB_FLAG_YES, drb->cnAssociation->choice.sdap_Config, drb->drb_Identity); + // add SDAP entity + nr_sdap_addmod_entity(GNB_FLAG_YES, ue_id, sdap); + // add PDCP entity + nr_pdcp_add_drb(GNB_FLAG_YES, ue_id, drb->pdcp_Config, &sdap, sp); + } +} + void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req) { bool need_ue_id_mgmt = e1_used(); @@ -208,11 +226,10 @@ void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req) security_parameters.integrity_algorithm = req->secInfo.integrityProtectionAlgorithm; memcpy(security_parameters.ciphering_key, req->secInfo.encryptionKey, NR_K_KEY_SIZE); memcpy(security_parameters.integrity_key, req->secInfo.integrityProtectionKey, NR_K_KEY_SIZE); - nr_pdcp_add_drbs(true, // set this to notify PDCP that his not UE - cu_up_ue_id, - &DRB_configList, - &security_parameters); + + e1_add_bearers(cu_up_ue_id, &DRB_configList, &security_parameters); ASN_STRUCT_RESET(asn_DEF_NR_DRB_ToAddModList, &DRB_configList.list); + if (f1inst >= 0) { /* we have F1(-U) */ teid_t dummy_teid = 0xffff; // we will update later with answer from DU in_addr_t dummy_address = {0}; // IPv4, updated later with answer from DU diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index ce885b6b33..94d44fe8ce 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -575,75 +575,32 @@ void add_srb(int is_gnb, nr_pdcp_manager_unlock(nr_pdcp_ue_manager); } -void add_drb(int is_gnb, - ue_id_t UEid, - struct NR_DRB_ToAddMod *s, - const nr_pdcp_entity_security_keys_and_algos_t *security_parameters) +void nr_pdcp_add_drb(int is_gnb, + const ue_id_t UEid, + const NR_PDCP_Config_t *pdcp, + const sdap_config_t *sdap, + const nr_pdcp_entity_security_keys_and_algos_t *security_parameters) { - nr_pdcp_entity_t *pdcp_drb; nr_pdcp_ue_t *ue; - int drb_id = s->drb_Identity; - if (!s->pdcp_Config || !s->pdcp_Config->drb) { - LOG_E(PDCP, "DRB field mandatory present at setup. DRB %d not configured.\n", drb_id); + if (!pdcp->drb) { + LOG_E(PDCP, "Missing PDCP config. DRB %d not configured.\n", sdap->drb_id); return; } - struct NR_PDCP_Config__drb *drb = s->pdcp_Config->drb; + struct NR_PDCP_Config__drb *drb = pdcp->drb; int sn_size_ul = decode_sn_size_ul(*drb->pdcp_SN_SizeUL); int sn_size_dl = decode_sn_size_dl(*drb->pdcp_SN_SizeDL); int discard_timer = decode_discard_timer(*drb->discardTimer); - int has_integrity; - int has_ciphering; - /* if pdcp_Config->t_Reordering is not present, it means infinity (-1) */ int t_reordering = -1; - if (s->pdcp_Config->t_Reordering != NULL) { - t_reordering = decode_t_reordering(*s->pdcp_Config->t_Reordering); + if (pdcp->t_Reordering != NULL) { + t_reordering = decode_t_reordering(*pdcp->t_Reordering); } - if (drb->integrityProtection != NULL) - has_integrity = 1; - else - has_integrity = 0; - - if (s->pdcp_Config->ext1 != NULL && s->pdcp_Config->ext1->cipheringDisabled != NULL) - has_ciphering = 0; - else - has_ciphering = 1; - - if ((!s->cnAssociation) || s->cnAssociation->present == NR_DRB_ToAddMod__cnAssociation_PR_NOTHING) { - LOG_E(PDCP, "fatal, cnAssociation is missing or present is NR_DRB_ToAddMod__cnAssociation_PR_NOTHING\n"); - exit(-1); - } - - int pdusession_id; - bool has_sdap_rx = false; - bool has_sdap_tx = false; - bool is_sdap_DefaultDRB = false; - NR_QFI_t *mappedQFIs2Add = NULL; - uint8_t mappedQFIs2AddCount=0; - if (s->cnAssociation->present == NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity) - pdusession_id = s->cnAssociation->choice.eps_BearerIdentity; - else { - if (!s->cnAssociation->choice.sdap_Config) { - LOG_E(PDCP,"fatal, sdap_Config is null"); - exit(-1); - } - pdusession_id = s->cnAssociation->choice.sdap_Config->pdu_Session; - has_sdap_rx = is_sdap_rx(is_gnb, s->cnAssociation->choice.sdap_Config); - has_sdap_tx = is_sdap_tx(is_gnb, s->cnAssociation->choice.sdap_Config); - is_sdap_DefaultDRB = s->cnAssociation->choice.sdap_Config->defaultDRB == true ? 1 : 0; - mappedQFIs2Add = (NR_QFI_t*)s->cnAssociation->choice.sdap_Config->mappedQoS_FlowsToAdd->list.array[0]; - mappedQFIs2AddCount = s->cnAssociation->choice.sdap_Config->mappedQoS_FlowsToAdd->list.count; - LOG_D(SDAP, "Captured mappedQoS_FlowsToAdd from RRC: %ld \n", *mappedQFIs2Add); - } - /* TODO(?): accept different UL and DL SN sizes? */ - if (sn_size_ul != sn_size_dl) { - LOG_E(PDCP, "fatal, bad SN sizes, must be same. ul=%d, dl=%d\n", sn_size_ul, sn_size_dl); - exit(1); - } + int has_integrity = (drb->integrityProtection != NULL) ? 1 : 0; + int has_ciphering = (pdcp->ext1 != NULL && pdcp->ext1->cipheringDisabled != NULL) ? 0 : 1; /* get actual ciphering and integrity algorithm based on pdcp_Config */ nr_pdcp_entity_security_keys_and_algos_t actual_security_parameters = *security_parameters; @@ -652,29 +609,33 @@ void add_drb(int is_gnb, nr_pdcp_manager_lock(nr_pdcp_ue_manager); ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, UEid); - if (nr_pdcp_get_rb(ue, drb_id, false) != NULL) { - LOG_W(PDCP, "warning DRB %d already exist for UE ID %ld, do nothing\n", drb_id, UEid); + if (nr_pdcp_get_rb(ue, sdap->drb_id, false) != NULL) { + LOG_W(PDCP, "warning DRB %d already exist for UE ID %ld, do nothing\n", sdap->drb_id, UEid); } else { - pdcp_drb = new_nr_pdcp_entity(NR_PDCP_DRB_AM, is_gnb, drb_id, pdusession_id, - has_sdap_rx, has_sdap_tx, deliver_sdu_drb, ue, - is_gnb ? - deliver_pdu_drb_gnb : deliver_pdu_drb_ue, - ue, - sn_size_dl, t_reordering, discard_timer, - &actual_security_parameters); - nr_pdcp_ue_add_drb_pdcp_entity(ue, drb_id, pdcp_drb); + // code assumption: same SN size for both DL and UL + if (sn_size_ul != sn_size_dl) { + LOG_E(PDCP, "fatal, bad SN sizes, must be same. ul=%d, dl=%d\n", sn_size_ul, sn_size_dl); + exit(1); + } - LOG_I(PDCP, "added drb %d to UE ID %ld\n", drb_id, UEid); - /* add new SDAP entity for the PDU session the DRB belongs to */ - new_nr_sdap_entity(is_gnb, - has_sdap_rx, - has_sdap_tx, - UEid, - pdusession_id, - is_sdap_DefaultDRB, - drb_id, - mappedQFIs2Add, - mappedQFIs2AddCount); + // add PDCP entity + nr_pdcp_entity_t *pdcp_drb = new_nr_pdcp_entity(NR_PDCP_DRB_AM, + is_gnb, + sdap->drb_id, + sdap->pdusession_id, + (sdap->role & (SDAP_UL_RX | SDAP_DL_RX)) != 0, + (sdap->role & (SDAP_UL_TX | SDAP_DL_TX)) != 0, + deliver_sdu_drb, + ue, + is_gnb ? deliver_pdu_drb_gnb : deliver_pdu_drb_ue, + ue, + sn_size_dl, + t_reordering, + discard_timer, + &actual_security_parameters); + nr_pdcp_ue_add_drb_pdcp_entity(ue, sdap->drb_id, pdcp_drb); + + LOG_I(PDCP, "Added DRB %d to UE ID %ld\n", sdap->drb_id, UEid); } nr_pdcp_manager_unlock(nr_pdcp_ue_manager); } @@ -692,22 +653,6 @@ void nr_pdcp_add_srbs(eNB_flag_t enb_flag, LOG_W(PDCP, "nr_pdcp_add_srbs() with void list\n"); } -void nr_pdcp_add_drbs(eNB_flag_t enb_flag, - ue_id_t UEid, - NR_DRB_ToAddModList_t *const drb2add_list, - const nr_pdcp_entity_security_keys_and_algos_t *security_parameters) -{ - if (drb2add_list != NULL) { - for (int i = 0; i < drb2add_list->list.count; i++) { - add_drb(enb_flag, - UEid, - drb2add_list->list.array[i], - security_parameters); - } - } else - LOG_W(PDCP, "nr_pdcp_add_drbs() with void list\n"); -} - uint64_t get_pdcp_optmask(void) { return pdcp_optmask; diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h index 375bd27458..884ea11f60 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h @@ -33,6 +33,7 @@ #include "nr_pdcp_ue_manager.h" struct NR_DRB_ToAddMod; struct NR_SRB_ToAddMod; +struct sdap_configuration_s; void nr_pdcp_layer_init(void); @@ -42,20 +43,16 @@ bool nr_pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP, const sdu_size_t sdu_buffer_size, uint8_t *const sdu_buffer); -void nr_pdcp_add_drbs(eNB_flag_t enb_flag, - ue_id_t UEid, - NR_DRB_ToAddModList_t *const drb2add_list, - const nr_pdcp_entity_security_keys_and_algos_t *security_parameters); - void nr_pdcp_add_srbs(eNB_flag_t enb_flag, ue_id_t UEid, NR_SRB_ToAddModList_t *const srb2add_list, const nr_pdcp_entity_security_keys_and_algos_t *security_parameters); -void add_drb(int is_gnb, - ue_id_t UEid, - struct NR_DRB_ToAddMod *s, - const nr_pdcp_entity_security_keys_and_algos_t *security_parameters); +void nr_pdcp_add_drb(int is_gnb, + const ue_id_t UEid, + const NR_PDCP_Config_t *pdcp, + const struct sdap_configuration_s *sdap, + const nr_pdcp_entity_security_keys_and_algos_t *security_parameters); void nr_pdcp_remove_UE(ue_id_t ue_id); void nr_pdcp_reestablishment(ue_id_t ue_id, diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 35b21a9722..2136e966ab 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -1020,7 +1020,7 @@ int do_RRCReestablishment(int8_t nh_ncc, uint8_t *const buffer, size_t buffer_si rrcReestablishment->criticalExtensions.choice.rrcReestablishment = CALLOC(1, sizeof(NR_RRCReestablishment_IEs_t)); // 3GPP TS 33.501 Section 6.11 Security handling for RRC connection re-establishment procedure - rrcReestablishment->criticalExtensions.choice.rrcReestablishment->nextHopChainingCount = nh_ncc >= 0 ? nh_ncc : 0; + rrcReestablishment->criticalExtensions.choice.rrcReestablishment->nextHopChainingCount = nh_ncc; rrcReestablishment->criticalExtensions.choice.rrcReestablishment->lateNonCriticalExtension = NULL; rrcReestablishment->criticalExtensions.choice.rrcReestablishment->nonCriticalExtension = NULL; diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index e76802338c..27e17e03f0 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -188,7 +188,6 @@ typedef struct gNB_RRC_UE_s { /* KgNB as derived from KASME received from EPC */ uint8_t kgnb[32]; - int8_t kgnb_ncc; uint8_t nh[32]; int8_t nh_ncc; @@ -209,6 +208,8 @@ typedef struct gNB_RRC_UE_s { uint64_t amf_ue_ngap_id; // Globally Unique AMF Identifier nr_guami_t ue_guami; + // Serving PLMN of the UE + plmn_id_t serving_plmn; ngap_security_capabilities_t security_capabilities; //NSA block diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index c2734c755a..97d0feda67 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -998,8 +998,7 @@ static void rrc_gNB_generate_RRCReestablishment(rrc_gNB_ue_context_t *ue_context const f1ap_served_cell_info_t *cell_info = &du->setup_req->cell[0].info; uint32_t ssb_arfcn = get_ssb_arfcn(du); LOG_I(NR_RRC, "Reestablishment update key pci=%d, earfcn_dl=%u\n", cell_info->nr_pci, ssb_arfcn); - nr_derive_key_ng_ran_star(cell_info->nr_pci, ssb_arfcn, ue_p->nh_ncc >= 0 ? ue_p->nh : ue_p->kgnb, ue_p->kgnb); - ue_p->kgnb_ncc = 0; + nr_derive_key_ng_ran_star(cell_info->nr_pci, ssb_arfcn, ue_p->nh_ncc > 0 ? ue_p->nh : ue_p->kgnb, ue_p->kgnb); int size = do_RRCReestablishment(ue_context_pP->ue_context.nh_ncc, buffer, NR_RRC_BUF_SIZE, xid); LOG_A(NR_RRC, "Send RRCReestablishment [%d bytes] to RNTI %04x\n", size, ue_p->rnti); diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 7d75384a9b..3b30341371 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -110,6 +110,24 @@ static const uint16_t NGAP_INTEGRITY_NIA3_MASK = 0x2000; static void set_UE_security_algos(const gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const ngap_security_capabilities_t *cap); +/** @brief Validates PLMN against allowed PLMN list and returns pointer to matching PLMN + * @param rrc RRC instance + * @param plmn PLMN to validate + * @return pointer to matching PLMN in configuration, or NULL if not found */ +static const plmn_id_t *get_serving_plmn(gNB_RRC_INST *rrc, const plmn_id_t *plmn) +{ + // Find matching PLMN in configuration + for (int idx = 0; idx < rrc->configuration.num_plmn; idx++) { + const plmn_id_t *allowed = &rrc->configuration.plmn[idx]; + if (allowed->mcc == plmn->mcc && allowed->mnc == plmn->mnc && allowed->mnc_digit_length == plmn->mnc_digit_length) { + LOG_D(NR_RRC, "PLMN (MCC:%d, MNC:%*d) matched with allowed PLMN[%d]\n", plmn->mcc, plmn->mnc_digit_length, plmn->mnc, idx); + return allowed; + } + } + LOG_W(NR_RRC, "PLMN (MCC:%d, MNC:%*d) not found in allowed PLMN list\n", plmn->mcc, plmn->mnc_digit_length, plmn->mnc); + return NULL; +} + /*! *\brief save security key. *\param UE UE context. @@ -122,7 +140,9 @@ static void set_UE_security_key(gNB_RRC_UE_t *UE, uint8_t *security_key_pP) /* Saves the security key */ memcpy(UE->kgnb, security_key_pP, SECURITY_KEY_LENGTH); memset(UE->nh, 0, SECURITY_KEY_LENGTH); - UE->nh_ncc = -1; + /* 3GPP TS 33.501 §6.9.2.1.1: On Initial Context Setup, AMF does not send NH; + * gNB shall initialize NCC to 0. */ + UE->nh_ncc = 0; char ascii_buffer[65]; for (i = 0; i < 32; i++) { @@ -165,9 +185,7 @@ static nr_guami_t get_guami(const uint32_t amf_Id, const plmn_id_t plmn) guami.amf_region_id = (amf_Id >> 16) & 0xff; guami.amf_set_id = (amf_Id >> 6) & 0x3ff; guami.amf_pointer = amf_Id & 0x3f; - guami.mcc = plmn.mcc; - guami.mnc = plmn.mnc; - guami.mnc_len = plmn.mnc_digit_length; + guami.plmn = plmn; return guami; } @@ -223,17 +241,22 @@ void rrc_gNB_send_NGAP_NAS_FIRST_REQ(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, NR_RRC req->nas_pdu = create_byte_array(rrcSetupComplete->dedicatedNAS_Message.size, rrcSetupComplete->dedicatedNAS_Message.buf); /* Selected PLMN Identity (Optional) - * selectedPLMN-Identity in RRCSetupComplete: Index of the PLMN selected by the UE from the plmn-IdentityInfoList (SIB1) - * Selected PLMN Identity in INITIAL UE MESSAGE: Indicates the selected PLMN id for the non-3GPP access.*/ - if (rrcSetupComplete->selectedPLMN_Identity > rrc->configuration.num_plmn) { + * selectedPLMN-Identity in RRCSetupComplete: Index of the PLMN selected by the UE from the plmn-IdentityInfoList (SIB1) */ + int idx = rrcSetupComplete->selectedPLMN_Identity - 1; // Convert 1-based PLMN Identity IE to 0-based index + if (idx < 0 || idx >= rrc->configuration.num_plmn) { LOG_E(NGAP, - "Failed to send Initial UE Message: selected PLMN (%ld) identity is out of bounds (%d)\n", - rrcSetupComplete->selectedPLMN_Identity, + "Failed to send Initial UE Message: selected PLMN index (%d) is out of bounds [0..%d)\n", + idx, rrc->configuration.num_plmn); return; } - int selected_plmn_identity = rrcSetupComplete->selectedPLMN_Identity - 1; // Convert 1-based PLMN Identity IE to 0-based index - req->plmn = rrc->configuration.plmn[selected_plmn_identity]; // Select from the stored list + req->plmn = rrc->configuration.plmn[idx]; // Select from the stored list + /* UE is connected to only one PLMN at a time: store this as the serving PLMN */ + UE->serving_plmn = req->plmn; + + // Cell ID (NR CGI) + req->nr_cell_id = UE->nr_cellid; + // PLMN (NR CGI and TAI) plmn_id_t *p = &req->plmn; LOG_I(NGAP, "Selected PLMN in the NG Initial UE Message: MCC=%03d MNC=%0*d\n", p->mcc, p->mnc_digit_length, p->mnc); @@ -721,6 +744,10 @@ void rrc_gNB_send_NGAP_UPLINK_NAS(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const NR_ NGAP_UPLINK_NAS(msg_p).gNB_ue_ngap_id = UE->rrc_ue_id; NGAP_UPLINK_NAS(msg_p).nas_pdu.len = nas->size; NGAP_UPLINK_NAS(msg_p).nas_pdu.buf = buf; + /* Fill PLMN and location info: use serving PLMN of the UE */ + NGAP_UPLINK_NAS(msg_p).plmn = UE->serving_plmn; + NGAP_UPLINK_NAS(msg_p).nr_cell_id = rrc->nr_cellid; + NGAP_UPLINK_NAS(msg_p).tac = rrc->configuration.tac; itti_send_msg_to_task(TASK_NGAP, rrc->module_id, msg_p); } @@ -1154,6 +1181,20 @@ int rrc_gNB_process_Handover_Request(gNB_RRC_INST *rrc, instance_t instance, nga rrc_gNB_send_NGAP_HANDOVER_FAILURE(rrc, &fail); return -1; } + + // Validate PLMN from GUAMI against allowed PLMN list + const plmn_id_t *serving_plmn = get_serving_plmn(rrc, &msg->guami.plmn); + if (!serving_plmn) { + LOG_E(NR_RRC, "PLMN from GUAMI not supported - rejecting handover\n"); + ngap_handover_failure_t fail = { + .amf_ue_ngap_id = msg->amf_ue_ngap_id, + .cause.type = NGAP_CAUSE_RADIO_NETWORK, + .cause.value = NGAP_CAUSE_RADIO_NETWORK_HO_TARGET_NOT_ALLOWED, + }; + rrc_gNB_send_NGAP_HANDOVER_FAILURE(rrc, &fail); + return -1; + } + uint16_t pci = du->setup_req->cell[0].info.nr_pci; LOG_I(NR_RRC, "Received Handover Request (on NR Cell ID=%lu, PCI=%u) \n", msg->nr_cell_id, pci); @@ -1169,6 +1210,9 @@ int rrc_gNB_process_Handover_Request(gNB_RRC_INST *rrc, instance_t instance, nga // Store IDs in UE context UE->amf_ue_ngap_id = msg->amf_ue_ngap_id; UE->ue_guami = msg->guami; + // Store the serving PLMN + UE->serving_plmn = *serving_plmn; + UE->ho_context->target->ue_ho_prep_info = copy_byte_array(msg->ue_ho_prep_info); // store the received UE Security Capabilities in the UE context FREE_AND_ZERO_BYTE_ARRAY(UE->ue_cap_buffer); diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index f0f7201517..996dc3528e 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -161,6 +161,28 @@ static NR_RadioBearerConfig_t *get_default_rbconfig(int eps_bearer_id, return rbconfig; } +static void rrc_nsa_add_drb(const int ue_id, + const NR_DRB_ToAddModList_t *addMod, + const nr_pdcp_entity_security_keys_and_algos_t *sp) +{ + for (int i = 0; i < addMod->list.count; i++) { + NR_DRB_ToAddMod_t *drb = addMod->list.array[i]; + DevAssert(drb->cnAssociation); + DevAssert(drb->cnAssociation->present != NR_DRB_ToAddMod__cnAssociation_PR_NOTHING); + DevAssert(drb->cnAssociation->present == NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity); + // get SDAP config + sdap_config_t sdap = {0}; + // EPC association + sdap.pdusession_id = drb->cnAssociation->choice.eps_BearerIdentity; + sdap.drb_id = drb->drb_Identity; + sdap.defaultDRB = true; + // add SDAP entity (terminated at gNB, since it's EPC) + nr_sdap_addmod_entity(GNB_FLAG_YES, ue_id, sdap); + // add PDCP entity + nr_pdcp_add_drb(GNB_FLAG_YES, ue_id, drb->pdcp_Config, &sdap, sp); + } +} + /* generate prototypes for the tree management functions (RB_INSERT used in rrc_add_nsa_user) */ RB_PROTOTYPE(rrc_nr_ue_tree_s, rrc_gNB_ue_context_s, entries, rrc_gNB_compare_ue_rnti_id); @@ -304,10 +326,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, x2ap_ENDC_sgnb_addition_req_t *m, sctp_ } DevAssert(UE->rb_config != NULL); - nr_pdcp_add_drbs(GNB_FLAG_YES, - UE->rrc_ue_id, - UE->rb_config->drb_ToAddModList, - &security_parameters); + rrc_nsa_add_drb(UE->rrc_ue_id, UE->rb_config->drb_ToAddModList, &security_parameters); /* assumption: only a single bearer, see above */ NR_DRB_ToAddModList_t *rb_list = UE->rb_config->drb_ToAddModList; diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index d23dd14c58..6681eed855 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -599,6 +599,31 @@ static void nr_rrc_process_dedicatedNAS_MessageList(NR_UE_RRC_INST_t *rrc, NR_RR } } +/** @brief Add bearer in PDCP/SDAP for 5GC association (SA) */ +static void rrc_ue_add_bearer(const int ue_id, const NR_DRB_ToAddMod_t *drb, const nr_pdcp_entity_security_keys_and_algos_t *sp) +{ + DevAssert(drb->cnAssociation); + DevAssert(drb->cnAssociation->present != NR_DRB_ToAddMod__cnAssociation_PR_NOTHING); + // get SDAP config + sdap_config_t sdap = {0}; + if (drb->cnAssociation->present == NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity) { + DevAssert(drb->cnAssociation->present == NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity); + + // EPC association + sdap.pdusession_id = drb->cnAssociation->choice.eps_BearerIdentity; + sdap.drb_id = drb->drb_Identity; + sdap.defaultDRB = true; + } else { + DevAssert(drb->cnAssociation->present == NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config); + DevAssert(drb->cnAssociation->choice.sdap_Config); + sdap = nr_sdap_get_config(GNB_FLAG_NO, drb->cnAssociation->choice.sdap_Config, drb->drb_Identity); + } + // add SDAP entity + nr_sdap_addmod_entity(GNB_FLAG_NO, ue_id, sdap); + // add PDCP entity + nr_pdcp_add_drb(GNB_FLAG_NO, ue_id, drb->pdcp_Config, &sdap, sp); +} + /** * @brief add, modify and release SRBs and/or DRBs * @ref 3GPP TS 38.331 @@ -706,10 +731,7 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc, NR_Rad nr_reconfigure_sdap_entity(sdap_Config, ue_rrc->ue_id, sdap_Config->pdu_Session, DRB_id); } else { set_DRB_status(ue_rrc ,DRB_id, RB_ESTABLISHED); - add_drb(false, - ue_rrc->ue_id, - radioBearerConfig->drb_ToAddModList->list.array[cnt], - &security_up_parameters); + rrc_ue_add_bearer(ue_rrc->ue_id, radioBearerConfig->drb_ToAddModList->list.array[cnt], &security_up_parameters); } } } // drb_ToAddModList // diff --git a/openair2/SDAP/nr_sdap/nr_sdap.c b/openair2/SDAP/nr_sdap/nr_sdap.c index f6602c7597..1aec02814e 100644 --- a/openair2/SDAP/nr_sdap/nr_sdap.c +++ b/openair2/SDAP/nr_sdap/nr_sdap.c @@ -47,7 +47,6 @@ static void reblock_tun_socket(int fd) bool sdap_data_req(protocol_ctxt_t *ctxt_p, const ue_id_t ue_id, const srb_flag_t srb_flag, - const rb_id_t rb_id, const mui_t mui, const confirm_t confirm, const sdu_size_t sdu_buffer_size, @@ -69,7 +68,6 @@ bool sdap_data_req(protocol_ctxt_t *ctxt_p, bool ret = sdap_entity->tx_entity(sdap_entity, ctxt_p, srb_flag, - rb_id, mui, confirm, sdu_buffer_size, @@ -82,7 +80,7 @@ bool sdap_data_req(protocol_ctxt_t *ctxt_p, return ret; } -void sdap_data_ind(rb_id_t pdcp_entity, +void sdap_data_ind(int pdcp_entity, int is_gnb, bool has_sdap_rx, int pdusession_id, @@ -100,7 +98,6 @@ void sdap_data_ind(rb_id_t pdcp_entity, sdap_entity->rx_entity(sdap_entity, pdcp_entity, is_gnb, - has_sdap_rx, pdusession_id, ue_id, buf, @@ -116,8 +113,6 @@ static void *sdap_tun_read_thread(void *arg) int len; reblock_tun_socket(entity->pdusession_sock); - int rb_id = 1; - while (!entity->stop_thread) { len = read(entity->pdusession_sock, &rx_buf, NL_MAX_PAYLOAD); if (len == -1) { @@ -148,7 +143,6 @@ static void *sdap_tun_read_thread(void *arg) entity->tx_entity(entity, &ctxt, SRB_FLAG_NO, - rb_id, RLC_MUI_UNDEFINED, RLC_SDU_CONFIRM_NO, len, diff --git a/openair2/SDAP/nr_sdap/nr_sdap.h b/openair2/SDAP/nr_sdap/nr_sdap.h index 3877e58603..1164641970 100644 --- a/openair2/SDAP/nr_sdap/nr_sdap.h +++ b/openair2/SDAP/nr_sdap/nr_sdap.h @@ -35,7 +35,6 @@ bool sdap_data_req(protocol_ctxt_t *ctxt_p, const ue_id_t ue_id, const srb_flag_t srb_flag, - const rb_id_t rb_id, const mui_t mui, const confirm_t confirm, const sdu_size_t sdu_buffer_size, @@ -53,7 +52,7 @@ bool sdap_data_req(protocol_ctxt_t *ctxt_p, * Uplink - gNB * Downlink - nrUE */ -void sdap_data_ind(rb_id_t pdcp_entity, +void sdap_data_ind(int pdcp_entity, int is_gnb, bool has_sdap_rx, int pdusession_id, diff --git a/openair2/SDAP/nr_sdap/nr_sdap_entity.c b/openair2/SDAP/nr_sdap/nr_sdap_entity.c index 6860fba6e6..f0e791c683 100644 --- a/openair2/SDAP/nr_sdap/nr_sdap_entity.c +++ b/openair2/SDAP/nr_sdap/nr_sdap_entity.c @@ -34,6 +34,8 @@ #include "tun_if.h" #include "nr_sdap.h" +#define NO_SDAP_HEADER 0 + typedef struct { nr_sdap_entity_t *sdap_entity_llist; } nr_sdap_entity_info; @@ -42,35 +44,22 @@ static nr_sdap_entity_info sdap_info; instance_t *N3GTPUInst = NULL; -/** - * @brief indicates whether it is a receiving SDAP entity - * i.e. for UE, header for DL data is present - * for gNB, header for UL data is present - */ -bool is_sdap_rx(bool is_gnb, NR_SDAP_Config_t *sdap_config) +/** @brief Returns a bitmap indicating the SDAP entity role, + * i.e. for UL transmission, header for UL data is present in RX/TX + * for DL transmission, header for DL data is present in RX/TX */ +static int get_sdap_role(bool is_gnb, const NR_SDAP_Config_t *sdap_config) { - if (is_gnb) { - return sdap_config->sdap_HeaderUL == NR_SDAP_Config__sdap_HeaderUL_present; - } else { - return sdap_config->sdap_HeaderDL == NR_SDAP_Config__sdap_HeaderDL_present; - } + sdap_role_t role_ul = is_gnb ? SDAP_UL_RX : SDAP_UL_TX; + sdap_role_t role_dl = is_gnb ? SDAP_DL_TX : SDAP_DL_RX; + int role = NO_SDAP_HEADER; + if (sdap_config->sdap_HeaderUL == NR_SDAP_Config__sdap_HeaderUL_present) + role |= role_ul; + if (sdap_config->sdap_HeaderDL == NR_SDAP_Config__sdap_HeaderDL_present) + role |= role_dl; + return role; } -/** - * @brief indicates whether it is a transmitting SDAP entity - * i.e. for UE, header for UL data is present - * for gNB, header for DL data is present - */ -bool is_sdap_tx(bool is_gnb, NR_SDAP_Config_t *sdap_config) -{ - if (is_gnb) { - return sdap_config->sdap_HeaderDL == NR_SDAP_Config__sdap_HeaderDL_present; - } else { - return sdap_config->sdap_HeaderUL == NR_SDAP_Config__sdap_HeaderUL_present; - } -} - -void nr_pdcp_submit_sdap_ctrl_pdu(ue_id_t ue_id, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu) +void nr_pdcp_submit_sdap_ctrl_pdu(ue_id_t ue_id, int sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu) { protocol_ctxt_t ctxt = { .rntiMaybeUEid = ue_id }; @@ -84,7 +73,7 @@ void nr_pdcp_submit_sdap_ctrl_pdu(ue_id_t ue_id, rb_id_t sdap_ctrl_pdu_drb, nr_s PDCP_TRANSMISSION_MODE_UNKNOWN, NULL, NULL); - LOG_D(SDAP, "Control PDU - Submitting Control PDU to DRB ID: %ld\n", sdap_ctrl_pdu_drb); + LOG_D(SDAP, "Control PDU - Submitting Control PDU to DRB ID: %d\n", sdap_ctrl_pdu_drb); LOG_D(SDAP, "QFI: %u\n R: %u\n D/C: %u\n", ctrl_pdu.QFI, ctrl_pdu.R, ctrl_pdu.DC); return; } @@ -92,7 +81,6 @@ void nr_pdcp_submit_sdap_ctrl_pdu(ue_id_t ue_id, rb_id_t sdap_ctrl_pdu_drb, nr_s static bool nr_sdap_tx_entity(nr_sdap_entity_t *entity, protocol_ctxt_t *ctxt_p, const srb_flag_t srb_flag, - const rb_id_t rb_id, const mui_t mui, const confirm_t confirm, const sdu_size_t sdu_buffer_size, @@ -105,9 +93,8 @@ static bool nr_sdap_tx_entity(nr_sdap_entity_t *entity, /* The offset of the SDAP header, it might be 0 if has_sdap_tx is not true in the pdcp entity. */ int offset=0; bool ret = false; - /*Hardcode DRB ID given from upper layer (ue/gnb_tun_read_thread rb_id), it will change if we have SDAP*/ - rb_id_t sdap_drb_id = rb_id; - int pdcp_ent_has_sdap = 0; + bool sdap_ul_tx = false; + bool sdap_dl_tx = false; if(sdu_buffer == NULL) { LOG_E(SDAP, "%s:%d:%s: NULL sdu_buffer \n", __FILE__, __LINE__, __FUNCTION__); @@ -115,19 +102,22 @@ static bool nr_sdap_tx_entity(nr_sdap_entity_t *entity, } uint8_t sdap_buf[SDAP_MAX_PDU]; - rb_id_t pdcp_entity = entity->qfi2drb_map(entity, qfi); + int drb_id = entity->qfi2drb_map(entity, qfi); - if(pdcp_entity){ - sdap_drb_id = pdcp_entity; - pdcp_ent_has_sdap = entity->qfi2drb_table[qfi].has_sdap_tx; - LOG_D(SDAP, "TX - QFI: %u is mapped to DRB ID: %ld\n", qfi, entity->qfi2drb_table[qfi].drb_id); + if (drb_id != SDAP_MAP_RULE_EMPTY) { + sdap_ul_tx = entity->qfi2drb_table[qfi].entity_role & SDAP_UL_TX; // UE TX entity + sdap_dl_tx = entity->qfi2drb_table[qfi].entity_role & SDAP_DL_TX; // gNB TX entity + LOG_D(SDAP, "TX - QFI: %u is mapped to DRB ID: %d\n", qfi, entity->qfi2drb_table[qfi].drb_id); + } else { + LOG_E(SDAP, "QFI %u not mapped to any DRB - dropping SDU of size %d\n", qfi, sdu_buffer_size); + return false; } - if(!pdcp_ent_has_sdap){ - LOG_D(SDAP, "TX - DRB ID: %ld does not have SDAP\n", entity->qfi2drb_table[qfi].drb_id); + if (!sdap_ul_tx && !sdap_dl_tx) { + LOG_D(SDAP, "TX - DRB ID: %d does not have SDAP header\n", entity->qfi2drb_table[qfi].drb_id); ret = nr_pdcp_data_req_drb(ctxt_p, srb_flag, - sdap_drb_id, + drb_id, mui, confirm, sdu_buffer_size, @@ -147,7 +137,7 @@ static bool nr_sdap_tx_entity(nr_sdap_entity_t *entity, return 0; } - if(ctxt_p->enb_flag) { // gNB + if (sdap_dl_tx) { // create DL Data PDU with SDAP header offset = SDAP_HDR_LENGTH; /* * TS 37.324 4.4 Functions @@ -165,7 +155,7 @@ static bool nr_sdap_tx_entity(nr_sdap_entity_t *entity, LOG_D(SDAP, "TX Entity QFI: %u \n", sdap_hdr.QFI); LOG_D(SDAP, "TX Entity RQI: %u \n", sdap_hdr.RQI); LOG_D(SDAP, "TX Entity RDI: %u \n", sdap_hdr.RDI); - } else { // nrUE + } else if (sdap_ul_tx) { // create UL Data PDU with SDAP header offset = SDAP_HDR_LENGTH; /* * TS 37.324 4.4 Functions @@ -195,7 +185,7 @@ static bool nr_sdap_tx_entity(nr_sdap_entity_t *entity, */ ret = nr_pdcp_data_req_drb(ctxt_p, srb_flag, - sdap_drb_id, + drb_id, mui, confirm, sdu_buffer_size + offset, @@ -211,9 +201,8 @@ static bool nr_sdap_tx_entity(nr_sdap_entity_t *entity, } static void nr_sdap_rx_entity(nr_sdap_entity_t *entity, - rb_id_t pdcp_entity, + int pdcp_entity, int is_gnb, - bool has_sdap_rx, int pdusession_id, ue_id_t ue_id, char *buf, @@ -221,9 +210,18 @@ static void nr_sdap_rx_entity(nr_sdap_entity_t *entity, { /* The offset of the SDAP header, it might be 0 if has_sdap_rx is not true in the pdcp entity. */ int offset=0; + int qfi = buf[0] & 0x3F; // QFI is always the first 6 bits in the first octet + if (qfi <= 0 || qfi >= SDAP_MAX_QFI) { + LOG_E(SDAP, "Invalid QFI %d received in SDAP header\n", qfi); + return; + } + + // Fetch entity role from the qfi2drb_table + bool sdap_ul_rx = entity->qfi2drb_table[qfi].entity_role & SDAP_UL_RX; // gNB RX entity + bool sdap_dl_rx = entity->qfi2drb_table[qfi].entity_role & SDAP_DL_RX; // UE RX entity if (is_gnb) { // gNB - if (has_sdap_rx) { // Handling the SDAP Header + if (sdap_ul_rx) { // UL Data/Control PDU with SDAP header offset = SDAP_HDR_LENGTH; nr_sdap_ul_hdr_t *sdap_hdr = (nr_sdap_ul_hdr_t *)buf; LOG_D(SDAP, "RX Entity Received QFI: %u\n", sdap_hdr->QFI); @@ -255,7 +253,7 @@ static void nr_sdap_rx_entity(nr_sdap_entity_t *entity, * 5.2.2 Downlink * if the DRB from which this SDAP data PDU is received is configured by RRC with the presence of SDAP header. */ - if (has_sdap_rx) { // Handling the SDAP Header + if (sdap_dl_rx) { // DL Data/Control PDU with SDAP header offset = SDAP_HDR_LENGTH; /* * TS 37.324 5.2 Data transfer @@ -281,7 +279,7 @@ static void nr_sdap_rx_entity(nr_sdap_entity_t *entity, */ if(!entity->qfi2drb_table[sdap_hdr->QFI].drb_id && entity->default_drb){ nr_sdap_ul_hdr_t sdap_ctrl_pdu = entity->sdap_construct_ctrl_pdu(sdap_hdr->QFI); - rb_id_t sdap_ctrl_pdu_drb = entity->sdap_map_ctrl_pdu(entity, pdcp_entity, SDAP_CTRL_PDU_MAP_DEF_DRB, sdap_hdr->QFI); + int sdap_ctrl_pdu_drb = entity->sdap_map_ctrl_pdu(entity, SDAP_CTRL_PDU_MAP_DEF_DRB, sdap_hdr->QFI); entity->sdap_submit_ctrl_pdu(ue_id, sdap_ctrl_pdu_drb, sdap_ctrl_pdu); } @@ -296,7 +294,7 @@ static void nr_sdap_rx_entity(nr_sdap_entity_t *entity, */ if (pdcp_entity != entity->qfi2drb_table[sdap_hdr->QFI].drb_id) { nr_sdap_ul_hdr_t sdap_ctrl_pdu = entity->sdap_construct_ctrl_pdu(sdap_hdr->QFI); - rb_id_t sdap_ctrl_pdu_drb = entity->sdap_map_ctrl_pdu(entity, pdcp_entity, SDAP_CTRL_PDU_MAP_RULE_DRB, sdap_hdr->QFI); + int sdap_ctrl_pdu_drb = entity->sdap_map_ctrl_pdu(entity, SDAP_CTRL_PDU_MAP_RULE_DRB, sdap_hdr->QFI); entity->sdap_submit_ctrl_pdu(ue_id, sdap_ctrl_pdu_drb, sdap_ctrl_pdu); } @@ -333,51 +331,52 @@ static void nr_sdap_rx_entity(nr_sdap_entity_t *entity, } } -/** - * @brief update QFI to DRB mapping rules -*/ -void nr_sdap_qfi2drb_map_update(nr_sdap_entity_t *entity, uint8_t qfi, rb_id_t drb, bool has_sdap_rx, bool has_sdap_tx) +static void nr_sdap_qfi2drb_map_add(nr_sdap_entity_t *entity, + const uint8_t qfi, + const uint8_t drb_id, + const uint8_t role) { - if(qfi < SDAP_MAX_QFI && - qfi > SDAP_MAP_RULE_EMPTY && - drb > 0 && - drb <= AVLBL_DRB){ - entity->qfi2drb_table[qfi].drb_id = drb; - entity->qfi2drb_table[qfi].has_sdap_rx = has_sdap_rx; - entity->qfi2drb_table[qfi].has_sdap_tx = has_sdap_tx; - LOG_D(SDAP, "Updated mapping: QFI %u -> DRB %ld \n", qfi, entity->qfi2drb_table[qfi].drb_id); - } else { - LOG_D(SDAP, "Map updated failed, QFI: %u, DRB: %ld\n", qfi, drb); - } + qfi2drb_t *qfi2drb = &entity->qfi2drb_table[qfi]; + LOG_D(SDAP, "%s mapping: QFI %u -> DRB %d \n", qfi2drb->drb_id == SDAP_NO_MAPPING_RULE ? "Add" : "Update", qfi, drb_id); + qfi2drb->drb_id = drb_id; + qfi2drb->entity_role = role; } -void nr_sdap_qfi2drb_map_del(nr_sdap_entity_t *entity, uint8_t qfi){ - entity->qfi2drb_table[qfi].drb_id = SDAP_NO_MAPPING_RULE; - LOG_D(SDAP, "Deleted mapping for QFI: %u \n", qfi); +static void nr_sdap_qfi2drb_map_del(nr_sdap_entity_t *entity, const uint8_t qfi) +{ + qfi2drb_t *qfi2drb = &entity->qfi2drb_table[qfi]; + qfi2drb->drb_id = SDAP_NO_MAPPING_RULE; + LOG_D(SDAP, "Deleted mapping for QFI=%d, DRB=%d\n", qfi, qfi2drb->drb_id); } /** - * @brief maps the QFIs to the default DRB if not mapping rule exists - * @return DRB that is mapped to the QFI, 0 if no mapping and no default DRB exists for that QFI -*/ -rb_id_t nr_sdap_qfi2drb_map(nr_sdap_entity_t *entity, uint8_t qfi){ - rb_id_t pdcp_entity; - - pdcp_entity = entity->qfi2drb_table[qfi].drb_id; - - if(pdcp_entity){ - LOG_D(SDAP, "Mapping rule exists for QFI: %u\n", qfi); - return pdcp_entity; - } else if(entity->default_drb) { - LOG_D(SDAP, "Mapping QFI: %u to Default DRB: %ld\n", qfi, entity->default_drb); - entity->qfi2drb_map_update(entity, qfi, entity->default_drb, entity->qfi2drb_table[qfi].has_sdap_rx, entity->qfi2drb_table[qfi].has_sdap_tx); + * @brief get the DRB ID mapped to the QFI, for both DL and UL + * @return DRB that is mapped to the QFI + * or the default DRB if no mapping rule exists + * or 0 if no mapping and no default DRB exists for that QFI + * @ref TS 37.324, 5.2.1 Uplink + * If there is no stored QoS flow to DRB mapping rule for the + * QoS flow as specified in the subclause 5.3, and a default DRB is configured, + * map the SDAP SDU to the default DRB else, map the SDAP SDU to the DRB according + * to the stored QoS flow to DRB mapping rule. */ +static int nr_sdap_qfi2drb(nr_sdap_entity_t *entity, uint8_t qfi) +{ + /* Fetch DRB ID mapped to QFI */ + int drb_id = entity->qfi2drb_table[qfi].drb_id; + if (drb_id) { + /* QoS flow to DRB mapping rule exists, return corresponding DRB ID */ + LOG_D(SDAP, "Existing QoS flow to DRB mapping rule: QFI %u to DRB %d\n", qfi, drb_id); + return drb_id; + } else if (entity->default_drb) { + /* QoS flow to DRB mapping rule does not exist, map SDAP SDU to default DRB, e.g. return default DRB of the SDAP entity */ + LOG_D(SDAP, "QoS flow to DRB mapping rule does not exists! mapping SDU to Default DRB: %d\n", entity->default_drb); return entity->default_drb; } else { - LOG_D(SDAP, "Mapping rule and default DRB do not exist for QFI:%u\n", qfi); + /* Note: UE undefined behaviour when neither a default DRB + nor a stored QoS flow to DRB mapping rule exists */ + LOG_E(SDAP, "Mapping rule and default DRB do not exist for QFI:%u\n", qfi); return SDAP_MAP_RULE_EMPTY; } - - return pdcp_entity; } nr_sdap_ul_hdr_t nr_sdap_construct_ctrl_pdu(uint8_t qfi){ @@ -391,15 +390,16 @@ nr_sdap_ul_hdr_t nr_sdap_construct_ctrl_pdu(uint8_t qfi){ return sdap_end_marker_hdr; } -rb_id_t nr_sdap_map_ctrl_pdu(nr_sdap_entity_t *entity, rb_id_t pdcp_entity, int map_type, uint8_t dl_qfi){ - rb_id_t drb_of_endmarker = 0; +int nr_sdap_map_ctrl_pdu(nr_sdap_entity_t *entity, int map_type, uint8_t dl_qfi) +{ + int drb_of_endmarker = 0; if(map_type == SDAP_CTRL_PDU_MAP_DEF_DRB){ drb_of_endmarker = entity->default_drb; - LOG_D(SDAP, "Mapping Control PDU QFI: %u to Default DRB: %ld\n", dl_qfi, drb_of_endmarker); + LOG_D(SDAP, "Mapping Control PDU QFI: %u to Default DRB: %d\n", dl_qfi, drb_of_endmarker); } if(map_type == SDAP_CTRL_PDU_MAP_RULE_DRB){ drb_of_endmarker = entity->qfi2drb_map(entity, dl_qfi); - LOG_D(SDAP, "Mapping Control PDU QFI: %u to DRB: %ld\n", dl_qfi, drb_of_endmarker); + LOG_D(SDAP, "Mapping Control PDU QFI: %u to DRB: %d\n", dl_qfi, drb_of_endmarker); } return drb_of_endmarker; } @@ -407,7 +407,7 @@ rb_id_t nr_sdap_map_ctrl_pdu(nr_sdap_entity_t *entity, rb_id_t pdcp_entity, int /** * @brief Submit the end-marker control PDU to PDCP according to TS 37.324, clause 5.3 */ -void nr_sdap_submit_ctrl_pdu(ue_id_t ue_id, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu) +void nr_sdap_submit_ctrl_pdu(ue_id_t ue_id, int sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu) { if(sdap_ctrl_pdu_drb){ nr_pdcp_submit_sdap_ctrl_pdu(ue_id, sdap_ctrl_pdu_drb, ctrl_pdu); @@ -415,116 +415,113 @@ void nr_sdap_submit_ctrl_pdu(ue_id_t ue_id, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_u } } -/** - * @brief UL QoS flow to DRB mapping configuration for an existing SDAP entity - * according to TS 37.324, 5.3 QoS flow to DRB Mapping, clause 5.3.1 Configuration Procedures - */ -static void nr_sdap_ue_qfi2drb_config(nr_sdap_entity_t *existing_sdap_entity, - rb_id_t pdcp_entity, - ue_id_t ue_id, - NR_QFI_t *mapped_qfi_2_add, - uint8_t mappedQFIs2AddCount, - uint8_t drb_identity, - bool has_sdap_rx, - bool has_sdap_tx) +/** @brief UL QoS flow to DRB mapping configuration for a SDAP entity has already been established + * according to TS 37.324, 5.3 QoS flow to DRB Mapping, 5.3.1 Configuration Procedures. */ +static void nr_sdap_ue_control_pdu_config(nr_sdap_entity_t *entity, const ue_id_t ue_id, const sdap_config_t *sdap) { - LOG_D(SDAP, "RRC Configuring SDAP Entity\n"); - for(int i = 0; i < mappedQFIs2AddCount; i++){ - uint8_t qfi = mapped_qfi_2_add[i]; - /* a default DRB exists and there is no QFI to DRB mapping rule for the QFI */ - if (existing_sdap_entity->default_drb && existing_sdap_entity->qfi2drb_table[qfi].drb_id == SDAP_NO_MAPPING_RULE) { - nr_sdap_ul_hdr_t sdap_ctrl_pdu = existing_sdap_entity->sdap_construct_ctrl_pdu(qfi); - rb_id_t sdap_ctrl_pdu_drb = - existing_sdap_entity->sdap_map_ctrl_pdu(existing_sdap_entity, pdcp_entity, SDAP_CTRL_PDU_MAP_DEF_DRB, qfi); - existing_sdap_entity->sdap_submit_ctrl_pdu(ue_id, sdap_ctrl_pdu_drb, sdap_ctrl_pdu); + // handle QFIs to DRB mapping rule to add + for (int i = 0; i < sdap->mappedQFIs2AddCount; i++) { + uint8_t qfi = sdap->mappedQFIs2Add[i]; + /* a default DRB exists and there is no stored QFI to DRB mapping rule for the QFI */ + if (entity->default_drb && entity->qfi2drb_table[qfi].drb_id == SDAP_NO_MAPPING_RULE) { + // construct an end-marker control PDU (6.2.3 TS 37.324) + nr_sdap_ul_hdr_t sdap_ctrl_pdu = entity->sdap_construct_ctrl_pdu(qfi); + // map the end-marker control PDU to the default DRB + int sdap_ctrl_pdu_drb = entity->sdap_map_ctrl_pdu(entity, SDAP_CTRL_PDU_MAP_DEF_DRB, qfi); + // submit the end-marker control PDU to the lower layers + entity->sdap_submit_ctrl_pdu(ue_id, sdap_ctrl_pdu_drb, sdap_ctrl_pdu); } - /* the stored UL QFI to DRB mapping rule is different from the configured one and has UL SDAP header*/ - if (existing_sdap_entity->qfi2drb_table[qfi].drb_id != drb_identity && existing_sdap_entity->qfi2drb_table[qfi].has_sdap_tx) { - nr_sdap_ul_hdr_t sdap_ctrl_pdu = existing_sdap_entity->sdap_construct_ctrl_pdu(qfi); - rb_id_t sdap_ctrl_pdu_drb = - existing_sdap_entity->sdap_map_ctrl_pdu(existing_sdap_entity, pdcp_entity, SDAP_CTRL_PDU_MAP_RULE_DRB, qfi); - existing_sdap_entity->sdap_submit_ctrl_pdu(ue_id, sdap_ctrl_pdu_drb, sdap_ctrl_pdu); + /* the stored UL QFI to DRB mapping rule is different from the configured one and has UL SDAP header */ + bool ul_sdap_header = (entity->qfi2drb_table[qfi].entity_role & SDAP_UL_TX) != 0; + if (entity->qfi2drb_table[qfi].drb_id != sdap->drb_id && ul_sdap_header) { + // construct an end-marker control PDU (6.2.3 TS 37.324) + nr_sdap_ul_hdr_t sdap_ctrl_pdu = entity->sdap_construct_ctrl_pdu(qfi); + // map the end-marker control PDU to the DRB according to the stored QoS flow to DRB mapping rule + int sdap_ctrl_pdu_drb = entity->sdap_map_ctrl_pdu(entity, SDAP_CTRL_PDU_MAP_RULE_DRB, qfi); + // submit the end-marker control PDU to the lower layers + entity->sdap_submit_ctrl_pdu(ue_id, sdap_ctrl_pdu_drb, sdap_ctrl_pdu); } - /* update QFI to DRB mapping rules */ - LOG_D(SDAP, "Storing the configured QoS flow to DRB mapping rule\n"); - existing_sdap_entity->qfi2drb_map_update(existing_sdap_entity, qfi, drb_identity, has_sdap_rx, has_sdap_tx); } } +/** @brief Add QoS flows to a DRB */ +static void nr_sdap_add_qos_flows_to_drb(nr_sdap_entity_t *entity, const sdap_config_t *sdap) +{ + for (int i = 0; i < sdap->mappedQFIs2AddCount; i++) { + uint8_t qfi = sdap->mappedQFIs2Add[i]; + LOG_D(SDAP, "Adding QFI to DRB mapping rules: %d mapped QFIs for DRB %d\n", sdap->mappedQFIs2AddCount, sdap->drb_id); + if (qfi < SDAP_MAX_QFI && qfi > SDAP_MAP_RULE_EMPTY && sdap->drb_id > 0 && sdap->drb_id <= MAX_DRBS_PER_UE) { + entity->qfi2drb_map_add(entity, qfi, sdap->drb_id, sdap->role); + } else { + LOG_E(SDAP, "Failed to add qfi2drb mapping: QFI=%d, DRB=%d\n", qfi, sdap->drb_id); + } + } +} + +/** @brief Remove QoS flows from a DRB */ +static void nr_sdap_rm_qos_flows_from_drb(nr_sdap_entity_t *entity, const sdap_config_t *sdap) +{ + for (int i = 0; i < sdap->mappedQFIs2ReleaseCount; i++) { + uint8_t qfi = sdap->mappedQFIs2Release[i]; + LOG_D(SDAP, "Removing QFI from DRB mapping rules: QFI=%d for DRB=%d\n", qfi, sdap->drb_id); + entity->qfi2drb_map_delete(entity, qfi); + } +} + +/** @brief Update QFI to DRB mapping rules + * @param qfi the QoS Flow index, used as unique index of the qfi2drb mapping table + * @param drb the DRB ID to be mapped */ +static void nr_sdap_qfi2drb_map_update(nr_sdap_entity_t *entity, const sdap_config_t *sdap) +{ + if (!entity->is_gnb) { // UE control PDU configuration + nr_sdap_ue_control_pdu_config(entity, entity->ue_id, sdap); + } + nr_sdap_add_qos_flows_to_drb(entity, sdap); + nr_sdap_rm_qos_flows_from_drb(entity, sdap); +} + /** * @brief add a new SDAP entity according to 5.1.1. of 3GPP TS 37.324 * @note there is one SDAP entity per PDU session * * @param is_gnb, indicates whether it is for gNB or UE - * @param has_sdap_rx, indicates whether it is a receiving SDAP entity - * @param has_sdap_tx, indicates whether it is a transmitting SDAP entity * @param ue_id, UE ID - * @param pdusession_id, PDU session ID - * @param is_defaultDRB, indicates whether the entity has a default DRB - * @param mapped_qfi_2_add, list of QoS flows to add/update - * @param mappedQFIs2AddCount, number of QoS flows to add/update - */ -nr_sdap_entity_t *new_nr_sdap_entity(int is_gnb, - bool has_sdap_rx, - bool has_sdap_tx, - ue_id_t ue_id, - int pdusession_id, - bool is_defaultDRB, - uint8_t drb_identity, - NR_QFI_t *mapped_qfi_2_add, - uint8_t mappedQFIs2AddCount) + * @param sdap, SDAP configuration */ +static void nr_sdap_add_entity(const int is_gnb, const ue_id_t ue_id, const sdap_config_t sdap) { - /* check whether the SDAP entity already exists and - update QFI to DRB mapping rules in that case */ - if (nr_sdap_get_entity(ue_id, pdusession_id)) { - LOG_E(SDAP, "SDAP Entity for UE already exists with RNTI/UE ID: %lu and PDU SESSION ID: %d\n", ue_id, pdusession_id); - nr_sdap_entity_t *existing_sdap_entity = nr_sdap_get_entity(ue_id, pdusession_id); - rb_id_t pdcp_entity = existing_sdap_entity->default_drb; - if(!is_gnb) - nr_sdap_ue_qfi2drb_config(existing_sdap_entity, - pdcp_entity, - ue_id, - mapped_qfi_2_add, - mappedQFIs2AddCount, - drb_identity, - has_sdap_rx, - has_sdap_tx); - return existing_sdap_entity; - } - - nr_sdap_entity_t *sdap_entity; - sdap_entity = calloc(1, sizeof(nr_sdap_entity_t)); - - if(sdap_entity == NULL) { - LOG_E(SDAP, "SDAP Entity creation failed, out of memory\n"); - exit(1); - } + nr_sdap_entity_t *sdap_entity = calloc_or_fail(1, sizeof(*sdap_entity)); + // SDAP entity ids sdap_entity->ue_id = ue_id; - sdap_entity->pdusession_id = pdusession_id; + sdap_entity->pdusession_id = sdap.pdusession_id; sdap_entity->is_gnb = is_gnb; + // rx/tx entities sdap_entity->tx_entity = nr_sdap_tx_entity; sdap_entity->rx_entity = nr_sdap_rx_entity; + // control pdu function pointers sdap_entity->sdap_construct_ctrl_pdu = nr_sdap_construct_ctrl_pdu; sdap_entity->sdap_map_ctrl_pdu = nr_sdap_map_ctrl_pdu; sdap_entity->sdap_submit_ctrl_pdu = nr_sdap_submit_ctrl_pdu; + // QFI to DRB mapping functions pointers sdap_entity->qfi2drb_map_update = nr_sdap_qfi2drb_map_update; + sdap_entity->qfi2drb_map_add = nr_sdap_qfi2drb_map_add; sdap_entity->qfi2drb_map_delete = nr_sdap_qfi2drb_map_del; - sdap_entity->qfi2drb_map = nr_sdap_qfi2drb_map; - + sdap_entity->qfi2drb_map = nr_sdap_qfi2drb; sdap_entity->pdusession_sock = -1; - if(is_defaultDRB) { - sdap_entity->default_drb = drb_identity; - LOG_I(SDAP, "Default DRB for the created SDAP entity: %ld \n", sdap_entity->default_drb); - LOG_D(SDAP, "RRC updating mapping rules: %d\n", mappedQFIs2AddCount); - for (int i = 0; i < mappedQFIs2AddCount; i++) - sdap_entity->qfi2drb_map_update(sdap_entity, mapped_qfi_2_add[i], sdap_entity->default_drb, has_sdap_rx, has_sdap_tx); + // set default DRB + if (sdap.defaultDRB) { + sdap_entity->default_drb = sdap.drb_id; + LOG_I(SDAP, "Default DRB for the created SDAP entity: DRB %d \n", sdap_entity->default_drb); } + // Add QoS flows to the DRB (initial configuration) + nr_sdap_add_qos_flows_to_drb(sdap_entity, &sdap); + + // update SDAP entity list pointers sdap_entity->next_entity = sdap_info.sdap_entity_llist; sdap_info.sdap_entity_llist = sdap_entity; @@ -533,7 +530,17 @@ nr_sdap_entity_t *new_nr_sdap_entity(int is_gnb, // PDCP SDUs to/from the TUN interface. start_sdap_tun_gnb_first_ue_default_pdu_session(ue_id); } - return sdap_entity; +} + +/** @brief Add or modify an SDAP entity if it already exists */ +void nr_sdap_addmod_entity(const int is_gnb, const ue_id_t ue_id, const sdap_config_t sdap) +{ + nr_sdap_entity_t *sdap_entity = nr_sdap_get_entity(ue_id, sdap.pdusession_id); + if (sdap_entity) { + sdap_entity->qfi2drb_map_update(sdap_entity, &sdap); + } else { + nr_sdap_add_entity(is_gnb, ue_id, sdap); + } } /** @@ -653,6 +660,40 @@ bool nr_sdap_delete_ue_entities(ue_id_t ue_id) return ret; } +/** @brief This function gets the relevant SDAP config from the received SDAP-Config */ +sdap_config_t nr_sdap_get_config(const int is_gnb, const NR_SDAP_Config_t *sdap_Config, const int drb_id) +{ + DevAssert(sdap_Config); + sdap_config_t sdapConfig = {0}; + sdapConfig.drb_id = drb_id; + sdapConfig.role = get_sdap_role(is_gnb, sdap_Config); + LOG_D(SDAP, "SDAP headers %s\n", sdapConfig.role == NO_SDAP_HEADER ? "absent" : "present"); + sdapConfig.defaultDRB = sdap_Config->defaultDRB; + // 3GPP TS 38.331 The network sets sdap-HeaderUL to present if the field defaultDRB is set to true + if (sdapConfig.defaultDRB && (sdap_Config->sdap_HeaderUL != NR_SDAP_Config__sdap_HeaderUL_present)) + LOG_D(SDAP, "Received SDAP-Config with defaultDRB but sdap-HeaderUL is not present\n"); + if (sdap_Config->mappedQoS_FlowsToAdd) { + sdapConfig.mappedQFIs2AddCount = sdap_Config->mappedQoS_FlowsToAdd->list.count; + DevAssert(sdapConfig.mappedQFIs2AddCount <= SDAP_MAX_QFI); + LOG_D(SDAP, "DRB %d: mapped QFIs = %d \n", sdapConfig.drb_id, sdapConfig.mappedQFIs2AddCount); + for (int i = 0; i < sdapConfig.mappedQFIs2AddCount; i++){ + DevAssert(i < SDAP_MAX_QFI); + sdapConfig.mappedQFIs2Add[i] = *sdap_Config->mappedQoS_FlowsToAdd->list.array[i]; + LOG_D(SDAP, "Captured mappedQoS_FlowsToAdd[%d] from RRC: %ld\n", i, sdapConfig.mappedQFIs2Add[i]); + } + } + sdapConfig.pdusession_id = sdap_Config->pdu_Session; + if (sdap_Config->mappedQoS_FlowsToRelease) { + sdapConfig.mappedQFIs2ReleaseCount = sdap_Config->mappedQoS_FlowsToRelease->list.count; + DevAssert(sdapConfig.mappedQFIs2ReleaseCount <= SDAP_MAX_QFI); + for (int i = 0; i < sdapConfig.mappedQFIs2ReleaseCount; i++) { + DevAssert(i < SDAP_MAX_QFI); + sdapConfig.mappedQFIs2Release[i] = *sdap_Config->mappedQoS_FlowsToRelease->list.array[i]; + } + } + return sdapConfig; +} + /** * @brief SDAP Entity reconfiguration at UE according to TS 37.324 * and triggered by RRC reconfiguration events according to clause 5.3.5.6.5 of TS 38.331. @@ -670,27 +711,8 @@ void nr_reconfigure_sdap_entity(NR_SDAP_Config_t *sdap_config, ue_id_t ue_id, in ue_id, pdusession_id); /* QFI to DRB mapping */ - NR_QFI_t *mappedQFIs2Add = (NR_QFI_t *)sdap_config->mappedQoS_FlowsToAdd->list.array[0]; - uint8_t mappedQFIs2AddCount = sdap_config->mappedQoS_FlowsToAdd->list.count; - bool has_sdap_rx = is_sdap_rx(is_gnb, sdap_config); - bool has_sdap_tx = is_sdap_tx(is_gnb, sdap_config); - nr_sdap_ue_qfi2drb_config(sdap_entity, - sdap_entity->default_drb, - ue_id, - mappedQFIs2Add, - mappedQFIs2AddCount, - drb_id, - has_sdap_rx, - has_sdap_tx); - /* handle QFIs to DRB mapping rule to release */ - if (sdap_config->mappedQoS_FlowsToRelease) { - NR_QFI_t *mappedQFIs2release = (NR_QFI_t *)sdap_config->mappedQoS_FlowsToRelease->list.array[0]; - uint8_t mappedQFIs2RemoveCount = sdap_config->mappedQoS_FlowsToRelease->list.count; - for(int i = 0; i < mappedQFIs2RemoveCount; i++){ - uint8_t qfi = mappedQFIs2release[i]; - sdap_entity->qfi2drb_map_delete(sdap_entity, qfi); - } - } + sdap_config_t sdap = nr_sdap_get_config(is_gnb, sdap_config, drb_id); + sdap_entity->qfi2drb_map_update(sdap_entity, &sdap); } void set_qfi(uint8_t qfi, uint8_t pduid, ue_id_t ue_id) diff --git a/openair2/SDAP/nr_sdap/nr_sdap_entity.h b/openair2/SDAP/nr_sdap/nr_sdap_entity.h index 3a42c6c076..a206189035 100644 --- a/openair2/SDAP/nr_sdap/nr_sdap_entity.h +++ b/openair2/SDAP/nr_sdap/nr_sdap_entity.h @@ -38,7 +38,6 @@ #define SDAP_HDR_LENGTH (1) #define SDAP_MAX_QFI (64) #define SDAP_MAP_RULE_EMPTY (0) -#define AVLBL_DRB (5) #define SDAP_NO_MAPPING_RULE (0) #define SDAP_REFLECTIVE_MAPPING (1) #define SDAP_RQI_HANDLING (1) @@ -69,17 +68,34 @@ typedef struct nr_sdap_ul_hdr_s { uint8_t DC:1; } __attribute__((packed)) nr_sdap_ul_hdr_t; +typedef enum { + SDAP_UL_TX = (1 << 0), + SDAP_UL_RX = (1 << 1), + SDAP_DL_TX = (1 << 2), + SDAP_DL_RX = (1 << 3) +} sdap_role_t; + typedef struct qfi2drb_s { - rb_id_t drb_id; - bool has_sdap_rx; - bool has_sdap_tx; + int drb_id; + int entity_role; } qfi2drb_t; -void nr_pdcp_submit_sdap_ctrl_pdu(ue_id_t ue_id, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu); +void nr_pdcp_submit_sdap_ctrl_pdu(ue_id_t ue_id, int sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu); + +typedef struct sdap_configuration_s { + int pdusession_id; + int drb_id; + int role; + bool defaultDRB; + NR_QFI_t mappedQFIs2Add[SDAP_MAX_QFI]; + uint8_t mappedQFIs2AddCount; + NR_QFI_t mappedQFIs2Release[SDAP_MAX_QFI]; + uint8_t mappedQFIs2ReleaseCount; +} sdap_config_t; typedef struct nr_sdap_entity_s { ue_id_t ue_id; - rb_id_t default_drb; + int default_drb; /// sdap_tun_read_thread needs to know if we are gNB/UE, so for noS1 mode, /// store which one we are bool is_gnb; @@ -91,18 +107,21 @@ typedef struct nr_sdap_entity_s { qfi2drb_t qfi2drb_table[SDAP_MAX_QFI]; - void (*qfi2drb_map_update)(struct nr_sdap_entity_s *entity, uint8_t qfi, rb_id_t drb, bool has_sdap_rx, bool has_sdap_tx); - void (*qfi2drb_map_delete)(struct nr_sdap_entity_s *entity, uint8_t qfi); - rb_id_t (*qfi2drb_map)(struct nr_sdap_entity_s *entity, uint8_t qfi); + void (*qfi2drb_map_update)(struct nr_sdap_entity_s *entity, const sdap_config_t *sdap); + void (*qfi2drb_map_delete)(struct nr_sdap_entity_s *entity, const uint8_t qfi); + void (*qfi2drb_map_add)(struct nr_sdap_entity_s *entity, + const uint8_t qfi, + const uint8_t drb_id, + const uint8_t role); + int (*qfi2drb_map)(struct nr_sdap_entity_s *entity, uint8_t qfi); nr_sdap_ul_hdr_t (*sdap_construct_ctrl_pdu)(uint8_t qfi); - rb_id_t (*sdap_map_ctrl_pdu)(struct nr_sdap_entity_s *entity, rb_id_t pdcp_entity, int map_type, uint8_t dl_qfi); - void (*sdap_submit_ctrl_pdu)(ue_id_t ue_id, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu); + int (*sdap_map_ctrl_pdu)(struct nr_sdap_entity_s *entity, int map_type, uint8_t dl_qfi); + void (*sdap_submit_ctrl_pdu)(ue_id_t ue_id, int sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu); bool (*tx_entity)(struct nr_sdap_entity_s *entity, protocol_ctxt_t *ctxt_p, const srb_flag_t srb_flag, - const rb_id_t rb_id, const mui_t mui, const confirm_t confirm, const sdu_size_t sdu_buffer_size, @@ -114,9 +133,8 @@ typedef struct nr_sdap_entity_s { const bool rqi); void (*rx_entity)(struct nr_sdap_entity_s *entity, - rb_id_t pdcp_entity, + int pdcp_entity, int is_gnb, - bool has_sdap_rx, int pdusession_id, ue_id_t ue_id, char *buf, @@ -126,23 +144,6 @@ typedef struct nr_sdap_entity_s { struct nr_sdap_entity_s *next_entity; } nr_sdap_entity_t; -/* QFI to DRB Mapping Related Function */ -void nr_sdap_qfi2drb_map_update(nr_sdap_entity_t *entity, uint8_t qfi, rb_id_t drb, bool has_sdap_rx, bool has_sdap_tx); - -/* QFI to DRB Mapping Related Function */ -void nr_sdap_qfi2drb_map_del(nr_sdap_entity_t *entity, uint8_t qfi); - -/* - * TS 37.324 - * 4.4 Functions - * Mapping between a QoS flow and a DRB for both DL and UL. - * - * 5.2.1 Uplink - * If there is no stored QoS flow to DRB mapping rule for the QoS flow as specified in the subclause 5.3, map the SDAP SDU to the default DRB - * else, map the SDAP SDU to the DRB according to the stored QoS flow to DRB mapping rule. - */ -rb_id_t nr_sdap_qfi2drb_map(nr_sdap_entity_t *entity, uint8_t qfi); - /* * TS 37.324 5.3 QoS flow to DRB Mapping * construct an end-marker control PDU, as specified in the subclause 6.2.3, for the QoS flow; @@ -155,33 +156,24 @@ nr_sdap_ul_hdr_t nr_sdap_construct_ctrl_pdu(uint8_t qfi); * 1.) default DRB or * 2.) DRB according to the stored QoS flow to DRB mapping rule */ -rb_id_t nr_sdap_map_ctrl_pdu(nr_sdap_entity_t *entity, rb_id_t pdcp_entity, int map_type, uint8_t dl_qfi); +int nr_sdap_map_ctrl_pdu(nr_sdap_entity_t *entity, int map_type, uint8_t dl_qfi); /* * TS 37.324 5.3 QoS flow to DRB Mapping * Submit the end-marker control PDU to the lower layer. */ -void nr_sdap_submit_ctrl_pdu(ue_id_t ue_id, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu); - -/* - * TS 37.324 4.4 5.1.1 SDAP entity establishment - * Establish an SDAP entity. - */ -nr_sdap_entity_t *new_nr_sdap_entity(int is_gnb, - bool has_sdap_rx, - bool has_sdap_tx, - ue_id_t ue_id, - int pdusession_id, - bool is_defaultDRB, - uint8_t default_DRB, - NR_QFI_t *mapped_qfi_2_add, - uint8_t mappedQFIs2AddCount); +void nr_sdap_submit_ctrl_pdu(ue_id_t ue_id, int sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu); /* Entity Handling Related Functions */ nr_sdap_entity_t *nr_sdap_get_entity(ue_id_t ue_id, int pdusession_id); +sdap_config_t nr_sdap_get_config(const int is_gnb, const NR_SDAP_Config_t *sdap_Config, const int drb_id); + void nr_sdap_release_drb(ue_id_t ue_id, int drb_id, int pdusession_id); +/** @brief Add or modify an SDAP entity based on whether it already exists */ +void nr_sdap_addmod_entity(const int is_gnb, const ue_id_t ue_id, const sdap_config_t sdap); + /** * @brief Function to delete a single SDAP Entity based on the ue_id and pdusession_id. * @note 1. SDAP entities may have the same ue_id. @@ -200,20 +192,6 @@ bool nr_sdap_delete_entity(ue_id_t ue_id, int pdusession_id); */ bool nr_sdap_delete_ue_entities(ue_id_t ue_id); -/** - * @brief indicates whether it is a receiving SDAP entity - * i.e. for UE, header for DL data is present - * for gNB, header for UL data is present - */ -bool is_sdap_rx(bool is_gnb, NR_SDAP_Config_t *sdap_config); - -/** - * @brief indicates whether it is a transmitting SDAP entity - * i.e. for UE, header for UL data is present - * for gNB, header for DL data is present - */ -bool is_sdap_tx(bool is_gnb, NR_SDAP_Config_t *sdap_config); - /** * @brief Run the SDAP reconfiguration for the DRB * @param[in] ue_id Unique identifier for the User Equipment. ID Range [0, 65536]. diff --git a/openair3/NGAP/ngap_common.c b/openair3/NGAP/ngap_common.c index c3865cff10..8be57349ec 100644 --- a/openair3/NGAP/ngap_common.c +++ b/openair3/NGAP/ngap_common.c @@ -106,7 +106,7 @@ ngap_cause_t decode_ngap_cause(const NGAP_Cause_t *in) nr_guami_t decode_ngap_guami(const NGAP_GUAMI_t *in) { nr_guami_t out = {0}; - TBCD_TO_MCC_MNC(&in->pLMNIdentity, out.mcc, out.mnc, out.mnc_len); + TBCD_TO_MCC_MNC(&in->pLMNIdentity, out.plmn.mcc, out.plmn.mnc, out.plmn.mnc_digit_length); OCTET_STRING_TO_INT8(&in->aMFRegionID, out.amf_region_id); OCTET_STRING_TO_INT16(&in->aMFSetID, out.amf_set_id); OCTET_STRING_TO_INT8(&in->aMFPointer, out.amf_pointer); diff --git a/openair3/NGAP/ngap_gNB_nas_procedures.c b/openair3/NGAP/ngap_gNB_nas_procedures.c index cff9cd0b72..7dd6359b7a 100644 --- a/openair3/NGAP/ngap_gNB_nas_procedures.c +++ b/openair3/NGAP/ngap_gNB_nas_procedures.c @@ -76,9 +76,9 @@ static ngap_gNB_amf_data_t *select_amf(ngap_gNB_instance_t *instance_p, const ng const nr_guami_t *guami = &msg->ue_identity.guami; LOG_D(NGAP, "GUAMI is present: MCC=%03d MNC=%0*d RegionID=%d SetID=%d Pointer=%d\n", - guami->mcc, - guami->mnc_len, - guami->mnc, + guami->plmn.mcc, + guami->plmn.mnc_digit_length, + guami->plmn.mnc, guami->amf_region_id, guami->amf_set_id, guami->amf_pointer); @@ -89,9 +89,9 @@ static ngap_gNB_amf_data_t *select_amf(ngap_gNB_instance_t *instance_p, const ng msg->gNB_ue_ngap_id, amf->amf_name, amf->assoc_id, - guami->mcc, - guami->mnc_len, - guami->mnc, + guami->plmn.mcc, + guami->plmn.mnc_digit_length, + guami->plmn.mnc, guami->amf_region_id, guami->amf_set_id, guami->amf_pointer); @@ -181,7 +181,6 @@ int ngap_gNB_handle_nas_first_req(instance_t instance, ngap_nas_first_req_t *UEf .amf_ref = amf, .gNB_ue_ngap_id = UEfirstReq->gNB_ue_ngap_id, .gNB_instance = instance_p, - .selected_plmn_identity = UEfirstReq->plmn, }; // RAN UE NGAP ID (M) @@ -211,16 +210,14 @@ int ngap_gNB_handle_nas_first_req(instance_t instance, ngap_nas_first_req_t *UEf ie->value.choice.UserLocationInformation.present = NGAP_UserLocationInformation_PR_userLocationInformationNR; asn1cCalloc(ie->value.choice.UserLocationInformation.choice.userLocationInformationNR, userinfo_nr_p); - /* Set nRCellIdentity. default userLocationInformationNR */ - MACRO_GNB_ID_TO_CELL_IDENTITY(instance_p->gNB_id, - 0, // Cell ID - &userinfo_nr_p->nR_CGI.nRCellIdentity); + /* NR CGI: use gNB ID and Cell ID passed from RRC */ + MACRO_GNB_ID_TO_CELL_IDENTITY(instance_p->gNB_id, UEfirstReq->nr_cell_id, &userinfo_nr_p->nR_CGI.nRCellIdentity); - plmn_id_t *plmn = &ue_desc_p.selected_plmn_identity; + /* Use UE's selected PLMN for nR-CGI (from Initial UE Message) */ + plmn_id_t *plmn = &UEfirstReq->plmn; MCC_MNC_TO_TBCD(plmn->mcc, plmn->mnc, plmn->mnc_digit_length, &userinfo_nr_p->nR_CGI.pLMNIdentity); - /* In case of network sharing, - the selected PLMN is indicated by the PLMN Identity IE within the TAI IE */ + /* Set TAI - use UE's selected PLMN */ INT24_TO_OCTET_STRING(instance_p->tac, &userinfo_nr_p->tAI.tAC); MCC_MNC_TO_PLMNID(plmn->mcc, plmn->mnc, plmn->mnc_digit_length, &userinfo_nr_p->tAI.pLMNIdentity); } @@ -444,17 +441,20 @@ int ngap_gNB_nas_uplink(instance_t instance, ngap_uplink_nas_t *ngap_uplink_nas_ ie->value.choice.UserLocationInformation.present = NGAP_UserLocationInformation_PR_userLocationInformationNR; asn1cCalloc(ie->value.choice.UserLocationInformation.choice.userLocationInformationNR, userinfo_nr_p); - /* Set nRCellIdentity. default userLocationInformationNR */ + /* Set nRCellIdentity: use gNB ID and Cell ID */ MACRO_GNB_ID_TO_CELL_IDENTITY(ngap_gNB_instance_p->gNB_id, - 0, // Cell ID + ngap_uplink_nas_p->nr_cell_id, &userinfo_nr_p->nR_CGI.nRCellIdentity); - plmn_id_t *plmn = &ue_context_p->selected_plmn_identity; + + /* NR CGI */ + plmn_id_t *plmn = &ngap_uplink_nas_p->plmn; MCC_MNC_TO_TBCD(plmn->mcc, plmn->mnc, plmn->mnc_digit_length, &userinfo_nr_p->nR_CGI.pLMNIdentity); - /* Set TAI */ - INT24_TO_OCTET_STRING(ngap_gNB_instance_p->tac, &userinfo_nr_p->tAI.tAC); + /* TAI */ + INT24_TO_OCTET_STRING(ngap_uplink_nas_p->tac, &userinfo_nr_p->tAI.tAC); MCC_MNC_TO_PLMNID(plmn->mcc, plmn->mnc, plmn->mnc_digit_length, &userinfo_nr_p->tAI.pLMNIdentity); } + if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { NGAP_ERROR("Failed to encode uplink NAS transport\n"); /* Encode procedure has failed... */ diff --git a/openair3/NGAP/ngap_gNB_nnsf.c b/openair3/NGAP/ngap_gNB_nnsf.c index f895737a0d..5fbc3e4d11 100644 --- a/openair3/NGAP/ngap_gNB_nnsf.c +++ b/openair3/NGAP/ngap_gNB_nnsf.c @@ -286,8 +286,7 @@ ngap_gNB_amf_data_t *ngap_gNB_nnsf_select_amf_by_guami(ngap_gNB_instance_t *inst struct plmn_identity_s *served_plmn_p = NULL; STAILQ_FOREACH(served_plmn_p, &guami_p->served_plmns, next) { - if ((served_plmn_p->mcc == guami.mcc) && - (served_plmn_p->mnc == guami.mnc)) { + if ((served_plmn_p->mcc == guami.plmn.mcc) && (served_plmn_p->mnc == guami.plmn.mnc)) { break; } } @@ -322,9 +321,9 @@ ngap_gNB_amf_data_t *ngap_gNB_nnsf_select_amf_by_guami(ngap_gNB_instance_t *inst } NGAP_WARN("No matching AMF found for GUAMI (MCC=%03d MNC=%0*d RegionID=%d SetID=%d Pointer=%d)\n", - guami.mcc, - guami.mnc_len, - guami.mnc, + guami.plmn.mcc, + guami.plmn.mnc_digit_length, + guami.plmn.mnc, guami.amf_region_id, guami.amf_set_id, guami.amf_pointer); @@ -373,8 +372,7 @@ ngap_gNB_amf_data_t *ngap_gNB_nnsf_select_amf_by_guami_no_cause(ngap_gNB_instanc struct plmn_identity_s *served_plmn_p = NULL; STAILQ_FOREACH(served_plmn_p, &guami_p->served_plmns, next) { - if ((served_plmn_p->mcc == guami.mcc) && - (served_plmn_p->mnc == guami.mnc)) { + if ((served_plmn_p->mcc == guami.plmn.mcc) && (served_plmn_p->mnc == guami.plmn.mnc)) { break; } } diff --git a/openair3/NGAP/ngap_gNB_ue_context.h b/openair3/NGAP/ngap_gNB_ue_context.h index 1022f2f4c3..8053e8f8c6 100644 --- a/openair3/NGAP/ngap_gNB_ue_context.h +++ b/openair3/NGAP/ngap_gNB_ue_context.h @@ -69,11 +69,6 @@ typedef struct ngap_gNB_ue_context_s { /* Reference to AMF data this UE is attached to */ struct ngap_gNB_amf_data_s *amf_ref; - /* Signaled by the UE in RRC Connection Setup Complete and used in NAS Uplink - * to route NAS messages correctly. 0-based, not 1-based as in TS 36.331 - * 6.2.2 RRC Connection Setup Complete! */ - plmn_id_t selected_plmn_identity; - /* Reference to gNB data this UE is attached to */ ngap_gNB_instance_t *gNB_instance; } ngap_gNB_ue_context_t; diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp index 9be1873612..aca2fcbb32 100644 --- a/openair3/ocp-gtpu/gtp_itf.cpp +++ b/openair3/ocp-gtpu/gtp_itf.cpp @@ -1244,7 +1244,6 @@ static int Gtpv1uHandleGpdu(int h, uint8_t *msgBuf, uint32_t msgBufLen, const st if (!uedata.callBackSDAP(&ctxt, uedata.ue_id, srb_flag, - rb_id, mui, confirm, sdu_buffer_size, diff --git a/openair3/ocp-gtpu/gtp_itf.h b/openair3/ocp-gtpu/gtp_itf.h index 4fcb8190e4..c31f8c935e 100644 --- a/openair3/ocp-gtpu/gtp_itf.h +++ b/openair3/ocp-gtpu/gtp_itf.h @@ -49,7 +49,6 @@ typedef struct gtpv1u_gnb_delete_tunnel_req_s gtpv1u_gnb_delete_tunnel_req_t; typedef bool (*gtpCallbackSDAP)(protocol_ctxt_t *ctxt_pP, const ue_id_t ue_id, const srb_flag_t srb_flagP, - const rb_id_t rb_idP, const mui_t muiP, const confirm_t confirmP, const sdu_size_t sdu_buffer_sizeP, diff --git a/radio/ETHERNET/CMakeLists.txt b/radio/ETHERNET/CMakeLists.txt index 3a9b9dc5cb..dd0f603eda 100644 --- a/radio/ETHERNET/CMakeLists.txt +++ b/radio/ETHERNET/CMakeLists.txt @@ -9,5 +9,3 @@ set_target_properties(oai_eth_transpro PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMA add_custom_command(TARGET oai_eth_transpro POST_BUILD COMMAND ${CMAKE_COMMAND} -E create_symlink liboai_eth_transpro.so liboai_transpro.so WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) - -add_subdirectory(benetel) diff --git a/radio/ETHERNET/benetel/4g/CMakeLists.txt b/radio/ETHERNET/benetel/4g/CMakeLists.txt deleted file mode 100644 index 164e33eb28..0000000000 --- a/radio/ETHERNET/benetel/4g/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -pkg_check_modules(libdpdk REQUIRED libdpdk=20.05.0) - -add_library(benetel_4g MODULE - benetel.c - shared_buffers.c - low.c - low_dpdk.c - dpdk_driver.c -) - -target_compile_definitions(benetel_4g PROPERTIES COMPILE_FLAGS "-fvisibility=hidden -I$ENV{RTE_SDK}/$ENV{RTE_TARGET}/include") - -SET(DPDK_LIBS "-Wl,-rpath,$ENV{RTE_SDK}/$ENV{RTE_TARGET}/lib -Wl,--whole-archive -L$ENV{RTE_SDK}/$ENV{RTE_TARGET}/lib -ldpdk -Wl,--no-whole-archive") -target_include_directories(benetel_4g PRIVATE ${libdpdk_INCLUDE_DIRS}) -target_link_libraries(benetel_4g PRIVATE ${libdpdk_LIBRARIES}) -target_link_libraries(benetel_4g PRIVATE pthread dl rt m numa) -set_target_properties(benetel_4g PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) -add_custom_command(TARGET benetel_4g POST_BUILD - COMMAND ${CMAKE_COMMAND} -E create_symlink libbenetel_4g.so liboai_transpro.so - WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) diff --git a/radio/ETHERNET/benetel/4g/benetel.c b/radio/ETHERNET/benetel/4g/benetel.c deleted file mode 100644 index 8e221fe929..0000000000 --- a/radio/ETHERNET/benetel/4g/benetel.c +++ /dev/null @@ -1,392 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#include - -#include "common_lib.h" -#include "ethernet_lib.h" -#include "shared_buffers.h" -#include "low.h" -#include "common/utils/LOG/log.h" -#include "common/utils/LOG/vcd_signal_dumper.h" - -typedef struct { - eth_state_t e; - shared_buffers buffers; - rru_config_msg_type_t last_msg; - int capabilities_sent; - void *benetel_priv; - char *dpdk_main_command_line; -} benetel_eth_state_t; - -int trx_benetel_start(openair0_device *device) -{ - printf("BENETEL: %s\n", __FUNCTION__); - return 0; -} - - -void trx_benetel_end(openair0_device *device) -{ - printf("BENETEL: %s\n", __FUNCTION__); -} - - -int trx_benetel_stop(openair0_device *device) -{ - printf("BENETEL: %s\n", __FUNCTION__); - return(0); -} - - -int trx_benetel_set_freq(openair0_device* device, openair0_config_t *openair0_cfg) -{ - printf("BENETEL: %s\n", __FUNCTION__); - return(0); -} - - -int trx_benetel_set_gains(openair0_device* device, - openair0_config_t *openair0_cfg) -{ - printf("BENETEL: %s\n", __FUNCTION__); - return(0); -} - - -int trx_benetel_get_stats(openair0_device* device) -{ - printf("BENETEL: %s\n", __FUNCTION__); - return(0); -} - - -int trx_benetel_reset_stats(openair0_device* device) -{ - printf("BENETEL: %s\n", __FUNCTION__); - return(0); -} - - -int ethernet_tune(openair0_device *device, - unsigned int option, - int value) -{ - printf("BENETEL: %s\n", __FUNCTION__); - return 0; -} - -int trx_benetel_write_raw(openair0_device *device, - openair0_timestamp timestamp, - void **buff, int nsamps, int cc, int flags) -{ - printf("BENETEL: %s\n", __FUNCTION__); - return nsamps*4; -} - -int trx_benetel_read_raw(openair0_device *device, - openair0_timestamp *timestamp, - void **buff, int nsamps, int cc) -{ - printf("BENETEL: %s\n", __FUNCTION__); - return nsamps*4; -} - -char *msg_type(int t) -{ - static char *s[12] = { - "RAU_tick", - "RRU_capabilities", - "RRU_config", - "RRU_config_ok", - "RRU_start", - "RRU_stop", - "RRU_sync_ok", - "RRU_frame_resynch", - "RRU_MSG_max_num", - "RRU_check_sync", - "RRU_config_update", - "RRU_config_update_ok", - }; - - if (t < 0 || t > 11) return "UNKNOWN"; - return s[t]; -} - -int trx_benetel_ctlsend(openair0_device *device, void *msg, ssize_t msg_len) -{ - RRU_CONFIG_msg_t *rru_config_msg = msg; - benetel_eth_state_t *s = device->priv; - - printf("BENETEL: %s\n", __FUNCTION__); - - printf(" rru_config_msg->type %d [%s]\n", rru_config_msg->type, - msg_type(rru_config_msg->type)); - - s->last_msg = rru_config_msg->type; - - return msg_len; -} - -int trx_benetel_ctlrecv(openair0_device *device, void *msg, ssize_t msg_len) -{ - RRU_CONFIG_msg_t *rru_config_msg = msg; - benetel_eth_state_t *s = device->priv; - - printf("BENETEL: %s\n", __FUNCTION__); - - if (s->last_msg == RAU_tick && s->capabilities_sent == 0) { - RRU_capabilities_t *cap; - rru_config_msg->type = RRU_capabilities; - rru_config_msg->len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE+sizeof(RRU_capabilities_t); - cap = (RRU_capabilities_t*)&rru_config_msg->msg[0]; - cap->FH_fmt = OAI_IF4p5_only; - cap->num_bands = 1; - cap->band_list[0] = 7; - cap->nb_rx[0] = device->openair0_cfg->rx_num_channels; - cap->nb_tx[0] = device->openair0_cfg->tx_num_channels; - cap->max_pdschReferenceSignalPower[0] = -27; - cap->max_rxgain[0] = 90; - - s->capabilities_sent = 1; - - return rru_config_msg->len; - } - if (s->last_msg == RRU_config) { - rru_config_msg->type = RRU_config_ok; - return 0; - } - if (s->last_msg == RRU_start) { - s->benetel_priv = benetel_start(s->e.if_name, &s->buffers, s->dpdk_main_command_line); - } - /* correct? */ - while (1) pause(); - - return 0; -} - -void benetel_fh_if4p5_south_in(RU_t *ru, - int *frame, - int *subframe) -{ - benetel_eth_state_t *s = ru->ifdevice.priv; - PHY_VARS_eNB **eNB_list = ru->eNB_list, *eNB; - LTE_DL_FRAME_PARMS *fp; - int symbol; - int32_t *rxdata; - int antenna; - - lock_ul_buffer(&s->buffers, *subframe); -next: - while (!((s->buffers.ul_busy[0][*subframe] == 0x3fff && - s->buffers.ul_busy[1][*subframe] == 0x3fff) || - s->buffers.prach_busy[*subframe] == 1)) - wait_ul_buffer(&s->buffers, *subframe); - if (s->buffers.prach_busy[*subframe] == 1) { - int i; - int antenna = 0; - uint16_t *in; - uint16_t *out; - in = (uint16_t *)s->buffers.prach[*subframe]; - out = (uint16_t *)ru->prach_rxsigF[0][antenna]; - for (i = 0; i < 840*2; i++) - out[i] = ntohs(in[i]); - s->buffers.prach_busy[*subframe] = 0; - ru->wakeup_prach_eNB(ru->eNB_list[0], ru, *frame, *subframe); - goto next; - } - - eNB = eNB_list[0]; - fp = &eNB->frame_parms; - for (antenna = 0; antenna < ru->nb_rx; antenna++) { - for (symbol = 0; symbol < 14; symbol++) { - int i; - uint16_t *p = (uint16_t *)(&s->buffers.ul[antenna][*subframe][symbol*1200*4]); - for (i = 0; i < 1200*2; i++) { - p[i] = htons(p[i]); - } - rxdata = &ru->common.rxdataF[antenna][symbol * fp->ofdm_symbol_size]; -#if 1 - memcpy(rxdata + 2048 - 600, - &s->buffers.ul[antenna][*subframe][symbol*1200*4], - 600 * 4); - memcpy(rxdata, - &s->buffers.ul[antenna][*subframe][symbol*1200*4] + 600*4, - 600 * 4); -#endif - } - } - - s->buffers.ul_busy[0][*subframe] = 0; - s->buffers.ul_busy[1][*subframe] = 0; - signal_ul_buffer(&s->buffers, *subframe); - unlock_ul_buffer(&s->buffers, *subframe); - - //printf("BENETEL: %s (f.sf %d.%d)\n", __FUNCTION__, *frame, *subframe); - - RU_proc_t *proc = &ru->proc; - extern int sf_ahead; - int f = *frame; - int sf = *subframe; - - //calculate timestamp_rx, timestamp_tx based on frame and subframe - proc->tti_rx = sf; - proc->frame_rx = f; - proc->timestamp_rx = ((proc->frame_rx * 10) + proc->tti_rx ) * fp->samples_per_tti ; - - if (get_nprocs()<=4) { - proc->tti_tx = (sf+sf_ahead)%10; - proc->frame_tx = (sf>(9-sf_ahead)) ? (f+1)&1023 : f; - } - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_IF4P5_SOUTH_IN_RU+ru->idx,f); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_IF4P5_SOUTH_IN_RU+ru->idx,sf); - proc->symbol_mask[sf] = 0; - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff); - -} - -void benetel_fh_if4p5_south_out(RU_t *ru, - int frame, - int subframe, - uint64_t timestamp) -{ - benetel_eth_state_t *s = ru->ifdevice.priv; - PHY_VARS_eNB **eNB_list = ru->eNB_list, *eNB; - LTE_DL_FRAME_PARMS *fp; - int symbol; - int32_t *txdata; - int aa; - - //printf("BENETEL: %s (f.sf %d.%d ts %ld)\n", __FUNCTION__, frame, subframe, timestamp); - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff ); - - lock_dl_buffer(&s->buffers, subframe); - if (s->buffers.dl_busy[0][subframe] || - s->buffers.dl_busy[1][subframe]) { - printf("%s: fatal: DL buffer busy for subframe %d\n", __FUNCTION__, subframe); - unlock_dl_buffer(&s->buffers, subframe); - return; - } - eNB = eNB_list[0]; - fp = &eNB->frame_parms; - if (ru->num_eNB != 1 || fp->ofdm_symbol_size != 2048 || - fp->Ncp != NORMAL || fp->symbols_per_tti != 14) { - printf("%s:%d:%s: unsupported configuration\n", - __FILE__, __LINE__, __FUNCTION__); - exit(1); - } - - for (aa = 0; aa < ru->nb_tx; aa++) { - for (symbol = 0; symbol < 14; symbol++) { - txdata = &ru->common.txdataF_BF[aa][symbol * fp->ofdm_symbol_size]; -#if 1 - memcpy(&s->buffers.dl[aa][subframe][symbol*1200*4], - txdata + 2048 - 600, - 600 * 4); - memcpy(&s->buffers.dl[aa][subframe][symbol*1200*4] + 600*4, - txdata + 1, - 600 * 4); -#endif - int i; - uint16_t *p = (uint16_t *)(&s->buffers.dl[aa][subframe][symbol*1200*4]); - for (i = 0; i < 1200*2; i++) { - p[i] = htons(p[i]); - } - } - } - - s->buffers.dl_busy[0][subframe] = 0x3fff; - s->buffers.dl_busy[1][subframe] = 0x3fff; - unlock_dl_buffer(&s->buffers, subframe); - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_IF4P5_SOUTH_OUT_RU+ru->idx, ru->proc.frame_tx); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_IF4P5_SOUTH_OUT_RU+ru->idx, ru->proc.tti_tx); - -} - -void *get_internal_parameter(char *name) -{ - printf("BENETEL: %s\n", __FUNCTION__); - - if (!strcmp(name, "fh_if4p5_south_in")) - return benetel_fh_if4p5_south_in; - if (!strcmp(name, "fh_if4p5_south_out")) - return benetel_fh_if4p5_south_out; - - return NULL; -} - -__attribute__((__visibility__("default"))) -int transport_init(openair0_device *device, - openair0_config_t *openair0_cfg, - eth_params_t * eth_params ) -{ - benetel_eth_state_t *eth; - - printf("BENETEL: %s\n", __FUNCTION__); - - device->Mod_id = 0; - device->transp_type = ETHERNET_TP; - device->trx_start_func = trx_benetel_start; - device->trx_get_stats_func = trx_benetel_get_stats; - device->trx_reset_stats_func = trx_benetel_reset_stats; - device->trx_end_func = trx_benetel_end; - device->trx_stop_func = trx_benetel_stop; - device->trx_set_freq_func = trx_benetel_set_freq; - device->trx_set_gains_func = trx_benetel_set_gains; - - device->trx_write_func = trx_benetel_write_raw; - device->trx_read_func = trx_benetel_read_raw; - - device->trx_ctlsend_func = trx_benetel_ctlsend; - device->trx_ctlrecv_func = trx_benetel_ctlrecv; - - device->get_internal_parameter = get_internal_parameter; - - eth = calloc(1, sizeof(benetel_eth_state_t)); - if (eth == NULL) { - AssertFatal(0==1, "out of memory\n"); - } - - eth->e.flags = ETH_RAW_IF4p5_MODE; - eth->e.compression = NO_COMPRESS; - eth->e.if_name = eth_params->local_if_name; - device->priv = eth; - device->openair0_cfg=&openair0_cfg[0]; - - if (openair0_cfg->sdr_addrs == NULL) { - printf("benetel: fatal: sdr_addrs not set in configuration file\n"); - exit(1); - } - - eth->dpdk_main_command_line = strdup(openair0_cfg->sdr_addrs); - if (eth->dpdk_main_command_line == NULL) { - AssertFatal(0==1, "out of memory\n"); - } - - eth->last_msg = -1; - - init_buffers(ð->buffers); - - return 0; -} diff --git a/radio/ETHERNET/benetel/4g/dpdk_driver.c b/radio/ETHERNET/benetel/4g/dpdk_driver.c deleted file mode 100644 index 2b6ef37e6f..0000000000 --- a/radio/ETHERNET/benetel/4g/dpdk_driver.c +++ /dev/null @@ -1,774 +0,0 @@ -/* license: to be defined */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "low.h" - -// HEADER DEFINITION -#define ANT_NUM buf[23] -#define PAYLOAD_1 buf[20] -#define PAYLOAD_2 buf[21] -#define ETH_TYPE buf[17] -#define SYMBOL buf[29] -#define SUBFRAME buf[28] -#define FRAME buf[27] - -static volatile bool force_quit; - -unsigned short iq[33600]; -unsigned char iq_swap[67200]; - -unsigned short *iq_ptr[14]; -unsigned int dl_start = 0; - -/* MAC updating enabled by default */ -static int mac_updating = 1; -#define RTE_LOGTYPE_L2FWD RTE_LOGTYPE_USER1 -#define MAX_PKT_BURST 32 -#define BURST_TX_DRAIN_US 5 /* TX drain every ~100us */ -#define MEMPOOL_CACHE_SIZE 256 -/* - * Configurable number of RX/TX ring descriptors - */ -#define RTE_TEST_RX_DESC_DEFAULT 1024 -#define RTE_TEST_TX_DESC_DEFAULT 1024 -static uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; -static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; -/* ethernet addresses of ports */ -static struct ether_addr l2fwd_ports_eth_addr[RTE_MAX_ETHPORTS]; -/* mask of enabled ports */ -static uint32_t l2fwd_enabled_port_mask = 0; -/* list of enabled ports */ -static uint32_t l2fwd_dst_ports[RTE_MAX_ETHPORTS]; -static unsigned int l2fwd_rx_queue_per_lcore = 1; -#define MAX_RX_QUEUE_PER_LCORE 16 -#define MAX_TX_QUEUE_PER_PORT 16 -struct lcore_queue_conf { - unsigned n_rx_port; - unsigned rx_port_list[MAX_RX_QUEUE_PER_LCORE]; -} __rte_cache_aligned; -struct lcore_queue_conf lcore_queue_conf[RTE_MAX_LCORE]; -static struct rte_eth_dev_tx_buffer *tx_buffer[RTE_MAX_ETHPORTS]; -static struct rte_eth_conf port_conf = { - .rxmode = { - .split_hdr_size = 0, - .offloads = DEV_RX_OFFLOAD_JUMBO_FRAME, - .split_hdr_size = 0, - .max_rx_pkt_len = 9500, - }, - .txmode = { - .mq_mode = ETH_MQ_TX_NONE, - }, -}; -struct rte_mempool * l2fwd_pktmbuf_pool = NULL; -/* Per-port statistics struct */ -struct l2fwd_port_statistics { - uint64_t tx; - uint64_t rx; - uint64_t dropped; -} __rte_cache_aligned; -struct l2fwd_port_statistics port_statistics[RTE_MAX_ETHPORTS]; -#define MAX_TIMER_PERIOD 86400 /* 1 day max */ -/* A tsc-based timer responsible for triggering statistics printout */ -static uint64_t timer_period = 10; /* default period is 10 seconds */ -/* Print out statistics on packets dropped */ -static void -print_stats(void) -{ - uint64_t total_packets_dropped, total_packets_tx, total_packets_rx; - unsigned portid; - total_packets_dropped = 0; - total_packets_tx = 0; - total_packets_rx = 0; - const char clr[] = { 27, '[', '2', 'J', '\0' }; - const char topLeft[] = { 27, '[', '1', ';', '1', 'H','\0' }; - /* Clear screen and move to top left */ - printf("%s%s", clr, topLeft); - printf("\nPort statistics ===================================="); - for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) { - /* skip disabled ports */ - if ((l2fwd_enabled_port_mask & (1 << portid)) == 0) - continue; - printf("\nStatistics for port %u ------------------------------" - "\nPackets sent: %24"PRIu64 - "\nPackets received: %20"PRIu64 - "\nPackets dropped: %21"PRIu64, - portid, - port_statistics[portid].tx, - port_statistics[portid].rx, - port_statistics[portid].dropped); - total_packets_dropped += port_statistics[portid].dropped; - total_packets_tx += port_statistics[portid].tx; - total_packets_rx += port_statistics[portid].rx; - } - printf("\nAggregate statistics ===============================" - "\nTotal packets sent: %18"PRIu64 - "\nTotal packets received: %14"PRIu64 - "\nTotal packets dropped: %15"PRIu64, - total_packets_tx, - total_packets_rx, - total_packets_dropped); - printf("\n====================================================\n"); -} -static void -l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) -{ - unsigned char *buf, *buf_tx; - unsigned int len; - struct ether_hdr *eth; - - unsigned dst_port; - int sent, prach_ctrl = 0; - struct rte_eth_dev_tx_buffer *buffer; - - unsigned char * IQ_ptr; - - ul_packet_t p; - - buf = rte_pktmbuf_mtod(m, unsigned char *); - //rte_memdump(stdout, "Rx Packet",buf ,34); - eth = rte_pktmbuf_mtod(m, struct ether_hdr *); - len = rte_pktmbuf_data_len(m); - - IQ_ptr = &buf[34]; - - //destination mac address (RRU MAC) - eth->d_addr.addr_bytes[0] = 0x02; - eth->d_addr.addr_bytes[1] = 0x00; - eth->d_addr.addr_bytes[2] = 0x5e; - eth->d_addr.addr_bytes[3] = 0x01; - eth->d_addr.addr_bytes[4] = 0x01; - eth->d_addr.addr_bytes[5] = 0x01; - - //source mac address (DU MAC) - eth->s_addr.addr_bytes[0] = 0xdd; - eth->s_addr.addr_bytes[1] = 0xdd; - eth->s_addr.addr_bytes[2] = 0xdd; - eth->s_addr.addr_bytes[3] = 0xdd; - eth->s_addr.addr_bytes[4] = 0xdd; - eth->s_addr.addr_bytes[5] = 0xdd; - - dst_port = l2fwd_dst_ports[portid]; - #if 1 - - if (buf[18] == 0xAA) //msg1 check - { - printf("\nHandshake MSG 1 Received\n"); - printf("\n====================================================\n"); - - buf[18] = 0xBB;//change to msg2 after receive msg1 - - printf("Handshake MSG 2 Sent\n"); - printf("\n====================================================\n"); - } - - #else - // Handshake Condition - if (buf[18] == 0x01 || buf[18] == 0x03) // ORAN handshake msgs. - { - if (buf[18] == 0x01) //msg1 check - { - printf("\nHandshake MSG 1 Received\n"); - printf("\n====================================================\n"); - - buf[18] = 0x02;//change to msg2 after receive msg1 - - printf("Handshake MSG 2 Sent\n"); - printf("\n====================================================\n"); - } - - else if(buf[18] == 0x03) //msg3 check - { - printf("Handshake MSG 3 Sent\n"); - printf("\n====================================================\n"); - - buf[18] = 0x04; - - printf("Handshake MSG 4 Sent\n"); - printf("\n====================================================\n"); - } - } - #endif - // Trigger start send DL packets - if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && SYMBOL == 0x09 && ANT_NUM == 0x00 && dl_start == 0){ - - printf("\nU-Plane Started\n"); - printf("\n====================================================\n"); - - dl_start = 1; - } - - - if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce) { - p.frame = FRAME; - p.subframe = SUBFRAME >> 4; - p.slot = 0; /* unused */ - p.symbol = SYMBOL; - p.antenna = ANT_NUM; - memcpy(p.iq, IQ_ptr, 4800); - store_ul(bs, &p); - } - - // U-PLANE UL PROCESSING - if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && dl_start == 1) - { - int a = ANT_NUM; - int tx_frame = FRAME; - int tx_subframe = SUBFRAME >> 4; - int tx_symbol = SYMBOL + 5; - if (tx_symbol > 13) { - tx_symbol -= 14; - tx_subframe++; - if (tx_subframe == 10) { - tx_subframe = 0; - tx_frame = (tx_frame + 1) & 255; - } - } - -// ANT_NUM = 0x00; -// SYMBOL = (SYMBOL + 5) % 14; - PAYLOAD_2 = 0xc8; - - FRAME = tx_frame; - SUBFRAME = tx_subframe << 4; - SYMBOL = tx_symbol; - - /* send actual DL data (if available) */ - lock_dl_buffer(bs->buffers, tx_subframe); - if (!(bs->buffers->dl_busy[a][tx_subframe] & (1 << tx_symbol))) { - printf("%s: warning, DL underflow (antenna %d sf.symbol %d.%d)\n", - __FUNCTION__, - a, - tx_subframe, tx_symbol); - memset(IQ_ptr, 0, 1200 * 4); - } else { - memcpy(IQ_ptr, bs->buffers->dl[a][tx_subframe] + tx_symbol * 1200*4, - 1200*4); - } - bs->buffers->dl_busy[a][tx_subframe] &= ~(1 << tx_symbol); - unlock_dl_buffer(bs->buffers, tx_subframe); - } - - // U-PLANE PRACH PROCESSING - else if(PAYLOAD_1 == 0x0d && PAYLOAD_2 == 0x28){ - if (ANT_NUM == 0) { - store_prach(bs, FRAME, SUBFRAME>>4, IQ_ptr); - } - - rte_pktmbuf_free(m); - return; - } - - // Send Packets - buffer = tx_buffer[dst_port]; - - sent = rte_eth_tx_buffer(dst_port, 0, buffer, m); - - if (sent) - port_statistics[dst_port].tx += sent; - -} -/* main processing loop */ -static void -l2fwd_main_loop(benetel_t *bs) -{ - struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; - struct rte_mbuf *m; - int sent; - unsigned lcore_id; - uint64_t prev_tsc, diff_tsc, cur_tsc, timer_tsc; - unsigned i, j, portid, nb_rx; - struct lcore_queue_conf *qconf; - const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) / US_PER_S * - BURST_TX_DRAIN_US; - struct rte_eth_dev_tx_buffer *buffer; - prev_tsc = 0; - timer_tsc = 0; - lcore_id = rte_lcore_id(); - qconf = &lcore_queue_conf[lcore_id]; - if (qconf->n_rx_port == 0) { - RTE_LOG(INFO, L2FWD, "lcore %u has nothing to do\n", lcore_id); - return; - } - RTE_LOG(INFO, L2FWD, "entering main loop on lcore %u\n", lcore_id); - for (i = 0; i < qconf->n_rx_port; i++) { - portid = qconf->rx_port_list[i]; - RTE_LOG(INFO, L2FWD, " -- lcoreid=%u portid=%u\n", lcore_id, - portid); - } - while (!force_quit) { - cur_tsc = rte_rdtsc(); - /* - * TX burst queue drain - */ - diff_tsc = cur_tsc - prev_tsc; - if (unlikely(diff_tsc > drain_tsc)) { - for (i = 0; i < qconf->n_rx_port; i++) { - portid = l2fwd_dst_ports[qconf->rx_port_list[i]]; - buffer = tx_buffer[portid]; - sent = rte_eth_tx_buffer_flush(portid, 0, buffer); - if (sent) - port_statistics[portid].tx += sent; - } - /* if timer is enabled */ - if (timer_period > 0) { - /* advance the timer */ - timer_tsc += diff_tsc; - /* if timer has reached its timeout */ - if (unlikely(timer_tsc >= timer_period)) { - /* do this only on master core */ - if (lcore_id == rte_get_master_lcore()) { - //print_stats(); - /* reset the timer */ - timer_tsc = 0; - } - } - } - prev_tsc = cur_tsc; - } - /* - * Read packet from RX queues - */ - for (i = 0; i < qconf->n_rx_port; i++) { - portid = qconf->rx_port_list[i]; - nb_rx = rte_eth_rx_burst(portid, 0, - pkts_burst, MAX_PKT_BURST); - port_statistics[portid].rx += nb_rx; - for (j = 0; j < nb_rx; j++) { - m = pkts_burst[j]; - rte_prefetch0(rte_pktmbuf_mtod(m, void *)); - l2fwd_simple_forward(m, portid, bs); - } - } - } -} -static int -l2fwd_launch_one_lcore(void *bs) -{ - l2fwd_main_loop(bs); - return 0; -} -/* display usage */ -static void -l2fwd_usage(const char *prgname) -{ - printf("%s [EAL options] -- -p PORTMASK [-q NQ]\n" - " -p PORTMASK: hexadecimal bitmask of ports to configure\n" - " -q NQ: number of queue (=ports) per lcore (default is 1)\n" - " -T PERIOD: statistics will be refreshed each PERIOD seconds (0 to disable, 10 default, 86400 maximum)\n" - " --[no-]mac-updating: Enable or disable MAC addresses updating (enabled by default)\n" - " When enabled:\n" - " - The source MAC address is replaced by the TX port MAC address\n" - " - The destination MAC address is replaced by 02:00:00:00:00:TX_PORT_ID\n", - prgname); -} -static int -l2fwd_parse_portmask(const char *portmask) -{ - char *end = NULL; - unsigned long pm; - /* parse hexadecimal string */ - pm = strtoul(portmask, &end, 16); - if ((portmask[0] == '\0') || (end == NULL) || (*end != '\0')) - return -1; - if (pm == 0) - return -1; - return pm; -} -static unsigned int -l2fwd_parse_nqueue(const char *q_arg) -{ - char *end = NULL; - unsigned long n; - /* parse hexadecimal string */ - n = strtoul(q_arg, &end, 10); - if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0')) - return 0; - if (n == 0) - return 0; - if (n >= MAX_RX_QUEUE_PER_LCORE) - return 0; - return n; -} -static int -l2fwd_parse_timer_period(const char *q_arg) -{ - char *end = NULL; - int n; - /* parse number string */ - n = strtol(q_arg, &end, 10); - if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0')) - return -1; - if (n >= MAX_TIMER_PERIOD) - return -1; - return n; -} -static const char short_options[] = - "p:" /* portmask */ - "q:" /* number of queues */ - "T:" /* timer period */ - ; -#define CMD_LINE_OPT_MAC_UPDATING "mac-updating" -#define CMD_LINE_OPT_NO_MAC_UPDATING "no-mac-updating" -enum { - /* long options mapped to a short option */ - /* first long only option value must be >= 256, so that we won't - * conflict with short options */ - CMD_LINE_OPT_MIN_NUM = 256, -}; -static const struct option lgopts[] = { - { CMD_LINE_OPT_MAC_UPDATING, no_argument, &mac_updating, 1}, - { CMD_LINE_OPT_NO_MAC_UPDATING, no_argument, &mac_updating, 0}, - {NULL, 0, 0, 0} -}; -/* Parse the argument given in the command line of the application */ -static int -l2fwd_parse_args(int argc, char **argv) -{ - int opt, ret, timer_secs; - char **argvopt; - int option_index; - char *prgname = argv[0]; - argvopt = argv; - while ((opt = getopt_long(argc, argvopt, short_options, - lgopts, &option_index)) != EOF) { - switch (opt) { - /* portmask */ - case 'p': - l2fwd_enabled_port_mask = l2fwd_parse_portmask(optarg); - if (l2fwd_enabled_port_mask == 0) { - printf("invalid portmask\n"); - l2fwd_usage(prgname); - return -1; - } - break; - /* nqueue */ - case 'q': - l2fwd_rx_queue_per_lcore = l2fwd_parse_nqueue(optarg); - if (l2fwd_rx_queue_per_lcore == 0) { - printf("invalid queue number\n"); - l2fwd_usage(prgname); - return -1; - } - break; - /* timer period */ - case 'T': - timer_secs = l2fwd_parse_timer_period(optarg); - if (timer_secs < 0) { - printf("invalid timer period\n"); - l2fwd_usage(prgname); - return -1; - } - timer_period = timer_secs; - break; - /* long options */ - case 0: - break; - default: - l2fwd_usage(prgname); - return -1; - } - } - if (optind >= 0) - argv[optind-1] = prgname; - ret = optind-1; - optind = 1; /* reset getopt lib */ - return ret; -} -/* Check the link status of all ports in up to 9s, and print them finally */ -static void -check_all_ports_link_status(uint32_t port_mask) -{ -#define CHECK_INTERVAL 100 /* 100ms */ -#define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */ - uint16_t portid; - uint8_t count, all_ports_up, print_flag = 0; - struct rte_eth_link link; - printf("\nChecking link status"); - fflush(stdout); - for (count = 0; count <= MAX_CHECK_TIME; count++) { - if (force_quit) - return; - all_ports_up = 1; - RTE_ETH_FOREACH_DEV(portid) { - if (force_quit) - return; - if ((port_mask & (1 << portid)) == 0) - continue; - memset(&link, 0, sizeof(link)); - rte_eth_link_get_nowait(portid, &link); - /* print link status if flag set */ - if (print_flag == 1) { - if (link.link_status) - printf( - "Port%d Link Up. Speed %u Mbps - %s\n", - portid, link.link_speed, - (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? - ("full-duplex") : ("half-duplex\n")); - else - printf("Port %d Link Down\n", portid); - continue; - } - /* clear all_ports_up flag if any link down */ - if (link.link_status == ETH_LINK_DOWN) { - all_ports_up = 0; - break; - } - } - /* after finally printing all link status, get out */ - if (print_flag == 1) - break; - if (all_ports_up == 0) { - printf("."); - fflush(stdout); - rte_delay_ms(CHECK_INTERVAL); - } - /* set the print_flag if all ports up or timeout */ - if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) { - print_flag = 1; - printf("done\n"); - } - } -} -static void -signal_handler(int signum) -{ - if (signum == SIGINT || signum == SIGTERM) { - printf("\n\nSignal %d received, preparing to exit...\n", - signum); - force_quit = true; - } -} -int -dpdk_main(int argc, char **argv, benetel_t *bs) -{ - struct lcore_queue_conf *qconf; - int ret; - uint16_t nb_ports; - uint16_t nb_ports_available = 0; - uint16_t portid, last_port; - unsigned lcore_id, rx_lcore_id; - unsigned nb_ports_in_mask = 0; - unsigned int nb_lcores = 0; - unsigned int nb_mbufs; - /* init EAL */ - ret = rte_eal_init(argc, argv); - if (ret < 0) - rte_exit(EXIT_FAILURE, "Invalid EAL arguments\n"); - argc -= ret; - argv += ret; - force_quit = false; - signal(SIGINT, signal_handler); - signal(SIGTERM, signal_handler); - /* parse application arguments (after the EAL ones) */ - ret = l2fwd_parse_args(argc, argv); - if (ret < 0) - rte_exit(EXIT_FAILURE, "Invalid L2FWD arguments\n"); - printf("MAC updating %s\n", mac_updating ? "enabled" : "disabled"); - /* convert to number of cycles */ - timer_period *= rte_get_timer_hz(); - nb_ports = rte_eth_dev_count_avail(); - if (nb_ports == 0) - rte_exit(EXIT_FAILURE, "No Ethernet ports - bye\n"); - /* check port mask to possible port mask */ - if (l2fwd_enabled_port_mask & ~((1 << nb_ports) - 1)) - rte_exit(EXIT_FAILURE, "Invalid portmask; possible (0x%x)\n", - (1 << nb_ports) - 1); - /* reset l2fwd_dst_ports */ - for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) - l2fwd_dst_ports[portid] = 0; - last_port = 0; - /* - * Each logical core is assigned a dedicated TX queue on each port. - */ - RTE_ETH_FOREACH_DEV(portid) { - /* skip ports that are not enabled */ - if ((l2fwd_enabled_port_mask & (1 << portid)) == 0) - continue; - if (nb_ports_in_mask % 2) { - l2fwd_dst_ports[portid] = last_port; - l2fwd_dst_ports[last_port] = portid; - } - else - last_port = portid; - nb_ports_in_mask++; - } - if (nb_ports_in_mask % 2) { - printf("Notice: odd number of ports in portmask.\n"); - l2fwd_dst_ports[last_port] = last_port; - } - rx_lcore_id = 0; - qconf = NULL; - /* Initialize the port/queue configuration of each logical core */ - RTE_ETH_FOREACH_DEV(portid) { - /* skip ports that are not enabled */ - if ((l2fwd_enabled_port_mask & (1 << portid)) == 0) - continue; - /* get the lcore_id for this port */ - while (rte_lcore_is_enabled(rx_lcore_id) == 0 || - lcore_queue_conf[rx_lcore_id].n_rx_port == - l2fwd_rx_queue_per_lcore) { - rx_lcore_id++; - if (rx_lcore_id >= RTE_MAX_LCORE) - rte_exit(EXIT_FAILURE, "Not enough cores\n"); - } - if (qconf != &lcore_queue_conf[rx_lcore_id]) { - /* Assigned a new logical core in the loop above. */ - qconf = &lcore_queue_conf[rx_lcore_id]; - nb_lcores++; - } - qconf->rx_port_list[qconf->n_rx_port] = portid; - qconf->n_rx_port++; - printf("Lcore %u: RX port %u\n", rx_lcore_id, portid); - } - nb_mbufs = RTE_MAX(nb_ports * (nb_rxd + nb_txd + MAX_PKT_BURST + - nb_lcores * MEMPOOL_CACHE_SIZE), 8192U); - /* create the mbuf pool */ - l2fwd_pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", nb_mbufs, - MEMPOOL_CACHE_SIZE, 0, 9680, - rte_socket_id()); - if (l2fwd_pktmbuf_pool == NULL) - rte_exit(EXIT_FAILURE, "Cannot init mbuf pool\n"); - /* Initialise each port */ - RTE_ETH_FOREACH_DEV(portid) { - struct rte_eth_rxconf rxq_conf; - struct rte_eth_txconf txq_conf; - struct rte_eth_conf local_port_conf = port_conf; - struct rte_eth_dev_info dev_info; - /* skip ports that are not enabled */ - if ((l2fwd_enabled_port_mask & (1 << portid)) == 0) { - printf("Skipping disabled port %u\n", portid); - continue; - } - nb_ports_available++; - /* init port */ - printf("Initializing port %u... ", portid); - fflush(stdout); - rte_eth_dev_info_get(portid, &dev_info); - if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE) - local_port_conf.txmode.offloads |= - DEV_TX_OFFLOAD_MBUF_FAST_FREE; - ret = rte_eth_dev_configure(portid, 1, 1, &local_port_conf); - if (ret < 0) - rte_exit(EXIT_FAILURE, "Cannot configure device: err=%d, port=%u\n", - ret, portid); - ret = rte_eth_dev_adjust_nb_rx_tx_desc(portid, &nb_rxd, - &nb_txd); - if (ret < 0) - rte_exit(EXIT_FAILURE, - "Cannot adjust number of descriptors: err=%d, port=%u\n", - ret, portid); - rte_eth_macaddr_get(portid,&l2fwd_ports_eth_addr[portid]); - /* init one RX queue */ - fflush(stdout); - rxq_conf = dev_info.default_rxconf; - rxq_conf.offloads = local_port_conf.rxmode.offloads; - ret = rte_eth_rx_queue_setup(portid, 0, nb_rxd, - rte_eth_dev_socket_id(portid), - &rxq_conf, - l2fwd_pktmbuf_pool); - if (ret < 0) - rte_exit(EXIT_FAILURE, "rte_eth_rx_queue_setup:err=%d, port=%u\n", - ret, portid); - /* init one TX queue on each port */ - fflush(stdout); - txq_conf = dev_info.default_txconf; - txq_conf.offloads = local_port_conf.txmode.offloads; - ret = rte_eth_tx_queue_setup(portid, 0, nb_txd, - rte_eth_dev_socket_id(portid), - &txq_conf); - if (ret < 0) - rte_exit(EXIT_FAILURE, "rte_eth_tx_queue_setup:err=%d, port=%u\n", - ret, portid); - /* Initialize TX buffers */ - tx_buffer[portid] = rte_zmalloc_socket("tx_buffer", - RTE_ETH_TX_BUFFER_SIZE(MAX_PKT_BURST), 0, - rte_eth_dev_socket_id(portid)); - if (tx_buffer[portid] == NULL) - rte_exit(EXIT_FAILURE, "Cannot allocate buffer for tx on port %u\n", - portid); - rte_eth_tx_buffer_init(tx_buffer[portid], MAX_PKT_BURST); - ret = rte_eth_tx_buffer_set_err_callback(tx_buffer[portid], - rte_eth_tx_buffer_count_callback, - &port_statistics[portid].dropped); - if (ret < 0) - rte_exit(EXIT_FAILURE, - "Cannot set error callback for tx buffer on port %u\n", - portid); - /* Start device */ - ret = rte_eth_dev_start(portid); - if (ret < 0) - rte_exit(EXIT_FAILURE, "rte_eth_dev_start:err=%d, port=%u\n", - ret, portid); - printf("done: \n"); - rte_eth_promiscuous_enable(portid); - printf("Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n\n", - portid, - l2fwd_ports_eth_addr[portid].addr_bytes[0], - l2fwd_ports_eth_addr[portid].addr_bytes[1], - l2fwd_ports_eth_addr[portid].addr_bytes[2], - l2fwd_ports_eth_addr[portid].addr_bytes[3], - l2fwd_ports_eth_addr[portid].addr_bytes[4], - l2fwd_ports_eth_addr[portid].addr_bytes[5]); - /* initialize port stats */ - memset(&port_statistics, 0, sizeof(port_statistics)); - } - if (!nb_ports_available) { - rte_exit(EXIT_FAILURE, - "All available ports are disabled. Please set portmask.\n"); - } - check_all_ports_link_status(l2fwd_enabled_port_mask); - ret = 0; - /* launch per-lcore init on every lcore */ - rte_eal_mp_remote_launch(l2fwd_launch_one_lcore, bs, CALL_MASTER); - RTE_LCORE_FOREACH_SLAVE(lcore_id) { - if (rte_eal_wait_lcore(lcore_id) < 0) { - ret = -1; - break; - } - } - RTE_ETH_FOREACH_DEV(portid) { - if ((l2fwd_enabled_port_mask & (1 << portid)) == 0) - continue; - printf("Closing port %d...", portid); - rte_eth_dev_stop(portid); - rte_eth_dev_close(portid); - printf(" Done\n"); - } - printf("Bye...\n"); - return ret; -} diff --git a/radio/ETHERNET/benetel/4g/low.c b/radio/ETHERNET/benetel/4g/low.c deleted file mode 100644 index 14783a700b..0000000000 --- a/radio/ETHERNET/benetel/4g/low.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#include "low.h" - -#include -#include -#include - -void store_ul(benetel_t *bs, ul_packet_t *ul) -{ - int a = ul->antenna; - - if (ul->subframe != bs->next_subframe[a] || - ul->symbol != bs->next_symbol[a]) { - printf("%s: fatal, antenna %d expected frame.sf.symbol %d.%d.%d, got %d.%d.%d\n", - __FUNCTION__, - a, - bs->expected_benetel_frame[a], bs->next_subframe[a], bs->next_symbol[a], - ul->frame, ul->subframe, ul->symbol); - exit(1); - } - - lock_ul_buffer(bs->buffers, bs->next_subframe[a]); - if (bs->buffers->ul_busy[a][bs->next_subframe[a]] & (1 << bs->next_symbol[a])) { - printf("%s: warning, UL overflow (sf.symbol %d.%d)\n", __FUNCTION__, - bs->next_subframe[a], bs->next_symbol[a]); - } - memcpy(bs->buffers->ul[a][bs->next_subframe[a]] + bs->next_symbol[a] * 1200*4, - ul->iq, 1200*4); - bs->buffers->ul_busy[a][bs->next_subframe[a]] |= (1 << bs->next_symbol[a]); - signal_ul_buffer(bs->buffers, bs->next_subframe[a]); - unlock_ul_buffer(bs->buffers, bs->next_subframe[a]); - - bs->next_symbol[a]++; - if (bs->next_symbol[a] == 14) { - bs->next_symbol[a] = 0; - bs->next_subframe[a] = (bs->next_subframe[a] + 1) % 10; - if (bs->next_subframe[a] == 0) { - bs->expected_benetel_frame[a]++; - bs->expected_benetel_frame[a] &= 255; - } - } -} - -void store_prach(benetel_t *bs, int frame, int subframe, void *data) -{ - static int last_frame = -1; - static int last_subframe = -1; - /* hack: antenna number is always 0, discard second packet with same f/sf */ - if (frame == last_frame && subframe == last_subframe) return; - last_frame = frame; - last_subframe = subframe; - - lock_ul_buffer(bs->buffers, subframe); - if (bs->buffers->prach_busy[subframe]) { - printf("store_prach: fatal: previous prach buffer not processed\n"); - unlock_ul_buffer(bs->buffers, subframe); - return; - } - bs->buffers->prach_busy[subframe] = 1; - memcpy(bs->buffers->prach[subframe], data, 849*4); - signal_ul_buffer(bs->buffers, subframe); - unlock_ul_buffer(bs->buffers, subframe); - -} - -void *benetel_start_dpdk(char *ifname, shared_buffers *buffers, char *dpdk_main_command_line); - -void *benetel_start(char *ifname, shared_buffers *buffers, char *dpdk_main_command_line) -{ - if (!strcmp(ifname, "dpdk")) - return benetel_start_dpdk(ifname, buffers, dpdk_main_command_line); - printf("benetel: fatal: interface %s not supported, only dpdpk is supported\n", ifname); - exit(1); -} diff --git a/radio/ETHERNET/benetel/4g/low.h b/radio/ETHERNET/benetel/4g/low.h deleted file mode 100644 index e74bf89163..0000000000 --- a/radio/ETHERNET/benetel/4g/low.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#ifndef _BENETEL_4G_LOW_H_ -#define _BENETEL_4G_LOW_H_ - -#include "shared_buffers.h" - -typedef struct { - shared_buffers *buffers; - /* [2] is for two antennas */ - int next_subframe[2]; - int next_symbol[2]; - int expected_benetel_frame[2]; - char *dpdk_main_command_line; -} benetel_t; - -typedef struct { - int frame; - int subframe; - int slot; - int symbol; - int antenna; - unsigned char iq[4800]; -} ul_packet_t; - -void *benetel_start(char *ifname, shared_buffers *buffers, char *dpdk_main_command_line); - -void store_ul(benetel_t *bs, ul_packet_t *ul); -void store_prach(benetel_t *bs, int frame, int subframe, void *data); - -#endif /* _BENETEL_4G_LOW_H_ */ diff --git a/radio/ETHERNET/benetel/4g/low_dpdk.c b/radio/ETHERNET/benetel/4g/low_dpdk.c deleted file mode 100644 index edf62a67e0..0000000000 --- a/radio/ETHERNET/benetel/4g/low_dpdk.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/* those 2 lines for CPU_SET */ -#define _GNU_SOURCE -#include - -#include -#include -#include -#include - -#include "low.h" - -int dpdk_main(int argc, char **argv, benetel_t *); - -void *dpdk_thread(void *_bs) -{ - benetel_t *bs = _bs; - int n = 0; - char **v = NULL; // { "softmodem", "-n", "2", "-l", "8", "--", "-p", "0x2" }; - char *s = bs->dpdk_main_command_line; - char *tok; - - while ((tok = strtok(s, " ")) != NULL) { - n++; - v = realloc(v, n * sizeof(char *)); - if (v == NULL) { - printf("%s: out of memory\n", __FUNCTION__); - exit(1); - } - v[n-1] = tok; - s = NULL; - } - - dpdk_main(n, v, bs); - exit(1); - return 0; -} - -void *benetel_start_dpdk(char *ifname, shared_buffers *buffers, char *dpdk_main_command_line) -{ - benetel_t *bs; - - bs = calloc(1, sizeof(benetel_t)); - if (bs == NULL) { - printf("%s: out of memory\n", __FUNCTION__); - exit(1); - } - - bs->buffers = buffers; - - bs->expected_benetel_frame[0] = 255; - bs->expected_benetel_frame[1] = 255; - - bs->dpdk_main_command_line = dpdk_main_command_line; - - pthread_attr_t attr; - - if (pthread_attr_init(&attr) != 0) { - printf("pthread_attr_init failed\n"); - exit(1); - } - - cpu_set_t cpuset; - CPU_ZERO(&cpuset); - CPU_SET(12,&cpuset); - if (pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t), &cpuset) != 0) { - printf("pthread_attr_setaffinity_np failed\n"); - exit(1); - } - - if (pthread_attr_setschedpolicy(&attr, SCHED_FIFO) != 0) { - printf("pthread_attr_setschedpolicy failed\n"); - exit(1); - } - - struct sched_param params; - params.sched_priority = sched_get_priority_max(SCHED_FIFO); - if (sched_get_priority_max(SCHED_FIFO) == -1) { - printf("sched_get_priority_max failed\n"); - exit(1); - } - if (pthread_attr_setschedparam(&attr, ¶ms) != 0) { - printf("pthread_setschedparam failed\n"); - exit(1); - } - - pthread_t t; - if (pthread_create(&t, &attr, dpdk_thread, bs) != 0) { - printf("%s: thread creation failed\n", __FUNCTION__); - exit(1); - } - - if (pthread_attr_destroy(&attr) != 0) { - printf("pthread_attr_init failed\n"); - exit(1); - } - - return bs; -} diff --git a/radio/ETHERNET/benetel/4g/shared_buffers.c b/radio/ETHERNET/benetel/4g/shared_buffers.c deleted file mode 100644 index 380cbabc73..0000000000 --- a/radio/ETHERNET/benetel/4g/shared_buffers.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#include "shared_buffers.h" - -#include -#include -#include - -void init_buffers(shared_buffers *s) -{ - int subframe; - - memset(s, 0, sizeof(*s)); - - for (subframe = 0; subframe < 10; subframe++) { - if (pthread_mutex_init(&s->m_dl[subframe], NULL) != 0 || - pthread_cond_init(&s->c_dl[subframe], NULL) != 0 || - pthread_mutex_init(&s->m_ul[subframe], NULL) != 0 || - pthread_cond_init(&s->c_ul[subframe], NULL) != 0) { - printf("%s: error initializing mutex/cond\n", __FUNCTION__); - exit(1); - } - } - - /* in FDD the eNB's first transmitted DL subframe is 4 but the device - * needs to have subframes 1, 2 and 3 ready. Let's pretend there are ready. - */ - s->dl_busy[0][1] = 0x3fff; - s->dl_busy[0][2] = 0x3fff; - s->dl_busy[0][3] = 0x3fff; - s->dl_busy[1][1] = 0x3fff; - s->dl_busy[1][2] = 0x3fff; - s->dl_busy[1][3] = 0x3fff; -} - -void lock_dl_buffer(shared_buffers *s, int subframe) -{ - if (pthread_mutex_lock(&s->m_dl[subframe]) != 0) { - printf("%s: fatal: lock fails\n", __FUNCTION__); - exit(1); - } -} - -void unlock_dl_buffer(shared_buffers *s, int subframe) -{ - if (pthread_mutex_unlock(&s->m_dl[subframe]) != 0) { - printf("%s: fatal: unlock fails\n", __FUNCTION__); - exit(1); - } -} - -void wait_dl_buffer(shared_buffers *s, int subframe) -{ - if (pthread_cond_wait(&s->c_dl[subframe], &s->m_dl[subframe]) != 0) { - printf("%s: fatal: cond_wait fails\n", __FUNCTION__); - exit(1); - } -} - -void signal_dl_buffer(shared_buffers *s, int subframe) -{ - if (pthread_cond_broadcast(&s->c_dl[subframe]) != 0) { - printf("%s: fatal: cond_broadcast fails\n", __FUNCTION__); - exit(1); - } -} - -void lock_ul_buffer(shared_buffers *s, int subframe) -{ - if (pthread_mutex_lock(&s->m_ul[subframe]) != 0) { - printf("%s: fatal: lock fails\n", __FUNCTION__); - exit(1); - } -} - -void unlock_ul_buffer(shared_buffers *s, int subframe) -{ - if (pthread_mutex_unlock(&s->m_ul[subframe]) != 0) { - printf("%s: fatal: unlock fails\n", __FUNCTION__); - exit(1); - } -} - -void wait_ul_buffer(shared_buffers *s, int subframe) -{ - if (pthread_cond_wait(&s->c_ul[subframe], &s->m_ul[subframe]) != 0) { - printf("%s: fatal: cond_wait fails\n", __FUNCTION__); - exit(1); - } -} - -void signal_ul_buffer(shared_buffers *s, int subframe) -{ - if (pthread_cond_broadcast(&s->c_ul[subframe]) != 0) { - printf("%s: fatal: cond_broadcast fails\n", __FUNCTION__); - exit(1); - } -} diff --git a/radio/ETHERNET/benetel/4g/shared_buffers.h b/radio/ETHERNET/benetel/4g/shared_buffers.h deleted file mode 100644 index ed174265c5..0000000000 --- a/radio/ETHERNET/benetel/4g/shared_buffers.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#ifndef _BENETEL_4G_SHARED_BUFFERS_H_ -#define _BENETEL_4G_SHARED_BUFFERS_H_ - -#include -#include - -typedef struct { - /* [2] is for two antennas */ - unsigned char dl[2][10][14*1200*4]; - unsigned char ul[2][10][14*1200*4]; - uint16_t dl_busy[2][10]; - uint16_t ul_busy[2][10]; - - pthread_mutex_t m_ul[10]; - pthread_cond_t c_ul[10]; - - pthread_mutex_t m_dl[10]; - pthread_cond_t c_dl[10]; - - unsigned char prach[10][849*4]; - unsigned char prach_busy[10]; - - /* statistics/error counting */ - int ul_overflow; - int dl_underflow; -} shared_buffers; - -void init_buffers(shared_buffers *s); - -void lock_dl_buffer(shared_buffers *s, int subframe); -void unlock_dl_buffer(shared_buffers *s, int subframe); -void wait_dl_buffer(shared_buffers *s, int subframe); -void signal_dl_buffer(shared_buffers *s, int subframe); - -void lock_ul_buffer(shared_buffers *s, int subframe); -void unlock_ul_buffer(shared_buffers *s, int subframe); -void wait_ul_buffer(shared_buffers *s, int subframe); -void signal_ul_buffer(shared_buffers *s, int subframe); - -#endif /* _BENETEL_4G_SHARED_BUFFERS_H_ */ diff --git a/radio/ETHERNET/benetel/5g/CMakeLists.txt b/radio/ETHERNET/benetel/5g/CMakeLists.txt deleted file mode 100644 index cdad594ce3..0000000000 --- a/radio/ETHERNET/benetel/5g/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -pkg_check_modules(libdpdk REQUIRED libdpdk=20.05.0) - -add_library(benetel_5g MODULE - benetel.c - shared_buffers.c - low.c - low_dpdk.c - dpdk_driver.c -) - -SET(DPDK_LIBS "-Wl,-rpath,$ENV{RTE_SDK}/$ENV{RTE_TARGET}/lib -Wl,--whole-archive -L$ENV{RTE_SDK}/$ENV{RTE_TARGET}/lib -ldpdk -Wl,--no-whole-archive") -target_include_directories(benetel_5g PRIVATE ${libdpdk_INCLUDE_DIRS}) -target_link_libraries(benetel_5g PRIVATE ${libdpdk_LIBRARIES}) -target_link_libraries(benetel_5g PRIVATE pthread dl rt m numa) -set_target_properties(benetel_5g PROPERTIES COMPILE_FLAGS "-fvisibility=hidden -I$ENV{RTE_SDK}/$ENV{RTE_TARGET}/include") -set_target_properties(benetel_5g PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) -add_custom_command(TARGET benetel_5g POST_BUILD - COMMAND ${CMAKE_COMMAND} -E create_symlink libbenetel_5g.so liboai_transpro.so - WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) diff --git a/radio/ETHERNET/benetel/5g/benetel.c b/radio/ETHERNET/benetel/5g/benetel.c deleted file mode 100644 index 996d568767..0000000000 --- a/radio/ETHERNET/benetel/5g/benetel.c +++ /dev/null @@ -1,399 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#include - -#include "common_lib.h" -#include "ethernet_lib.h" -#include "shared_buffers.h" -#include "low.h" -#include "openair1/PHY/defs_gNB.h" - -typedef struct { - eth_state_t e; - shared_buffers buffers; - rru_config_msg_type_t last_msg; - int capabilities_sent; - void *benetel_priv; - char *dpdk_main_command_line; -} benetel_eth_state_t; - -int trx_benetel_start(openair0_device *device) -{ - printf("BENETEL: %s\n", __FUNCTION__); - return 0; -} - - -void trx_benetel_end(openair0_device *device) -{ - printf("BENETEL: %s\n", __FUNCTION__); -} - - -int trx_benetel_stop(openair0_device *device) -{ - printf("BENETEL: %s\n", __FUNCTION__); - return(0); -} - - -int trx_benetel_set_freq(openair0_device* device, openair0_config_t *openair0_cfg) -{ - printf("BENETEL: %s\n", __FUNCTION__); - return(0); -} - - -int trx_benetel_set_gains(openair0_device* device, - openair0_config_t *openair0_cfg) -{ - printf("BENETEL: %s\n", __FUNCTION__); - return(0); -} - - -int trx_benetel_get_stats(openair0_device* device) -{ - printf("BENETEL: %s\n", __FUNCTION__); - return(0); -} - - -int trx_benetel_reset_stats(openair0_device* device) -{ - printf("BENETEL: %s\n", __FUNCTION__); - return(0); -} - - -int ethernet_tune(openair0_device *device, - unsigned int option, - int value) -{ - printf("BENETEL: %s\n", __FUNCTION__); - return 0; -} - -int trx_benetel_write_raw(openair0_device *device, - openair0_timestamp timestamp, - void **buff, int nsamps, int cc, int flags) -{ - printf("BENETEL: %s\n", __FUNCTION__); - return nsamps*4; -} - -int trx_benetel_read_raw(openair0_device *device, - openair0_timestamp *timestamp, - void **buff, int nsamps, int cc) -{ - printf("BENETEL: %s\n", __FUNCTION__); - return nsamps*4; -} - -char *msg_type(int t) -{ - static char *s[12] = { - "RAU_tick", - "RRU_capabilities", - "RRU_config", - "RRU_config_ok", - "RRU_start", - "RRU_stop", - "RRU_sync_ok", - "RRU_frame_resynch", - "RRU_MSG_max_num", - "RRU_check_sync", - "RRU_config_update", - "RRU_config_update_ok", - }; - - if (t < 0 || t > 11) return "UNKNOWN"; - return s[t]; -} - -int trx_benetel_ctlsend(openair0_device *device, void *msg, ssize_t msg_len) -{ - RRU_CONFIG_msg_t *rru_config_msg = msg; - benetel_eth_state_t *s = device->priv; - - printf("BENETEL: %s\n", __FUNCTION__); - - printf(" rru_config_msg->type %d [%s]\n", rru_config_msg->type, - msg_type(rru_config_msg->type)); - - s->last_msg = rru_config_msg->type; - - return msg_len; -} - -int trx_benetel_ctlrecv(openair0_device *device, void *msg, ssize_t msg_len) -{ - RRU_CONFIG_msg_t *rru_config_msg = msg; - benetel_eth_state_t *s = device->priv; - - printf("BENETEL: %s\n", __FUNCTION__); - - if (s->last_msg == RAU_tick && s->capabilities_sent == 0) { - RRU_capabilities_t *cap; - rru_config_msg->type = RRU_capabilities; - rru_config_msg->len = sizeof(RRU_CONFIG_msg_t)-MAX_RRU_CONFIG_SIZE+sizeof(RRU_capabilities_t); - cap = (RRU_capabilities_t*)&rru_config_msg->msg[0]; - cap->FH_fmt = OAI_IF4p5_only; - cap->num_bands = 1; - cap->band_list[0] = 78; - /* TODO: hardcoded to 1 for the moment, get the real value somehow... */ - cap->nb_rx[0] = 1; //device->openair0_cfg->rx_num_channels; - cap->nb_tx[0] = 1; //device->openair0_cfg->tx_num_channels; - cap->max_pdschReferenceSignalPower[0] = -27; - cap->max_rxgain[0] = 90; - - s->capabilities_sent = 1; - - return rru_config_msg->len; - } -#if 0 - if (s->last_msg == RRU_config) { - rru_config_msg->type = RRU_config_ok; - return 0; - } - if (s->last_msg == RRU_start) { -printf("***************** benetel start\n"); - s->benetel_priv = benetel_start(s->e.if_name, &s->buffers, s->dpdk_main_command_line); - } -#endif - if (s->last_msg == RRU_config) { - rru_config_msg->type = RRU_config_ok; - s->benetel_priv = benetel_start(s->e.if_name, &s->buffers, s->dpdk_main_command_line); - } - /* correct? */ -//printf("***************** benetel pause\n"); -// while (1) pause(); - - return 0; -} - -void benetel_fh_if4p5_south_in(RU_t *ru, - int *frame, - int *slot) -{ -//printf("XXX benetel_fh_if4p5_south_in %d %d\n", *frame, *slot); - benetel_eth_state_t *s = ru->ifdevice.priv; - NR_DL_FRAME_PARMS *fp; - int symbol; - int32_t *rxdata; - int antenna; - - lock_ul_buffer(&s->buffers, *slot); -#if 1 -next: - while (!((s->buffers.ul_busy[0][*slot] == 0x3fff && - s->buffers.ul_busy[1][*slot] == 0x3fff) || - s->buffers.prach_busy[*slot] == 1)) - wait_ul_buffer(&s->buffers, *slot); - if (s->buffers.prach_busy[*slot] == 1) { - int i; - int antenna = 0; - uint16_t *in; - uint16_t *out; - in = (uint16_t *)s->buffers.prach[*slot]; - out = (uint16_t *)ru->prach_rxsigF[0][antenna]; - for (i = 0; i < 839*2; i++) - out[i] = ntohs(in[i]); - s->buffers.prach_busy[*slot] = 0; - //printf("prach for f.sl %d.%d\n", *frame, *slot); - //ru->wakeup_prach_gNB(ru->gNB_list[0], ru, *frame, *slot); - goto next; - } -#endif - - fp = ru->nr_frame_parms; - for (antenna = 0; antenna < ru->nb_rx; antenna++) { - for (symbol = 0; symbol < 14; symbol++) { - int i; - int16_t *p = (int16_t *)(&s->buffers.ul[antenna][*slot][symbol*1272*4]); - for (i = 0; i < 1272*2; i++) { - p[i] = (int16_t)(ntohs(p[i])) / 16; - } - rxdata = &ru->common.rxdataF[antenna][symbol * fp->ofdm_symbol_size]; -#if 0 -if (*slot == 0 && symbol == 0) -printf("rxdata in benetel_fh_if4p5_south_in %p\n", &ru->common.rxdataF[antenna][0]); -#endif -#if 1 - memcpy(rxdata + 2048 - 1272/2, - &s->buffers.ul[antenna][*slot][symbol*1272*4], - (1272/2) * 4); - memcpy(rxdata, - &s->buffers.ul[antenna][*slot][symbol*1272*4] + (1272/2)*4, - (1272/2) * 4); -#endif - } - } - - s->buffers.ul_busy[0][*slot] = 0; - s->buffers.ul_busy[1][*slot] = 0; - signal_ul_buffer(&s->buffers, *slot); - unlock_ul_buffer(&s->buffers, *slot); - - //printf("BENETEL: %s (f.sf %d.%d)\n", __FUNCTION__, *frame, *slot); - - RU_proc_t *proc = &ru->proc; - int f = *frame; - int sl = *slot; - - //calculate timestamp_rx, timestamp_tx based on frame and slot - proc->tti_rx = sl; - proc->frame_rx = f; - /* TODO: be sure of samples_per_slot0 - FK: should use get_samples_per_slot(slot) - but for mu=1 its ok - */ - proc->timestamp_rx = ((proc->frame_rx * 20) + proc->tti_rx ) * fp->samples_per_slot0; - - if (get_nprocs()<=4) { - // why? what if there are more? - proc->tti_tx = (sl+ru->sl_ahead)%20; - proc->frame_tx = (sl>(19-ru->sl_ahead)) ? (f+1)&1023 : f; - } -} - -void benetel_fh_if4p5_south_out(RU_t *ru, - int frame, - int slot, - uint64_t timestamp) -{ - -//printf("XXX benetel_fh_if4p5_south_out %d %d %ld\n", frame, slot, timestamp); - benetel_eth_state_t *s = ru->ifdevice.priv; - NR_DL_FRAME_PARMS *fp; - int symbol; - int32_t *txdata; - int aa; - - //printf("BENETEL: %s (f.sf %d.%d ts %ld)\n", __FUNCTION__, frame, slot, timestamp); - - lock_dl_buffer(&s->buffers, slot); - if (s->buffers.dl_busy[0][slot] || - s->buffers.dl_busy[1][slot]) { - printf("%s: fatal: DL buffer busy for subframe %d\n", __FUNCTION__, slot); - unlock_dl_buffer(&s->buffers, slot); - return; - } - - fp = ru->nr_frame_parms; - if (ru->num_gNB != 1 || fp->ofdm_symbol_size != 2048 || - fp->Ncp != NORMAL || fp->symbols_per_slot != 14) { - printf("%s:%d:%s: unsupported configuration\n", - __FILE__, __LINE__, __FUNCTION__); - exit(1); - } - - for (aa = 0; aa < ru->nb_tx; aa++) { - for (symbol = 0; symbol < 14; symbol++) { - txdata = &ru->common.txdataF_BF[aa][symbol * fp->ofdm_symbol_size]; -#if 1 - memcpy(&s->buffers.dl[aa][slot][symbol*1272*4], - txdata + 2048 - (1272/2), - (1272/2) * 4); - memcpy(&s->buffers.dl[aa][slot][symbol*1272*4] + (1272/2)*4, - txdata, - (1272/2) * 4); -#endif - int i; - uint16_t *p = (uint16_t *)(&s->buffers.dl[aa][slot][symbol*1272*4]); - for (i = 0; i < 1272*2; i++) { - p[i] = htons(p[i]); - } - } - } - - s->buffers.dl_busy[0][slot] = 0x3fff; - s->buffers.dl_busy[1][slot] = 0x3fff; - unlock_dl_buffer(&s->buffers, slot); -} - -void *get_internal_parameter(char *name) -{ - printf("BENETEL: %s\n", __FUNCTION__); - - if (!strcmp(name, "fh_if4p5_south_in")) - return benetel_fh_if4p5_south_in; - if (!strcmp(name, "fh_if4p5_south_out")) - return benetel_fh_if4p5_south_out; - - return NULL; -} - -__attribute__((__visibility__("default"))) -int transport_init(openair0_device *device, - openair0_config_t *openair0_cfg, - eth_params_t * eth_params ) -{ - benetel_eth_state_t *eth; - - printf("BENETEL: %s\n", __FUNCTION__); - - device->Mod_id = 0; - device->transp_type = ETHERNET_TP; - device->trx_start_func = trx_benetel_start; - device->trx_get_stats_func = trx_benetel_get_stats; - device->trx_reset_stats_func = trx_benetel_reset_stats; - device->trx_end_func = trx_benetel_end; - device->trx_stop_func = trx_benetel_stop; - device->trx_set_freq_func = trx_benetel_set_freq; - device->trx_set_gains_func = trx_benetel_set_gains; - - device->trx_write_func = trx_benetel_write_raw; - device->trx_read_func = trx_benetel_read_raw; - - device->trx_ctlsend_func = trx_benetel_ctlsend; - device->trx_ctlrecv_func = trx_benetel_ctlrecv; - - device->get_internal_parameter = get_internal_parameter; - - eth = calloc(1, sizeof(benetel_eth_state_t)); - if (eth == NULL) { - AssertFatal(0==1, "out of memory\n"); - } - - eth->e.flags = ETH_RAW_IF4p5_MODE; - eth->e.compression = NO_COMPRESS; - eth->e.if_name = eth_params->local_if_name; - device->priv = eth; - device->openair0_cfg=&openair0_cfg[0]; - - if (openair0_cfg->sdr_addrs == NULL) { - printf("benetel: fatal: sdr_addrs not set in configuration file\n"); - exit(1); - } - - eth->dpdk_main_command_line = strdup(openair0_cfg->sdr_addrs); - if (eth->dpdk_main_command_line == NULL) { - AssertFatal(0==1, "out of memory\n"); - } - - eth->last_msg = -1; - - init_buffers(ð->buffers); - - return 0; -} diff --git a/radio/ETHERNET/benetel/5g/dpdk_driver.c b/radio/ETHERNET/benetel/5g/dpdk_driver.c deleted file mode 100644 index 9b398e9bd9..0000000000 --- a/radio/ETHERNET/benetel/5g/dpdk_driver.c +++ /dev/null @@ -1,835 +0,0 @@ -/* license: to be defined */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "low.h" - -// HEADER DEFINITION -#define ANT_NUM buf[23] -#define PAYLOAD_1 buf[20] -#define PAYLOAD_2 buf[21] -#define ETH_TYPE buf[17] -#define SYMBOL buf[29] -#define SUBFRAME buf[28] -#define FRAME buf[27] - -static volatile bool force_quit; - -unsigned short iq[712320]; -unsigned char iq_swap[1424640]; - -unsigned short *iq_ptr[14]; -unsigned int dl_start = 0, slot_id_ctrl = 0, count_symbol = 0, sf = 0x10; - -/* MAC updating enabled by default */ -static int mac_updating = 1; -#define RTE_LOGTYPE_L2FWD RTE_LOGTYPE_USER1 -#define MAX_PKT_BURST 32 -#define BURST_TX_DRAIN_US 5 /* TX drain every ~100us */ -#define MEMPOOL_CACHE_SIZE 256 -/* - * Configurable number of RX/TX ring descriptors - */ -#define RTE_TEST_RX_DESC_DEFAULT 1024 -#define RTE_TEST_TX_DESC_DEFAULT 1024 -static uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT; -static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT; -/* ethernet addresses of ports */ -static struct ether_addr l2fwd_ports_eth_addr[RTE_MAX_ETHPORTS]; -/* mask of enabled ports */ -static uint32_t l2fwd_enabled_port_mask = 0; -/* list of enabled ports */ -static uint32_t l2fwd_dst_ports[RTE_MAX_ETHPORTS]; -static unsigned int l2fwd_rx_queue_per_lcore = 1; -#define MAX_RX_QUEUE_PER_LCORE 16 -#define MAX_TX_QUEUE_PER_PORT 16 -struct lcore_queue_conf { - unsigned n_rx_port; - unsigned rx_port_list[MAX_RX_QUEUE_PER_LCORE]; -} __rte_cache_aligned; -struct lcore_queue_conf lcore_queue_conf[RTE_MAX_LCORE]; -static struct rte_eth_dev_tx_buffer *tx_buffer[RTE_MAX_ETHPORTS]; -static struct rte_eth_conf port_conf = { - .rxmode = { - .split_hdr_size = 0, - .offloads = DEV_RX_OFFLOAD_JUMBO_FRAME, - .split_hdr_size = 0, - .max_rx_pkt_len = 9500, - }, - .txmode = { - .mq_mode = ETH_MQ_TX_NONE, - }, -}; -struct rte_mempool * l2fwd_pktmbuf_pool = NULL; -/* Per-port statistics struct */ -struct l2fwd_port_statistics { - uint64_t tx; - uint64_t rx; - uint64_t dropped; -} __rte_cache_aligned; -struct l2fwd_port_statistics port_statistics[RTE_MAX_ETHPORTS]; -#define MAX_TIMER_PERIOD 86400 /* 1 day max */ -/* A tsc-based timer responsible for triggering statistics printout */ -static uint64_t timer_period = 10; /* default period is 10 seconds */ -/* Print out statistics on packets dropped */ -static void -print_stats(void) -{ - uint64_t total_packets_dropped, total_packets_tx, total_packets_rx; - unsigned portid; - total_packets_dropped = 0; - total_packets_tx = 0; - total_packets_rx = 0; - const char clr[] = { 27, '[', '2', 'J', '\0' }; - const char topLeft[] = { 27, '[', '1', ';', '1', 'H','\0' }; - /* Clear screen and move to top left */ - printf("%s%s", clr, topLeft); - printf("\nPort statistics ===================================="); - for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) { - /* skip disabled ports */ - if ((l2fwd_enabled_port_mask & (1 << portid)) == 0) - continue; - printf("\nStatistics for port %u ------------------------------" - "\nPackets sent: %24"PRIu64 - "\nPackets received: %20"PRIu64 - "\nPackets dropped: %21"PRIu64, - portid, - port_statistics[portid].tx, - port_statistics[portid].rx, - port_statistics[portid].dropped); - total_packets_dropped += port_statistics[portid].dropped; - total_packets_tx += port_statistics[portid].tx; - total_packets_rx += port_statistics[portid].rx; - } - printf("\nAggregate statistics ===============================" - "\nTotal packets sent: %18"PRIu64 - "\nTotal packets received: %14"PRIu64 - "\nTotal packets dropped: %15"PRIu64, - total_packets_tx, - total_packets_rx, - total_packets_dropped); - printf("\n====================================================\n"); -} -static void -l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs) -{ - unsigned char *buf, *buf_tx; - unsigned int len; - struct ether_hdr *eth; - - unsigned dst_port; - int sent, prach_ctrl = 0; - struct rte_eth_dev_tx_buffer *buffer; - - unsigned char * IQ_ptr; - - ul_packet_t p; - - buf = rte_pktmbuf_mtod(m, unsigned char *); - //DD Debug - //rte_memdump(stdout, "Rx Packet",buf ,34); - eth = rte_pktmbuf_mtod(m, struct ether_hdr *); - len = rte_pktmbuf_data_len(m); - - IQ_ptr = &buf[34]; - if (portid == 0) - { - //destination mac address (RRU MAC) - /*eth->d_addr.addr_bytes[0] = 0x02; - eth->d_addr.addr_bytes[1] = 0x00; - eth->d_addr.addr_bytes[2] = 0x5e; - eth->d_addr.addr_bytes[3] = 0x01; - eth->d_addr.addr_bytes[4] = 0x01; - eth->d_addr.addr_bytes[5] = 0x01;*/ - - eth->d_addr.addr_bytes[0] = buf[6]; - eth->d_addr.addr_bytes[1] = buf[7]; - eth->d_addr.addr_bytes[2] = buf[8]; - eth->d_addr.addr_bytes[3] = buf[9]; - eth->d_addr.addr_bytes[4] = buf[10]; - eth->d_addr.addr_bytes[5] = buf[11]; - - //source mac address (DU MAC) - eth->s_addr.addr_bytes[0] = 0xdd; - eth->s_addr.addr_bytes[1] = 0xdd; - eth->s_addr.addr_bytes[2] = 0xdd; - eth->s_addr.addr_bytes[3] = 0xdd; - eth->s_addr.addr_bytes[4] = 0xdd; - eth->s_addr.addr_bytes[5] = 0xdd; - } - else - { - //destination mac address (RRU MAC) - /*eth->d_addr.addr_bytes[0] = 0x02; - eth->d_addr.addr_bytes[1] = 0x00; - eth->d_addr.addr_bytes[2] = 0x5e; - eth->d_addr.addr_bytes[3] = 0x01; - eth->d_addr.addr_bytes[4] = 0x01; - eth->d_addr.addr_bytes[5] = 0x01;*/ - - eth->d_addr.addr_bytes[0] = buf[6]; - eth->d_addr.addr_bytes[1] = buf[7]; - eth->d_addr.addr_bytes[2] = buf[8]; - eth->d_addr.addr_bytes[3] = buf[9]; - eth->d_addr.addr_bytes[4] = buf[10]; - eth->d_addr.addr_bytes[5] = buf[11]; - //source mac address (DU MAC) - eth->s_addr.addr_bytes[0] = 0xdd; - eth->s_addr.addr_bytes[1] = 0xdd; - eth->s_addr.addr_bytes[2] = 0xdd; - eth->s_addr.addr_bytes[3] = 0xdd; - eth->s_addr.addr_bytes[4] = 0xdd; - eth->s_addr.addr_bytes[5] = 0xde; - - } - dst_port = l2fwd_dst_ports[portid]; - //DD Debug - //printf("dstPort =%d\n", dst_port); - // Handshake Condition - if (buf[18] == 0xAA ) // ORAN handshake msgs. - { - printf("\n Start UP Request Received\n"); - printf("\n====================================================\n"); - - buf[18] = 0xBB;//change to msg2 after receive msg1 - - printf(" Start Up Response Sent\n"); - printf("\n====================================================\n"); - - } - - // Trigger start send DL packets - if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4 && SYMBOL == 0x44 && ANT_NUM == 0x00 && SUBFRAME == 0x00 && dl_start == 0){ - - printf("\nU-Plane Started\n"); - printf("\n====================================================\n"); - - dl_start = 1; - count_symbol = 28; - } - - - if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4) { - int subframe = SUBFRAME >> 4; - int slot = ((SUBFRAME & 0x0f) << 2) | ((SYMBOL >> 6) & 0x03); - p.frame = FRAME; - p.slot = subframe * 2 + slot; - p.symbol = SYMBOL & 0x3f; - p.antenna = ANT_NUM; - memcpy(p.iq, IQ_ptr, 5088); - store_ul(bs, &p); - // if (p.symbol==0) printf("store ul f.sl.sy %d.%d.%d\n", p.frame, p.slot, p.symbol); - } - - // U-PLANE UL PROCESSING - if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4 && dl_start == 1) - { - int a = ANT_NUM & 0x01; - int frame = FRAME; - int subframe = SUBFRAME >> 4; - int slot = ((SUBFRAME & 0x0f) << 2) | ((SYMBOL >> 6) & 0x03); - int symbol = SYMBOL & 0x3f; - int oai_slot; - - int tx_frame = frame; - int tx_subframe = subframe; - int tx_slot = slot; - int tx_symbol = symbol + 10; - - if (tx_symbol > 13) { - tx_symbol -= 14; - tx_slot++; - if (tx_slot == 2) { - tx_slot = 0; - tx_subframe++; - if (tx_subframe == 10) { - tx_subframe = 0; - tx_frame = (tx_frame + 1) & 255; - } - } - } - - // Mask the symbol bits from UL packet received and apply the shift. - SYMBOL = ((SYMBOL & 0b00111111) + 10) % 14; - - ANT_NUM = a; - SUBFRAME = sf; - - if (a == 1) - slot_id_ctrl++; - - // Slot id control for DL - if (slot_id_ctrl > 13) { - SYMBOL = SYMBOL | 0b01000000; - - if (a == 1) { - if (slot_id_ctrl > 27) { - slot_id_ctrl = 0; - sf = sf + 0x10; - - if (sf > 0x90){ - sf = 0; - } - } - } - } - - /* send actual DL data (if available) */ - oai_slot = tx_subframe * 2 + tx_slot; - lock_dl_buffer(bs->buffers, oai_slot); - if (!(bs->buffers->dl_busy[a][oai_slot] & (1 << tx_symbol))) { - //printf("%s: warning, DL underflow (antenna %d sl.symbol %d.%d)\n", __FUNCTION__,a, oai_slot, tx_symbol); - memset(IQ_ptr, 0, 1272 * 4); - } else { - memcpy(IQ_ptr, bs->buffers->dl[a][oai_slot] + tx_symbol * 1272*4, - 1272*4); - } - //printf("DL buffer f sf slot symbol %d %d %d %d (sf %d)\n", tx_frame, tx_subframe, tx_slot, tx_symbol, (int)sf); - bs->buffers->dl_busy[a][oai_slot] &= ~(1 << tx_symbol); - unlock_dl_buffer(bs->buffers, oai_slot); - } - - // U-PLANE PRACH PROCESSING - else if(PAYLOAD_1 == 0x0d && PAYLOAD_2 == 0x28){ - if (ANT_NUM == 0) { - int subframe = SUBFRAME >> 4; - //int slot = ((SUBFRAME & 0x0f) << 2) | ((SYMBOL >> 6) & 0x03); - if (subframe==9) { - //printf("store prach f.sf.sl %d.%d.%d %d\n", FRAME, subframe, slot, subframe * 2 + slot); - store_prach(bs, FRAME, subframe * 2 + 1, IQ_ptr); - } - } - rte_pktmbuf_free(m); - return; - } - - // Send Packets - buffer = tx_buffer[dst_port]; - - sent = rte_eth_tx_buffer(dst_port, 0, buffer, m); - - if (sent) - port_statistics[dst_port].tx += sent; - -} -/* main processing loop */ -static void -l2fwd_main_loop(benetel_t *bs) -{ - struct rte_mbuf *pkts_burst[MAX_PKT_BURST]; - struct rte_mbuf *m; - int sent; - unsigned lcore_id; - uint64_t prev_tsc, diff_tsc, cur_tsc, timer_tsc; - unsigned i, j, portid, nb_rx; - struct lcore_queue_conf *qconf; - const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) / US_PER_S * - BURST_TX_DRAIN_US; - struct rte_eth_dev_tx_buffer *buffer; - prev_tsc = 0; - timer_tsc = 0; - lcore_id = rte_lcore_id(); - qconf = &lcore_queue_conf[lcore_id]; - if (qconf->n_rx_port == 0) { - RTE_LOG(INFO, L2FWD, "lcore %u has nothing to do\n", lcore_id); - return; - } - RTE_LOG(INFO, L2FWD, "entering main loop on lcore %u\n", lcore_id); - for (i = 0; i < qconf->n_rx_port; i++) { - portid = qconf->rx_port_list[i]; - RTE_LOG(INFO, L2FWD, " -- lcoreid=%u portid=%u\n", lcore_id, - portid); - } - while (!force_quit) { - cur_tsc = rte_rdtsc(); - /* - * TX burst queue drain - */ - diff_tsc = cur_tsc - prev_tsc; - if (unlikely(diff_tsc > drain_tsc)) { - for (i = 0; i < qconf->n_rx_port; i++) { - portid = l2fwd_dst_ports[qconf->rx_port_list[i]]; - buffer = tx_buffer[portid]; - sent = rte_eth_tx_buffer_flush(portid, 0, buffer); - if (sent) - port_statistics[portid].tx += sent; - } - /* if timer is enabled */ - if (timer_period > 0) { - /* advance the timer */ - timer_tsc += diff_tsc; - /* if timer has reached its timeout */ - if (unlikely(timer_tsc >= timer_period)) { - /* do this only on master core */ - if (lcore_id == rte_get_master_lcore()) { - print_stats(); - /* reset the timer */ - timer_tsc = 0; - } - } - } - prev_tsc = cur_tsc; - } - /* - * Read packet from RX queues - */ - for (i = 0; i < qconf->n_rx_port; i++) { - portid = qconf->rx_port_list[i]; - nb_rx = rte_eth_rx_burst(portid, 0, - pkts_burst, MAX_PKT_BURST); - port_statistics[portid].rx += nb_rx; - for (j = 0; j < nb_rx; j++) { - m = pkts_burst[j]; - rte_prefetch0(rte_pktmbuf_mtod(m, void *)); - l2fwd_simple_forward(m, portid, bs); - } - } - } -} -static int -l2fwd_launch_one_lcore(void *bs) -{ - l2fwd_main_loop(bs); - return 0; -} -/* display usage */ -static void -l2fwd_usage(const char *prgname) -{ - printf("%s [EAL options] -- -p PORTMASK [-q NQ]\n" - " -p PORTMASK: hexadecimal bitmask of ports to configure\n" - " -q NQ: number of queue (=ports) per lcore (default is 1)\n" - " -T PERIOD: statistics will be refreshed each PERIOD seconds (0 to disable, 10 default, 86400 maximum)\n" - " --[no-]mac-updating: Enable or disable MAC addresses updating (enabled by default)\n" - " When enabled:\n" - " - The source MAC address is replaced by the TX port MAC address\n" - " - The destination MAC address is replaced by 02:00:00:00:00:TX_PORT_ID\n", - prgname); -} -static int -l2fwd_parse_portmask(const char *portmask) -{ - char *end = NULL; - unsigned long pm; - /* parse hexadecimal string */ - pm = strtoul(portmask, &end, 16); - if ((portmask[0] == '\0') || (end == NULL) || (*end != '\0')) - return -1; - if (pm == 0) - return -1; - return pm; -} -static unsigned int -l2fwd_parse_nqueue(const char *q_arg) -{ - char *end = NULL; - unsigned long n; - /* parse hexadecimal string */ - n = strtoul(q_arg, &end, 10); - if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0')) - return 0; - if (n == 0) - return 0; - if (n >= MAX_RX_QUEUE_PER_LCORE) - return 0; - return n; -} -static int -l2fwd_parse_timer_period(const char *q_arg) -{ - char *end = NULL; - int n; - /* parse number string */ - n = strtol(q_arg, &end, 10); - if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0')) - return -1; - if (n >= MAX_TIMER_PERIOD) - return -1; - return n; -} -static const char short_options[] = - "p:" /* portmask */ - "q:" /* number of queues */ - "T:" /* timer period */ - ; -#define CMD_LINE_OPT_MAC_UPDATING "mac-updating" -#define CMD_LINE_OPT_NO_MAC_UPDATING "no-mac-updating" -enum { - /* long options mapped to a short option */ - /* first long only option value must be >= 256, so that we won't - * conflict with short options */ - CMD_LINE_OPT_MIN_NUM = 256, -}; -static const struct option lgopts[] = { - { CMD_LINE_OPT_MAC_UPDATING, no_argument, &mac_updating, 1}, - { CMD_LINE_OPT_NO_MAC_UPDATING, no_argument, &mac_updating, 0}, - {NULL, 0, 0, 0} -}; -/* Parse the argument given in the command line of the application */ -static int -l2fwd_parse_args(int argc, char **argv) -{ - int opt, ret, timer_secs; - char **argvopt; - int option_index; - char *prgname = argv[0]; - argvopt = argv; - while ((opt = getopt_long(argc, argvopt, short_options, - lgopts, &option_index)) != EOF) { - switch (opt) { - /* portmask */ - case 'p': - l2fwd_enabled_port_mask = l2fwd_parse_portmask(optarg); - if (l2fwd_enabled_port_mask == 0) { - printf("invalid portmask\n"); - l2fwd_usage(prgname); - return -1; - } - break; - /* nqueue */ - case 'q': - l2fwd_rx_queue_per_lcore = l2fwd_parse_nqueue(optarg); - if (l2fwd_rx_queue_per_lcore == 0) { - printf("invalid queue number\n"); - l2fwd_usage(prgname); - return -1; - } - break; - /* timer period */ - case 'T': - timer_secs = l2fwd_parse_timer_period(optarg); - if (timer_secs < 0) { - printf("invalid timer period\n"); - l2fwd_usage(prgname); - return -1; - } - timer_period = timer_secs; - break; - /* long options */ - case 0: - break; - case 'proc-type': - break; - case 'socket-mem': - break; - case 'file-prefix': - l2fwd_rx_queue_per_lcore = l2fwd_parse_nqueue(optarg); - if (l2fwd_rx_queue_per_lcore == 0) { - printf("invalid queue number\n"); - l2fwd_usage(prgname); - return -1; - } - break; - /* timer period */ - /* timer period */ - /* timer period */ - default: - l2fwd_usage(prgname); - return -1; - } - } - if (optind >= 0) - argv[optind-1] = prgname; - ret = optind-1; - optind = 1; /* reset getopt lib */ - return ret; -} -/* Check the link status of all ports in up to 9s, and print them finally */ -static void -check_all_ports_link_status(uint32_t port_mask) -{ -#define CHECK_INTERVAL 100 /* 100ms */ -#define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */ - uint16_t portid; - uint8_t count, all_ports_up, print_flag = 0; - struct rte_eth_link link; - printf("\nChecking link status"); - fflush(stdout); - for (count = 0; count <= MAX_CHECK_TIME; count++) { - if (force_quit) - return; - all_ports_up = 1; - RTE_ETH_FOREACH_DEV(portid) { - if (force_quit) - return; - if ((port_mask & (1 << portid)) == 0) - continue; - memset(&link, 0, sizeof(link)); - rte_eth_link_get_nowait(portid, &link); - /* print link status if flag set */ - if (print_flag == 1) { - if (link.link_status) - printf( - "Port%d Link Up. Speed %u Mbps - %s\n", - portid, link.link_speed, - (link.link_duplex == ETH_LINK_FULL_DUPLEX) ? - ("full-duplex") : ("half-duplex\n")); - else - printf("Port %d Link Down\n", portid); - continue; - } - /* clear all_ports_up flag if any link down */ - if (link.link_status == ETH_LINK_DOWN) { - all_ports_up = 0; - break; - } - } - /* after finally printing all link status, get out */ - if (print_flag == 1) - break; - if (all_ports_up == 0) { - printf("."); - fflush(stdout); - rte_delay_ms(CHECK_INTERVAL); - } - /* set the print_flag if all ports up or timeout */ - if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) { - print_flag = 1; - printf("done\n"); - } - } -} -static void -signal_handler(int signum) -{ - if (signum == SIGINT || signum == SIGTERM) { - printf("\n\nSignal %d received, preparing to exit...\n", - signum); - force_quit = true; - } -} -int -dpdk_main(int argc, char **argv, benetel_t *bs) -{ - struct lcore_queue_conf *qconf; - int ret; - uint16_t nb_ports; - uint16_t nb_ports_available = 0; - uint16_t portid, last_port; - unsigned lcore_id, rx_lcore_id; - unsigned nb_ports_in_mask = 0; - unsigned int nb_lcores = 0; - unsigned int nb_mbufs; - /* init EAL */ - ret = rte_eal_init(argc, argv); - if (ret < 0) - rte_exit(EXIT_FAILURE, "Invalid EAL arguments\n"); - argc -= ret; - argv += ret; - force_quit = false; - signal(SIGINT, signal_handler); - signal(SIGTERM, signal_handler); - /* parse application arguments (after the EAL ones) */ - ret = l2fwd_parse_args(argc, argv); - if (ret < 0) - rte_exit(EXIT_FAILURE, "Invalid L2FWD arguments\n"); - printf("MAC updating %s\n", mac_updating ? "enabled" : "disabled"); - /* convert to number of cycles */ - timer_period *= rte_get_timer_hz(); - nb_ports = rte_eth_dev_count_avail(); - if (nb_ports == 0) - rte_exit(EXIT_FAILURE, "No Ethernet ports - bye\n"); - /* check port mask to possible port mask */ - if (l2fwd_enabled_port_mask & ~((1 << nb_ports) - 1)) - rte_exit(EXIT_FAILURE, "Invalid portmask; possible (0x%x)\n", - (1 << nb_ports) - 1); - /* reset l2fwd_dst_ports */ - for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) - l2fwd_dst_ports[portid] = 0; - last_port = 0; - /* - * Each logical core is assigned a dedicated TX queue on each port. - */ - RTE_ETH_FOREACH_DEV(portid) { - /* skip ports that are not enabled */ - if ((l2fwd_enabled_port_mask & (1 << portid)) == 0) - continue; - if (nb_ports_in_mask % 2) { - l2fwd_dst_ports[portid] = last_port; - l2fwd_dst_ports[last_port] = portid; - } - else - last_port = portid; - nb_ports_in_mask++; - } - if (nb_ports_in_mask % 2) { - printf("Notice: odd number of ports in portmask.\n"); - l2fwd_dst_ports[last_port] = last_port; - } - rx_lcore_id = 0; - qconf = NULL; - /* Initialize the port/queue configuration of each logical core */ - RTE_ETH_FOREACH_DEV(portid) { - /* skip ports that are not enabled */ - if ((l2fwd_enabled_port_mask & (1 << portid)) == 0) - continue; - /* get the lcore_id for this port */ - while (rte_lcore_is_enabled(rx_lcore_id) == 0 || - lcore_queue_conf[rx_lcore_id].n_rx_port == - l2fwd_rx_queue_per_lcore) { - rx_lcore_id++; - if (rx_lcore_id >= RTE_MAX_LCORE) - rte_exit(EXIT_FAILURE, "Not enough cores\n"); - } - if (qconf != &lcore_queue_conf[rx_lcore_id]) { - /* Assigned a new logical core in the loop above. */ - qconf = &lcore_queue_conf[rx_lcore_id]; - nb_lcores++; - } - qconf->rx_port_list[qconf->n_rx_port] = portid; - qconf->n_rx_port++; - printf("Lcore %u: RX port %u\n", rx_lcore_id, portid); - } - nb_mbufs = RTE_MAX(nb_ports * (nb_rxd + nb_txd + MAX_PKT_BURST + - nb_lcores * MEMPOOL_CACHE_SIZE), 8192U); - /* create the mbuf pool */ - //DD Debug - //printf ("Proc Type %d \n", rte_eal_process_type()); - l2fwd_pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", nb_mbufs, - MEMPOOL_CACHE_SIZE, 0, 9680, - rte_socket_id()); - if (l2fwd_pktmbuf_pool == NULL) - rte_exit(EXIT_FAILURE, "Cannot init mbuf pool\n"); - /* Initialise each port */ - RTE_ETH_FOREACH_DEV(portid) { - struct rte_eth_rxconf rxq_conf; - struct rte_eth_txconf txq_conf; - struct rte_eth_conf local_port_conf = port_conf; - struct rte_eth_dev_info dev_info; - /* skip ports that are not enabled */ - if ((l2fwd_enabled_port_mask & (1 << portid)) == 0) { - printf("Skipping disabled port %u\n", portid); - continue; - } - nb_ports_available++; - /* init port */ - printf("Initializing port %u... ", portid); - fflush(stdout); - rte_eth_dev_info_get(portid, &dev_info); - if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE) - local_port_conf.txmode.offloads |= - DEV_TX_OFFLOAD_MBUF_FAST_FREE; - ret = rte_eth_dev_configure(portid, 1, 1, &local_port_conf); - if (ret < 0) - rte_exit(EXIT_FAILURE, "Cannot configure device: err=%d, port=%u\n", - ret, portid); - ret = rte_eth_dev_adjust_nb_rx_tx_desc(portid, &nb_rxd, - &nb_txd); - if (ret < 0) - rte_exit(EXIT_FAILURE, - "Cannot adjust number of descriptors: err=%d, port=%u\n", - ret, portid); - rte_eth_macaddr_get(portid,&l2fwd_ports_eth_addr[portid]); - /* init one RX queue */ - fflush(stdout); - rxq_conf = dev_info.default_rxconf; - rxq_conf.offloads = local_port_conf.rxmode.offloads; - ret = rte_eth_rx_queue_setup(portid, 0, nb_rxd, - rte_eth_dev_socket_id(portid), - &rxq_conf, - l2fwd_pktmbuf_pool); - if (ret < 0) - rte_exit(EXIT_FAILURE, "rte_eth_rx_queue_setup:err=%d, port=%u\n", - ret, portid); - /* init one TX queue on each port */ - fflush(stdout); - txq_conf = dev_info.default_txconf; - txq_conf.offloads = local_port_conf.txmode.offloads; - ret = rte_eth_tx_queue_setup(portid, 0, nb_txd, - rte_eth_dev_socket_id(portid), - &txq_conf); - if (ret < 0) - rte_exit(EXIT_FAILURE, "rte_eth_tx_queue_setup:err=%d, port=%u\n", - ret, portid); - /* Initialize TX buffers */ - tx_buffer[portid] = rte_zmalloc_socket("tx_buffer", - RTE_ETH_TX_BUFFER_SIZE(MAX_PKT_BURST), 0, - rte_eth_dev_socket_id(portid)); - if (tx_buffer[portid] == NULL) - rte_exit(EXIT_FAILURE, "Cannot allocate buffer for tx on port %u\n", - portid); - rte_eth_tx_buffer_init(tx_buffer[portid], MAX_PKT_BURST); - ret = rte_eth_tx_buffer_set_err_callback(tx_buffer[portid], - rte_eth_tx_buffer_count_callback, - &port_statistics[portid].dropped); - if (ret < 0) - rte_exit(EXIT_FAILURE, - "Cannot set error callback for tx buffer on port %u\n", - portid); - /* Start device */ - ret = rte_eth_dev_start(portid); - if (ret < 0) - rte_exit(EXIT_FAILURE, "rte_eth_dev_start:err=%d, port=%u\n", - ret, portid); - printf("done: \n"); - rte_eth_promiscuous_enable(portid); - printf("Port %u, MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n\n", - portid, - l2fwd_ports_eth_addr[portid].addr_bytes[0], - l2fwd_ports_eth_addr[portid].addr_bytes[1], - l2fwd_ports_eth_addr[portid].addr_bytes[2], - l2fwd_ports_eth_addr[portid].addr_bytes[3], - l2fwd_ports_eth_addr[portid].addr_bytes[4], - l2fwd_ports_eth_addr[portid].addr_bytes[5]); - /* initialize port stats */ - memset(&port_statistics, 0, sizeof(port_statistics)); - } - if (!nb_ports_available) { - rte_exit(EXIT_FAILURE, - "All available ports are disabled. Please set portmask.\n"); - } - check_all_ports_link_status(l2fwd_enabled_port_mask); - ret = 0; - /* launch per-lcore init on every lcore */ - rte_eal_mp_remote_launch(l2fwd_launch_one_lcore, bs, CALL_MASTER); - RTE_LCORE_FOREACH_SLAVE(lcore_id) { - if (rte_eal_wait_lcore(lcore_id) < 0) { - ret = -1; - break; - } - } - RTE_ETH_FOREACH_DEV(portid) { - if ((l2fwd_enabled_port_mask & (1 << portid)) == 0) - continue; - printf("Closing port %d...", portid); - rte_eth_dev_stop(portid); - rte_eth_dev_close(portid); - printf(" Done\n"); - } - printf("Bye...\n"); - return ret; -} diff --git a/radio/ETHERNET/benetel/5g/low.c b/radio/ETHERNET/benetel/5g/low.c deleted file mode 100644 index b34d69784f..0000000000 --- a/radio/ETHERNET/benetel/5g/low.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#include "low.h" - -#include -#include -#include - -void store_ul(benetel_t *bs, ul_packet_t *ul) -{ -#if 0 -struct timespec t; -static struct timespec old; -clock_gettime(CLOCK_REALTIME, &t); -printf("store_ul %d.%ld (%ld)\n", (int)(t.tv_sec % 60), t.tv_nsec, t.tv_nsec - old.tv_nsec); -old = t; -#endif - - int a = ul->antenna; - - if (ul->slot != bs->next_slot[a] || - ul->symbol != bs->next_symbol[a]) { - printf("%s: error, antenna %d expected frame.sl.symbol %d.%d.%d, got %d.%d.%d\n", - __FUNCTION__, - a, bs->expected_benetel_frame[a], bs->next_slot[a], bs->next_symbol[a], - ul->frame, ul->slot, ul->symbol); - } - - /* fill missing data with 0s */ - while (ul->slot != bs->next_slot[a] || - ul->symbol != bs->next_symbol[a]) { - lock_ul_buffer(bs->buffers, bs->next_slot[a]); - if (bs->buffers->ul_busy[a][bs->next_slot[a]] & (1 << bs->next_symbol[a])) { - printf("%s: warning, antenna %d UL overflow (sl.symbol %d.%d)\n", __FUNCTION__, - a, bs->next_slot[a], bs->next_symbol[a]); - } - - memset(bs->buffers->ul[a][bs->next_slot[a]] + bs->next_symbol[a] * 1272*4, - 0, 1272*4); - bs->buffers->ul_busy[a][bs->next_slot[a]] |= (1 << bs->next_symbol[a]); - signal_ul_buffer(bs->buffers, bs->next_slot[a]); - unlock_ul_buffer(bs->buffers, bs->next_slot[a]); - - bs->next_symbol[a]++; - if (bs->next_symbol[a] == 14) { - bs->next_symbol[a] = 0; - bs->next_slot[a] = (bs->next_slot[a] + 1) % 20; - if (bs->next_slot[a] == 0) { - bs->expected_benetel_frame[a]++; - bs->expected_benetel_frame[a] &= 255; - } - } - } - - lock_ul_buffer(bs->buffers, bs->next_slot[a]); - if (bs->buffers->ul_busy[a][bs->next_slot[a]] & (1 << bs->next_symbol[a])) { - printf("%s: warning, antenna %d UL overflow (sl.symbol %d.%d)\n", __FUNCTION__, - a, bs->next_slot[a], bs->next_symbol[a]); - } - - memcpy(bs->buffers->ul[a][bs->next_slot[a]] + bs->next_symbol[a] * 1272*4, - ul->iq, 1272*4); - bs->buffers->ul_busy[a][bs->next_slot[a]] |= (1 << bs->next_symbol[a]); - signal_ul_buffer(bs->buffers, bs->next_slot[a]); - unlock_ul_buffer(bs->buffers, bs->next_slot[a]); - - bs->next_symbol[a]++; - if (bs->next_symbol[a] == 14) { - bs->next_symbol[a] = 0; - bs->next_slot[a] = (bs->next_slot[a] + 1) % 20; - if (bs->next_slot[a] == 0) { - bs->expected_benetel_frame[a]++; - bs->expected_benetel_frame[a] &= 255; - } - } -} - -void store_prach(benetel_t *bs, int frame, int slot, void *data) -{ - static int last_frame = -1; - static int last_slot = -1; - /* hack: antenna number is always 0, discard second packet with same f/sf */ - //if (frame == last_frame && slot == last_slot) return; - if (frame == last_frame && slot == last_slot) { printf("got f.sl %d.%d twice\n", frame, slot); return; } - last_frame = frame; - last_slot = slot; - - lock_ul_buffer(bs->buffers, slot); - if (bs->buffers->prach_busy[slot]) { - printf("store_prach: fatal: previous prach buffer not processed\n"); - unlock_ul_buffer(bs->buffers, slot); - return; - } - bs->buffers->prach_busy[slot] = 1; - memcpy(bs->buffers->prach[slot], data, 839*4); - signal_ul_buffer(bs->buffers, slot); - unlock_ul_buffer(bs->buffers, slot); - -} - -void *benetel_start_dpdk(char *ifname, shared_buffers *buffers, char *dpdk_main_command_line); - -void *benetel_start(char *ifname, shared_buffers *buffers, char *dpdk_main_command_line) -{ - if (!strcmp(ifname, "dpdk")) - return benetel_start_dpdk(ifname, buffers, dpdk_main_command_line); - printf("benetel: fatal: interface %s not supported, only dpdpk is supported\n", ifname); - exit(1); -} diff --git a/radio/ETHERNET/benetel/5g/low.h b/radio/ETHERNET/benetel/5g/low.h deleted file mode 100644 index 659819296a..0000000000 --- a/radio/ETHERNET/benetel/5g/low.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#ifndef _BENETEL_5G_LOW_H_ -#define _BENETEL_5G_LOW_H_ - -#include "shared_buffers.h" - -typedef struct { - shared_buffers *buffers; - /* [2] is for two antennas */ - int next_slot[2]; - int next_symbol[2]; - int expected_benetel_frame[2]; - char *dpdk_main_command_line; -} benetel_t; - -typedef struct { - int frame; - int slot; - int symbol; - int antenna; - unsigned char iq[5088]; -} ul_packet_t; - -void *benetel_start(char *ifname, shared_buffers *buffers, char *dpdk_main_command_line); - -void store_ul(benetel_t *bs, ul_packet_t *ul); -void store_prach(benetel_t *bs, int frame, int slot, void *data); - -#endif /* _BENETEL_5G_LOW_H_ */ diff --git a/radio/ETHERNET/benetel/5g/low_dpdk.c b/radio/ETHERNET/benetel/5g/low_dpdk.c deleted file mode 100644 index b26df07723..0000000000 --- a/radio/ETHERNET/benetel/5g/low_dpdk.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/* those 2 lines for CPU_SET */ -#define _GNU_SOURCE -#include - -#include -#include -#include -#include - -#include "low.h" - -int dpdk_main(int argc, char **argv, benetel_t *); - -void *dpdk_thread(void *_bs) -{ - benetel_t *bs = _bs; - int n = 0; - char **v = NULL; // = { "softmodem", "-n", "2", "--file-prefix", "pg2", "-l", "6", "--", "-p", "0x1" }; - char *s = bs->dpdk_main_command_line; - char *tok; - - while ((tok = strtok(s, " ")) != NULL) { - n++; - v = realloc(v, n * sizeof(char *)); - if (v == NULL) { - printf("%s: out of memory\n", __FUNCTION__); - exit(1); - } - v[n-1] = tok; - s = NULL; - } - - dpdk_main(n, v, bs); - exit(1); - return 0; -} - -void *benetel_start_dpdk(char *ifname, shared_buffers *buffers, char *dpdk_main_command_line) -{ - benetel_t *bs; - - bs = calloc(1, sizeof(benetel_t)); - if (bs == NULL) { - printf("%s: out of memory\n", __FUNCTION__); - exit(1); - } - - bs->buffers = buffers; - - bs->expected_benetel_frame[0] = 255; - bs->expected_benetel_frame[1] = 255; - - bs->dpdk_main_command_line = dpdk_main_command_line; - - pthread_attr_t attr; - - if (pthread_attr_init(&attr) != 0) { - printf("pthread_attr_init failed\n"); - exit(1); - } - - cpu_set_t cpuset; - CPU_ZERO(&cpuset); - CPU_SET(10,&cpuset); - if (pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t), &cpuset) != 0) { - printf("pthread_attr_setaffinity_np failed\n"); - exit(1); - } - - if (pthread_attr_setschedpolicy(&attr, SCHED_FIFO) != 0) { - printf("pthread_attr_setschedpolicy failed\n"); - exit(1); - } - - struct sched_param params; - params.sched_priority = sched_get_priority_max(SCHED_FIFO); - if (sched_get_priority_max(SCHED_FIFO) == -1) { - printf("sched_get_priority_max failed\n"); - exit(1); - } - if (pthread_attr_setschedparam(&attr, ¶ms) != 0) { - printf("pthread_setschedparam failed\n"); - exit(1); - } - - pthread_t t; - if (pthread_create(&t, &attr, dpdk_thread, bs) != 0) { - printf("%s: thread creation failed\n", __FUNCTION__); - exit(1); - } - - if (pthread_attr_destroy(&attr) != 0) { - printf("pthread_attr_init failed\n"); - exit(1); - } - - return bs; -} diff --git a/radio/ETHERNET/benetel/5g/shared_buffers.c b/radio/ETHERNET/benetel/5g/shared_buffers.c deleted file mode 100644 index a302400eb4..0000000000 --- a/radio/ETHERNET/benetel/5g/shared_buffers.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#include "shared_buffers.h" - -#include -#include -#include - -void init_buffers(shared_buffers *s) -{ - int slot; - - memset(s, 0, sizeof(*s)); - - for (slot = 0; slot < 20; slot++) { - if (pthread_mutex_init(&s->m_dl[slot], NULL) != 0 || - pthread_cond_init(&s->c_dl[slot], NULL) != 0 || - pthread_mutex_init(&s->m_ul[slot], NULL) != 0 || - pthread_cond_init(&s->c_ul[slot], NULL) != 0) { - printf("%s: error initializing mutex/cond\n", __FUNCTION__); - exit(1); - } - } - - /* the gNB's first transmitted DL slot is 6 but the device - * needs to have slots 1, 2 and 3, 4 and 5 ready. Let's pretend - * they are ready. - */ - s->dl_busy[0][1] = 0x3fff; - s->dl_busy[0][2] = 0x3fff; - s->dl_busy[0][3] = 0x3fff; - s->dl_busy[0][4] = 0x3fff; - s->dl_busy[0][5] = 0x3fff; - s->dl_busy[1][1] = 0x3fff; - s->dl_busy[1][2] = 0x3fff; - s->dl_busy[1][3] = 0x3fff; - s->dl_busy[1][4] = 0x3fff; - s->dl_busy[1][5] = 0x3fff; -} - -void lock_dl_buffer(shared_buffers *s, int slot) -{ - if (pthread_mutex_lock(&s->m_dl[slot]) != 0) { - printf("%s: fatal: lock fails\n", __FUNCTION__); - exit(1); - } -} - -void unlock_dl_buffer(shared_buffers *s, int slot) -{ - if (pthread_mutex_unlock(&s->m_dl[slot]) != 0) { - printf("%s: fatal: unlock fails\n", __FUNCTION__); - exit(1); - } -} - -void wait_dl_buffer(shared_buffers *s, int slot) -{ - if (pthread_cond_wait(&s->c_dl[slot], &s->m_dl[slot]) != 0) { - printf("%s: fatal: cond_wait fails\n", __FUNCTION__); - exit(1); - } -} - -void signal_dl_buffer(shared_buffers *s, int slot) -{ - if (pthread_cond_broadcast(&s->c_dl[slot]) != 0) { - printf("%s: fatal: cond_broadcast fails\n", __FUNCTION__); - exit(1); - } -} - -void lock_ul_buffer(shared_buffers *s, int slot) -{ - if (pthread_mutex_lock(&s->m_ul[slot]) != 0) { - printf("%s: fatal: lock fails\n", __FUNCTION__); - printf("%s: fatal: lock fails slot %d\n", __FUNCTION__, slot); - exit(1); - } -} - -void unlock_ul_buffer(shared_buffers *s, int slot) -{ - if (pthread_mutex_unlock(&s->m_ul[slot]) != 0) { - printf("%s: fatal: unlock fails\n", __FUNCTION__); - exit(1); - } -} - -void wait_ul_buffer(shared_buffers *s, int slot) -{ - if (pthread_cond_wait(&s->c_ul[slot], &s->m_ul[slot]) != 0) { - printf("%s: fatal: cond_wait fails\n", __FUNCTION__); - exit(1); - } -} - -void signal_ul_buffer(shared_buffers *s, int slot) -{ - if (pthread_cond_broadcast(&s->c_ul[slot]) != 0) { - printf("%s: fatal: cond_broadcast fails\n", __FUNCTION__); - exit(1); - } -} diff --git a/radio/ETHERNET/benetel/5g/shared_buffers.h b/radio/ETHERNET/benetel/5g/shared_buffers.h deleted file mode 100644 index 9d51b8138d..0000000000 --- a/radio/ETHERNET/benetel/5g/shared_buffers.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#ifndef _BENETEL_5G_SHARED_BUFFERS_H_ -#define _BENETEL_5G_SHARED_BUFFERS_H_ - -#include -#include - -typedef struct { - /* [2] is for two antennas */ - unsigned char dl[2][20][14*1272*4]; - unsigned char ul[2][20][14*1272*4]; - uint16_t dl_busy[2][20]; - uint16_t ul_busy[2][20]; - - pthread_mutex_t m_ul[20]; - pthread_cond_t c_ul[20]; - - pthread_mutex_t m_dl[20]; - pthread_cond_t c_dl[20]; - - unsigned char prach[20][849*4]; - unsigned char prach_busy[20]; - - /* statistics/error counting */ - int ul_overflow; - int dl_underflow; -} shared_buffers; - -void init_buffers(shared_buffers *s); - -void lock_dl_buffer(shared_buffers *s, int slot); -void unlock_dl_buffer(shared_buffers *s, int slot); -void wait_dl_buffer(shared_buffers *s, int slot); -void signal_dl_buffer(shared_buffers *s, int slot); - -void lock_ul_buffer(shared_buffers *s, int slot); -void unlock_ul_buffer(shared_buffers *s, int slot); -void wait_ul_buffer(shared_buffers *s, int slot); -void signal_ul_buffer(shared_buffers *s, int slot); - -#endif /* _BENETEL_5G_SHARED_BUFFERS_H_ */ diff --git a/radio/ETHERNET/benetel/CMakeLists.txt b/radio/ETHERNET/benetel/CMakeLists.txt deleted file mode 100644 index 1a95d1ec2c..0000000000 --- a/radio/ETHERNET/benetel/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -add_boolean_option(OAI_BENETEL4G OFF "Activate OAI's Benetel 4G radio driver" OFF) -if(OAI_BENETEL4G) - add_subdirectory(4g) -endif() - -add_boolean_option(OAI_BENETEL5G OFF "Activate OAI's Benetel 5G radio driver" OFF) -if(OAI_BENETEL5G) - add_subdirectory(5g) -endif() diff --git a/radio/fhi_72/CMakeLists.txt b/radio/fhi_72/CMakeLists.txt index f2161d06a8..fb40852ebb 100644 --- a/radio/fhi_72/CMakeLists.txt +++ b/radio/fhi_72/CMakeLists.txt @@ -17,7 +17,7 @@ add_library(oran_fhlib_5g MODULE ) set(E_VERSION 5.1.6) -set(F_VERSION 6.1.4) +set(F_VERSION 6.1.5) find_package(xran REQUIRED) if(xran_VERSION VERSION_EQUAL E_VERSION) diff --git a/radio/fhi_72/oaioran.c b/radio/fhi_72/oaioran.c index fc9f58a492..37661d7ad1 100644 --- a/radio/fhi_72/oaioran.c +++ b/radio/fhi_72/oaioran.c @@ -259,7 +259,14 @@ static bool is_tdd_ul_symbol(const struct xran_frame_config *frame_conf, int slo * slot is not UL). */ static bool is_tdd_dl_guard_slot(const struct xran_frame_config *frame_conf, int slot) { - return !is_tdd_ul_symbol(frame_conf, slot, XRAN_NUM_OF_SYMBOL_PER_SLOT - 1); + return !is_tdd_ul_symbol(frame_conf, slot, 0); +} + +/** @brief Check if current slot is UL or guard/mixed without UL (i.e., current + * slot is not UL). */ +static bool is_tdd_ul_guard_slot(const struct xran_frame_config *frame_conf, int slot) +{ + return is_tdd_ul_symbol(frame_conf, slot, XRAN_NUM_OF_SYMBOL_PER_SLOT - 1); } /** @details Read PRACH and PUSCH data from xran buffers. If @@ -337,7 +344,7 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot) start_ptr = rx_data + (slot_size * slot_offset_rxdata); const struct xran_frame_config *frame_conf = &get_xran_fh_config(ant_id / nb_rx_per_ru)->frame_conf; // skip processing this slot is TX (no RX in this slot) - if (is_tdd_dl_guard_slot(frame_conf, *slot)) + if (!is_tdd_ul_guard_slot(frame_conf, *slot)) continue; // This loop would better be more inner to avoid confusion and maybe also errors. for (int32_t sym_idx = 0; sym_idx < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_idx++) { @@ -484,12 +491,70 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp) int nPRBs = fh_cfg->nDLRBs; int fftsize = 1 << fh_cfg->ru_conf.fftSize; int nb_tx_per_ru = ru->nb_tx / fh_init->xran_ports; + int nb_rx_per_ru = ru->nb_rx / fh_init->xran_ports; + + // Handle CP UL packet here instead of at xran_fh_rx_read_slot() as oran_fh_if4p5_south_in() lags behind + // oran_fh_if4p5_south_out() (which is invoked at the right time slot) by 4 slots. + // Need to use --continuous-tx so that this routine will be triggered in RX slot. + for (uint16_t cc_id = 0; cc_id < 1 /*nSectorNum*/; cc_id++) { // OAI does not support multiple CC yet. + for (uint8_t ant_id = 0; ant_id < ru->nb_rx; ant_id++) { + int first = 1; // The first UL symbol + const struct xran_frame_config *frame_conf = &get_xran_fh_config(ant_id / nb_rx_per_ru)->frame_conf; + // skip processing this slot is TX (no RX in this slot) + if (!is_tdd_ul_guard_slot(frame_conf, slot)) { + continue; + } + // This loop would better be more inner to avoid confusion and maybe also errors. + for (int32_t sym_idx = 0; sym_idx < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_idx++) { + /* the callback is for mixed and UL slots. In mixed, we have to + * skip DL and guard symbols. */ + if (!is_tdd_ul_symbol(frame_conf, slot, sym_idx)) { + continue; + } + oran_buf_list_t *bufs = get_xran_buffers(ant_id / nb_rx_per_ru); + uint8_t *pPrbMapData = bufs->dstcp[ant_id % nb_rx_per_ru][tti % XRAN_N_FE_BUF_LEN].pBuffers->pData; + struct xran_prb_map *pPrbMap = (struct xran_prb_map *)pPrbMapData; + + struct xran_prb_elm *pRbElm = &pPrbMap->prbMap[0]; + + struct xran_prb_map *pRbMap = pPrbMap; + uint32_t idxElm = 0; + + LOG_D(HW, "pRbMap->nPrbElm %d\n", pRbMap->nPrbElm); + for (idxElm = 0; idxElm < pRbMap->nPrbElm; idxElm++) { + LOG_D(HW, "prbMap[%d] : PRBstart %d nPRBs %d\n", idxElm, pRbMap->prbMap[idxElm].nRBStart, pRbMap->prbMap[idxElm].nRBSize); + pRbElm = &pRbMap->prbMap[idxElm]; + if (first) { + // ant_id / no of antenna per beam gives the beam_nb + pRbElm->nBeamIndex = + ru->beam_id[ant_id / (ru->nb_rx / ru->num_beams_period)][slot * XRAN_NUM_OF_SYMBOL_PER_SLOT + sym_idx]; + // In phy-f-1.0/fhi_lib/lib/api/xran_pkt_cp.h, beamId:15 is of 15bit. -1 set extension bit ef:1 to 1 mistakenly. + if (pRbElm->nBeamIndex == -1) { + pRbElm->nBeamIndex = 0; + } else { + first = 0; + } + } + } + } + } + } for (uint16_t cc_id = 0; cc_id < 1 /*nSectorNum*/; cc_id++) { // OAI does not support multiple CC yet. for (uint8_t ant_id = 0; ant_id < ru->nb_tx; ant_id++) { oran_buf_list_t *bufs = get_xran_buffers(ant_id / nb_tx_per_ru); + const struct xran_frame_config *frame_conf = &get_xran_fh_config(ant_id / nb_tx_per_ru)->frame_conf; + // skip processing this slot is TX (no TX in this slot) + if (!is_tdd_dl_guard_slot(frame_conf, slot)) { + continue; + } // This loop would better be more inner to avoid confusion and maybe also errors. for (int32_t sym_idx = 0; sym_idx < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_idx++) { + /* the callback is for mixed and UL slots. In mixed, we have to + * skip UL and guard symbols. */ + if (is_tdd_ul_symbol(frame_conf, slot, sym_idx)) { + continue; + } uint8_t *pData = bufs->src[ant_id % nb_tx_per_ru][tti % XRAN_N_FE_BUF_LEN].pBuffers[sym_idx % XRAN_NUM_OF_SYMBOL_PER_SLOT].pData; uint8_t *pPrbMapData = bufs->srccp[ant_id % nb_tx_per_ru][tti % XRAN_N_FE_BUF_LEN].pBuffers->pData; @@ -512,6 +577,14 @@ int xran_fh_tx_send_slot(ru_info_t *ru, int frame, int slot, uint64_t timestamp) for (idxElm = 0; idxElm < pRbMap->nPrbElm; idxElm++) { struct xran_section_desc *p_sec_desc = NULL; p_prbMapElm = &pRbMap->prbMap[idxElm]; + if (sym_idx == 0) { + // ant_id / no of antenna per beam gives the beam_nb + p_prbMapElm->nBeamIndex = ru->beam_id[ant_id / (ru->nb_tx / ru->num_beams_period)][slot * XRAN_NUM_OF_SYMBOL_PER_SLOT]; + // In phy-f-1.0/fhi_lib/lib/api/xran_pkt_cp.h, beamId:15 is of 15bit. -1 set extension bit ef:1 to 1 mistakenly. + if (p_prbMapElm->nBeamIndex == -1) + p_prbMapElm->nBeamIndex = 0; + } + // assumes one fragment per symbol #ifdef E_RELEASE p_sec_desc = p_prbMapElm->p_sec_desc[sym_id][0]; diff --git a/radio/fhi_72/oran-config.c b/radio/fhi_72/oran-config.c index 89c1838fa3..684d44e7cf 100644 --- a/radio/fhi_72/oran-config.c +++ b/radio/fhi_72/oran-config.c @@ -918,7 +918,7 @@ static bool set_fh_config(void *mplane_api, int ru_idx, int num_rus, enum xran_c fh_config->dpdk_port = ru_idx; // DPDK port number used for FH fh_config->sector_id = 0; // Band sector ID for FH; not used in xran fh_config->nCC = 1; // number of Component carriers supported on FH; M-plane info - fh_config->neAxc = RTE_MAX(oai0->num_distributed_ru * oai0->tx_num_channels / num_rus, oai0->num_distributed_ru * oai0->rx_num_channels / num_rus); // number of eAxc supported on one CC = max(PDSCH, PUSCH) + fh_config->neAxc = RTE_MAX(oai0->tx_num_channels / num_rus, oai0->rx_num_channels / num_rus); // number of eAxc supported on one CC = max(PDSCH, PUSCH) fh_config->neAxcUl = 0; // number of eAxc supported on one CC for UL direction = PUSCH; used only if XRAN_CATEGORY_B fh_config->nAntElmTRx = 0; // number of antenna elements for TX and RX = SRS; used only if XRAN_CATEGORY_B fh_config->nDLFftSize = 0; // DL FFT size; not used in xran diff --git a/radio/fhi_72/oran_isolate.c b/radio/fhi_72/oran_isolate.c index 3bdbe1df12..48e95e7344 100644 --- a/radio/fhi_72/oran_isolate.c +++ b/radio/fhi_72/oran_isolate.c @@ -214,7 +214,10 @@ void oran_fh_if4p5_south_in(RU_t *ru, int *frame, int *slot) { ru_info_t ru_info; ru_info.nb_rx = ru->nb_rx * ru->num_beams_period; + ru_info.nb_tx = ru->nb_tx * ru->num_beams_period; ru_info.rxdataF = ru->common.rxdataF; + ru_info.beam_id = ru->common.beam_id; + ru_info.num_beams_period = ru->num_beams_period; ru_info.prach_buf = ru->prach_rxsigF[0]; // index: [prach_oca][ant_id] RU_proc_t *proc = &ru->proc; @@ -267,8 +270,12 @@ void oran_fh_if4p5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp) { start_meas(&ru->tx_fhaul); ru_info_t ru_info; + ru_info.nb_rx = ru->nb_rx * ru->num_beams_period; ru_info.nb_tx = ru->nb_tx * ru->num_beams_period; ru_info.txdataF_BF = ru->common.txdataF_BF; + ru_info.beam_id = ru->common.beam_id; + ru_info.num_beams_period = ru->num_beams_period; + // printf("south_out:\tframe=%d\tslot=%d\ttimestamp=%ld\n",frame,slot,timestamp); int ret = xran_fh_tx_send_slot(&ru_info, frame, slot, timestamp); diff --git a/radio/fhi_72/oran_isolate.h b/radio/fhi_72/oran_isolate.h index 174c1399a6..7dd61ad739 100644 --- a/radio/fhi_72/oran_isolate.h +++ b/radio/fhi_72/oran_isolate.h @@ -41,6 +41,14 @@ typedef struct ru_info_s { int nb_tx; int32_t **txdataF_BF; + /// \brief Anaglogue beam ID for each OFDM symbol (used when beamforming not done in RU) + /// - first index: concurrent beam + /// - second index: beam_id [0.. symbols_per_frame] + int32_t **beam_id; + + /// number of concurrent analog beams in period + int num_beams_period; + // Needed for Prach int16_t **prach_buf; } ru_info_t; diff --git a/tests/nr-cuup/nr-cuup-load-test.c b/tests/nr-cuup/nr-cuup-load-test.c index 0c417ca5aa..533b119c9e 100644 --- a/tests/nr-cuup/nr-cuup-load-test.c +++ b/tests/nr-cuup/nr-cuup-load-test.c @@ -165,7 +165,6 @@ static struct ue_stat { static bool recv_ng(protocol_ctxt_t *ctxt, const ue_id_t ue_id, const srb_flag_t flag, - const rb_id_t rb, const mui_t mui, const confirm_t confirm, const sdu_size_t size,