diff --git a/CMakeLists.txt b/CMakeLists.txt index d0b9f17a02..b8a1b3a082 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,7 @@ # * contact@openairinterface.org # */ -cmake_minimum_required (VERSION 3.16) +cmake_minimum_required (VERSION 3.19) project (OpenAirInterface LANGUAGES C CXX) set(CMAKE_CXX_STANDARD 17) set(OAI_VERSION 2.4.0) @@ -441,6 +441,7 @@ add_library(ngap ${NGAP_DIR}/ngap_gNB_overload.c ${NGAP_DIR}/ngap_gNB_trace.c ${NGAP_DIR}/ngap_gNB_ue_context.c + ${NGAP_DIR}/ngap_gNB_NRPPa_transport_procedures.c ) target_link_libraries(ngap PUBLIC asn1_ngap) target_link_libraries(ngap PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs) @@ -1308,6 +1309,8 @@ set (GNB_APP_SRC ${OPENAIR2_DIR}/GNB_APP/gnb_app.c ${OPENAIR2_DIR}/E1AP/e1ap_setup.c ${OPENAIR2_DIR}/GNB_APP/gnb_config.c + ${OPENAIR2_DIR}/GNB_APP/gnb_config_common.c + ${OPENAIR2_DIR}/GNB_APP/gnb_config_ng.c ) set (MCE_APP_SRC @@ -2012,11 +2015,9 @@ target_link_libraries(nr_pbchsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) add_executable(nr_psbchsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/psbchsim.c ${NFAPI_USER_DIR}/nfapi.c - ${NFAPI_USER_DIR}/gnb_ind_vars.c - ${PHY_INTERFACE_DIR}/queue_t.c ) target_link_libraries(nr_psbchsim PRIVATE - -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_UE_NR MAC_NR_COMMON CONFIG_LIB L2_NR -Wl,--end-group + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_UE_NR MAC_NR_COMMON CONFIG_LIB -Wl,--end-group m pthread ${T_LIB} ITTI dl physim_common softmodem_common ) target_link_libraries(nr_psbchsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) @@ -2035,7 +2036,7 @@ add_executable(nr_dlsim ${PHY_INTERFACE_DIR}/queue_t.c ) target_link_libraries(nr_dlsim PRIVATE - -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_UE_NR MAC_NR_COMMON nr_rrc CONFIG_LIB L2_NR x2ap SECURITY ngap -Wl,--end-group + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_UE_NR MAC_NR_COMMON CONFIG_LIB L2_NR -Wl,--end-group m pthread ${T_LIB} ITTI dl nr_ue_phy_meas physim_common softmodem_common ) @@ -2049,7 +2050,6 @@ target_link_libraries(nr_prachsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) add_executable(nr_ulschsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulschsim.c - ${PHY_INTERFACE_DIR}/queue_t.c ) target_link_libraries(nr_ulschsim PRIVATE -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group @@ -2065,7 +2065,7 @@ add_executable(nr_ulsim ) target_link_libraries(nr_ulsim PRIVATE - -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_UE_NR MAC_NR_COMMON nr_rrc CONFIG_LIB L2_NR x2ap SECURITY ngap -Wl,--end-group + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_UE_NR MAC_NR_COMMON CONFIG_LIB L2_NR -Wl,--end-group m pthread ${T_LIB} ITTI dl nr_ue_phy_meas physim_common softmodem_common ) target_link_libraries(nr_ulsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) @@ -2073,8 +2073,6 @@ target_link_libraries(nr_ulsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) add_executable(nr_srssim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/srssim.c ${NFAPI_USER_DIR}/nfapi.c - ${NFAPI_USER_DIR}/gnb_ind_vars.c - ${PHY_INTERFACE_DIR}/queue_t.c ) target_link_libraries(nr_srssim PRIVATE diff --git a/README.md b/README.md index 17e275f240..aba30a855b 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Supported OS Ubuntu 22 Supported OS Ubuntu 24 Supported OS RHEL9 - Supported OS Fedora 41 + Supported OS Fedora 43

diff --git a/ci-scripts/Jenkinsfile-GitLab-Container b/ci-scripts/Jenkinsfile-GitLab-Container index e94f386e2e..85b6f18c18 100644 --- a/ci-scripts/Jenkinsfile-GitLab-Container +++ b/ci-scripts/Jenkinsfile-GitLab-Container @@ -795,6 +795,29 @@ pipeline { } } } + stage ("SA-AERIAL-OAIUE-CN5G") { + when { expression {do5Gtest || do5GUeTest} } + steps { + script { + triggerSlaveJob ('RAN-SA-AERIAL-OAIUE-CN5G', 'SA-AERIAL-OAIUE-CN5G') + } + } + post { + always { + script { + // Using a unique variable name for each test stage to avoid overwriting on a global variable + // due to parallel-time concurrency + saAERIALOAIUEStatus = finalizeSlaveJob('RAN-SA-AERIAL-OAIUE-CN5G') + } + } + failure { + script { + currentBuild.result = 'FAILURE' + failingStages += saAERIALOAIUEStatus + } + } + } + } stage ("SA-OAIUE-CN5G") { when { expression {do5Gtest || do5GUeTest} } steps { diff --git a/ci-scripts/ci_infra.yaml b/ci-scripts/ci_infra.yaml index 837f1edb82..00da44ed77 100644 --- a/ci-scripts/ci_infra.yaml +++ b/ci-scripts/ci_infra.yaml @@ -101,6 +101,14 @@ oc-cn5g-20897-aerial: Undeploy: "! scripts/oc-cn5g-undeploy.sh /opt/oai-cn5g-fed-develop-2025-jan oaicicd-core-for-nvidia-aerial" LogCollect: "! scripts/oc-cn5g-logcollect.sh /opt/oai-cn5g-fed-develop-2025-jan oaicicd-core-for-nvidia-aerial %%log_dir%%" +oc-cn5g-00104: + Host: gracehopper1-oai + NetworkScript: echo "inet 172.21.6.105" + RunIperf3Server: False + Deploy: "! scripts/oc-cn5g-deploy.sh /opt/oai-cn5g-fed-develop-00104 oaicicd-core-for-nvidia-aerial" + Undeploy: "! scripts/oc-cn5g-undeploy.sh /opt/oai-cn5g-fed-develop-00104 oaicicd-core-for-nvidia-aerial" + LogCollect: "! scripts/oc-cn5g-logcollect.sh /opt/oai-cn5g-fed-develop-00104 oaicicd-core-for-nvidia-aerial %%log_dir%%" + matix-cn5g: Host: matix NetworkScript: docker exec prod-trf-gen ip a show dev eth0 @@ -300,6 +308,14 @@ oai_ue_caracal: IF: oaitun_ue1 MTU: 1500 +oai_ue_jetson2: + Host: jetson2-oai + AttachScript: 'docker start oai-nr-ue' + DetachScript: 'docker stop oai-nr-ue' + NetworkScript: ip a show dev oaitun_ue1 + IF: oaitun_ue1 + MTU: 1500 + lte_oai_ue_carabe: Host: carabe NetworkScript: docker exec lte-b200-ue-fdd-10Mhz-tm1 ip a show dev oaitun_ue1 diff --git a/ci-scripts/conf_files/gnb-vnf.sa.band78.78prb.aerial.conf b/ci-scripts/conf_files/gnb-vnf.sa.band78.78prb.aerial.conf new file mode 100644 index 0000000000..12c0aba35c --- /dev/null +++ b/ci-scripts/conf_files/gnb-vnf.sa.band78.78prb.aerial.conf @@ -0,0 +1,226 @@ +Active_gNBs = ( "gNB-OAI"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +nfapi = "AERIAL"; + +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 = 04; mnc_length = 2; snssaiList = ({sst = 1;});}); + + nr_cellid = 12345678L; + + ////////// Physical parameters: + + pdsch_AntennaPorts_XP = 2; + pdsch_AntennaPorts_N1 = 2; + pusch_AntennaPorts = 2; + do_CSIRS = 0; + do_SRS = 0; + min_rxtxtime = 6; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # center frequency = 3350.01 MHz + # selected SSB frequency = 3349.92 MHz + absoluteFrequencySSB = 623328; + dl_frequencyBand = 78; + # frequency point A = 3300.87 MHz + dl_absoluteFrequencyPointA = 622398; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 78; + #initialDownlinkBWP + #genericParameters + # this is RBstart=0,L=162 (275*(275-L+1))+(274-RBstart)) + initialDLBWPlocationAndBandwidth = 21175; + # +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 78; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 21175; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 148;# testMAC 158; OAI gNB 98 +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 12; + 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 = 15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + + 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; #5; + nrofDownlinkSlots = 6; #3; + nrofDownlinkSymbols = 10; #6; + nrofUplinkSlots = 3; #1; + nrofUplinkSymbols = 0; + + 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.103"; }); + + + NETWORK_INTERFACES : + { + GNB_IPV4_ADDRESS_FOR_NG_AMF = "172.21.16.53"; + GNB_IPV4_ADDRESS_FOR_NGU = "172.21.16.53"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + } +); + +MACRLCs = ( +{ + num_cc = 1; + remote_s_address = "127.0.0.1"; // pnf addr [!] + local_s_address = "127.0.0.2"; // vnf addr + local_s_portc = 50001; // vnf p5 port + remote_s_portc = 50000; // pnf p5 port [!] + local_s_portd = 50011; // vnf p7 port [!] + remote_s_portd = 50010; // pnf p7 port [!] + tr_s_preference = "aerial"; + tr_n_preference = "local_RRC"; + pusch_TargetSNRx10 = 180; # 150; + pucch_TargetSNRx10 = 180; #200; + ulsch_max_frame_inactivity = 10; + dl_max_mcs = 28; + ul_max_mcs = 28; +} +); + + +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/scripts/set-wnc-bandwidth.sh b/ci-scripts/scripts/set-wnc-bandwidth.sh new file mode 100644 index 0000000000..c52f30e388 --- /dev/null +++ b/ci-scripts/scripts/set-wnc-bandwidth.sh @@ -0,0 +1,93 @@ +#!/bin/bash + +if [ -z "$1" ]; then + echo "Usage: $0 [reboot]" + exit 1 +fi + +BANDWIDTH="$1" +DO_REBOOT="$2" +RU_IP="10.10.0.115" +HOST="root@$RU_IP" +LOGFILE="/tmp/radio_config_$(date +%Y%m%d_%H%M%S).log" + +echo "=== Starting at $(date) ===" | tee "$LOGFILE" +echo "Target bandwidth: $BANDWIDTH" | tee -a "$LOGFILE" +echo "Reboot before configuration: ${DO_REBOOT:-no}" | tee -a "$LOGFILE" + +if [ "$DO_REBOOT" == "reboot" ]; then + echo "=== Rebooting RU ($RU_IP) ... ===" | tee -a "$LOGFILE" + + expect < /dev/null 2>&1 +set timeout 10 +spawn ssh -tt $HOST + +expect "#" +send "reboot\r" +expect "Continue?" +send "Y\r" +# We expect disconnect now +expect eof +EOF + + echo "→ Waiting for $RU_IP SSH to go down..." | tee -a "$LOGFILE" + sleep 10 + + echo "→ Waiting for $RU_IP SSH port 22 to be open..." | tee -a "$LOGFILE" + while ! nc -zv $RU_IP 22 >/dev/null 2>&1; do + echo "SSH port 22 not open, waiting 5 seconds..." | tee -a "$LOGFILE" + sleep 5 + done + echo "✓ SSH port 22 is open on $RU_IP" | tee -a "$LOGFILE" +fi + +echo "=== Applying bandwidth configuration ===" | tee -a "$LOGFILE" + +expect < /dev/null 2>&1 +set timeout 10 +spawn ssh -tt $HOST + +expect "#" +send "radio disable\r" + +expect "#" +send "config\r" + +expect "(config)#" +send "radio 1\r" + +expect "(conf-rf 1)#" +send "bandwidth ${BANDWIDTH}\r" + +expect "(conf-rf 1)#" +send "exit\r" + +expect "(config)#" +send "exit\r" + +expect "#" +send "radio enable\r" + +expect "#" +send "show running-config\r" + +expect "#" +send "exit\r" +EOF + +echo "=== Checking bandwidth in running-config ===" | tee -a "$LOGFILE" + +FOUND_BW=$(grep -E "bandwidth[[:space:]]+[0-9]+" "$LOGFILE" \ + | tail -n 1 \ + | awk '{print $2}' \ + | tr -d '\r[:space:]') + +if [ "$FOUND_BW" -eq "$BANDWIDTH" ]; then + echo "✓ SUCCESS: Bandwidth correctly set to $FOUND_BW" | tee -a "$LOGFILE" + rm "$LOGFILE" + exit 0 +else + echo "✖ ERROR: Expected bandwidth $BANDWIDTH but found: $FOUND_BW" | tee -a "$LOGFILE" + exit 1 +fi + diff --git a/ci-scripts/xml_files/container_sa_aerial_quectel.xml b/ci-scripts/xml_files/container_sa_aerial_quectel.xml index b5de982e5a..e7e5ebd2dd 100644 --- a/ci-scripts/xml_files/container_sa_aerial_quectel.xml +++ b/ci-scripts/xml_files/container_sa_aerial_quectel.xml @@ -33,6 +33,15 @@ arm_ + + Custom_Script + true + Configure 100 MHz bandwidth on WNC RU + gracehopper1-oai + + 100 + + Detach_UE true diff --git a/ci-scripts/xml_files/container_sa_aerial_quectel_ul_heavy.xml b/ci-scripts/xml_files/container_sa_aerial_quectel_ul_heavy.xml index 9d826d2261..65a34c3e4e 100644 --- a/ci-scripts/xml_files/container_sa_aerial_quectel_ul_heavy.xml +++ b/ci-scripts/xml_files/container_sa_aerial_quectel_ul_heavy.xml @@ -33,6 +33,15 @@ arm_ + + Custom_Script + true + Configure 100 MHz bandwidth on WNC RU + gracehopper1-oai + + 100 + + Detach_UE true diff --git a/ci-scripts/xml_files/container_sa_b200_nrue_jetson.xml b/ci-scripts/xml_files/container_sa_b200_nrue_jetson.xml new file mode 100644 index 0000000000..610aa306d5 --- /dev/null +++ b/ci-scripts/xml_files/container_sa_b200_nrue_jetson.xml @@ -0,0 +1,212 @@ + + + JETSON-5G-NRUE + 30 MHz TDD SA JETSON + tasks + + DeployCoreNetwork + Initialize 5G Core + oc-cn5g-00104 + + + + Pull_Local_Registry + Pull Images from Local Registry + jetson2-oai + oai-nr-ue + armv8_ + + + + Pull_Local_Registry + Pull Images from Local Registry + gracehopper1-oai + oai-gnb-aerial + arm_ + + + + Create_Workspace + Create new Workspace + jetson2-oai + + + + Create_Workspace + Create new Workspace + gracehopper1-oai + + + + Custom_Script + Configure 30 MHz bandwidth on WNC RU + gracehopper1-oai + + 30 + + + + Deploy_Object + Deploy PNF/Nvidia CUBB in a container + gracehopper1-oai + ci-scripts/yaml_files/sa_gnb_aerial_30MHz + nv-cubb + + + + Deploy_Object + Deploy VNF in a container + gracehopper1-oai + ci-scripts/yaml_files/sa_gnb_aerial_30MHz + oai-gnb-aerial + + + + Deploy_Object + Deploy nrUE (TDD/Band78/40MHz/N310) in a container + ci-scripts/yaml_files/sa_b200_jetson_nrue + jetson2-oai + 3 + + + + Attach_UE + Attach OAIUE + oai_ue_jetson2 + + + + Custom_Command + Configure IP route + jetson2-oai + sudo ip route add 172.21.6.105 via 13.1.1.100 dev oaitun_ue1 + + + + Ping + Ping: 20pings in 20sec + oai_ue_jetson2 + oc-cn5g-00104 + -c 20 + 1 + 25 + + + + Iperf + iperf (UL/10Mbps/UDP)(30 sec) + -u -b 10M -t 30 -i 1 + oai_ue_jetson2 + oc-cn5g-00104 + 25 + 80 + + + + Iperf + iperf (DL/10Mbps/UDP)(30 sec) + -u -b 10M -t 30 -i 1 -R + oai_ue_jetson2 + oc-cn5g-00104 + 25 + 80 + + + + Iperf + iperf (UL/30Mbps/UDP)(30 sec) + true + -u -b 30M -t 30 -i 1 + oai_ue_jetson2 + oc-cn5g-00104 + 25 + 80 + + + + Iperf + iperf (DL/30Mbps/UDP)(30 sec) + true + -u -b 30M -t 30 -i 1 -R + oai_ue_jetson2 + oc-cn5g-00104 + 25 + 80 + + + + Undeploy_Object + true + Undeploy nr UE + jetson2-oai + ci-scripts/yaml_files/sa_b200_jetson_nrue + + oai-nr-ue + + + + + Undeploy_Object + true + Undeploy gNB + gracehopper1-oai + ci-scripts/yaml_files/sa_gnb_aerial_30MHz + + oai-gnb-aerial=RetxCheck=20,100,100,100 oai-gnb-aerial=EndsWithBye + + + + + Custom_Script + true + Configure 100 MHz bandwidth on WNC RU + gracehopper1-oai + + 100 + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + gracehopper1-oai + oai-gnb-aerial + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + jetson2-oai + oai-nr-ue + + + + UndeployCoreNetwork + true + Terminate 5G Core + oc-cn5g-00104 + + + diff --git a/ci-scripts/yaml_files/sa_b200_jetson_nrue/docker-compose.yml b/ci-scripts/yaml_files/sa_b200_jetson_nrue/docker-compose.yml new file mode 100644 index 0000000000..0a35a3caaa --- /dev/null +++ b/ci-scripts/yaml_files/sa_b200_jetson_nrue/docker-compose.yml @@ -0,0 +1,27 @@ +services: + oai-nr-ue: + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${TAG:-develop} + network_mode: host + container_name: oai-nr-ue + cap_drop: + - ALL + cap_add: + - NET_ADMIN # for interface bringup + - NET_RAW # for ping + - SYS_NICE # for performance + - IPC_LOCK # for memory locking + devices: + - /dev/net/tun:/dev/net/tun + - /dev/bus/usb/:/dev/bus/usb/ + environment: + TZ: Europe/Paris + USE_B2XX: 'yes' + USE_ADDITIONAL_OPTIONS: --usrp-args type=b200 -C 3350010000 -r 78 --numerology 1 --band 78 --ssb 345 --ue-fo-compensation --uicc0.imsi 001040000000001 --uicc0.pdu_sessions.[0].dnn oai.ipv4 -A 60 --thread-pool 5,6,7,8,9 --ue-txgain 15 --ue-rxgain 90 + cpuset: "3-11" + volumes: + - ../../conf_files/ue.sa.conf:/opt/oai-nr-ue/etc/nr-ue.conf + healthcheck: + test: /bin/bash -c "pgrep nr-uesoftmodem" + interval: 10s + timeout: 5s + retries: 5 diff --git a/ci-scripts/yaml_files/sa_gnb_aerial/docker-compose-ue.yaml b/ci-scripts/yaml_files/sa_gnb_aerial/docker-compose-ue.yaml new file mode 100644 index 0000000000..15f2f177f4 --- /dev/null +++ b/ci-scripts/yaml_files/sa_gnb_aerial/docker-compose-ue.yaml @@ -0,0 +1,61 @@ +services: + oai-nr-ue: + image: ${REGISTRY-oaisoftwarealliance/}${NRUE_IMG:-oai-nr-ue}:${UE_TAG:-${TAG:-develop}} + logging: + options: + max-file: "1" + network_mode: host + container_name: oai-nr-ue + privileged: true + cpuset: 4,6,8,10,12,14,16,18,20,22,24,26,28 + cap_drop: + - ALL + cap_add: + - NET_ADMIN # for interface bringup + - NET_RAW # for ping + - SYS_NICE # for performance + - IPC_LOCK # for memory locking + - SYS_PTRACE # for debugging + devices: + - /dev/net/tun:/dev/net/tun + ulimits: + core: -1 # for core dumps + #entrypoint: /bin/bash -c "sleep infinity" + environment: + TZ: UTC + #DISPLAY: $DISPLAY #Uncomment for GUI + USE_ADDITIONAL_OPTIONS: | + --thread-pool 4,6,8,10,12,14,16,18,20,22,24,26 + --usrp-args type=x4xx,addr=192.168.10.2,clock_source=external,time_source=external + --ssb 1478 -r 273 --numerology 1 --band 78 -C 3750000000 + --num-dl-actors 20 + --ue-nb-ant-tx 1 + --ue-nb-ant-rx 1 + --ue-rxgain 25 + --ue-txgain 13 + --uicc0.imsi 001010000000003 + --ue-fo-compensation -A 90 + --usrp-tx-thread-config 1 + --log_config.global_log_options level,nocolor,utc_time + # Unused options: + # --T_stdout 2 + # --imscope + # --ssb 1478 -r 273 --numerology 1 --band 78 -C 3750000000 + # --usrp-tx-thread-config 1 + # --log_config.mac_log_level debug + # --log_config.nr_mac_log_level debug + # --usrp-tx-thread-config 1 -d + # --ssb 194 -r 51 --numerology 1 --band 78 -C 3750000000 #20MHz + # --ssb 236 -r 106 --numerology 1 --band 78 -C 3750000000 #40MHz + volumes: + - ../../conf_files/ue.sa.conf:/opt/oai-nr-ue/etc/nr-ue.conf + # UL throughput is worse with 256-qam table + - ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/uecap_ports1.xml:/opt/oai-nr-ue/uecap_ports1.xml + #For GUI + - ${HOME}/.Xauthority:/root/.Xauthority:rw + - /tmp/.X11-unix:/tmp/.X11-unix + healthcheck: + test: /bin/bash -c "pgrep nr-uesoftmodem" + interval: 10s + timeout: 5s + retries: 5 diff --git a/ci-scripts/yaml_files/sa_gnb_aerial_30MHz/aerial_l1_entrypoint.sh b/ci-scripts/yaml_files/sa_gnb_aerial_30MHz/aerial_l1_entrypoint.sh new file mode 100755 index 0000000000..c8bac9eb3e --- /dev/null +++ b/ci-scripts/yaml_files/sa_gnb_aerial_30MHz/aerial_l1_entrypoint.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +# Check if cuBB_SDK is defined, if not, use default path +cuBB_Path="${cuBB_SDK:-/opt/nvidia/cuBB}" + +cd "$cuBB_Path" || exit 1 + +# Restart MPS +# Export variables +export CUDA_DEVICE_MAX_CONNECTIONS=8 +export CUDA_MPS_PIPE_DIRECTORY=/var +export CUDA_MPS_LOG_DIRECTORY=/var + +# Stop existing MPS +echo quit | sudo -E nvidia-cuda-mps-control + +# Start MPS +sudo -E nvidia-cuda-mps-control -d +sudo -E echo start_server -uid 0 | sudo -E nvidia-cuda-mps-control + +# Start cuphycontroller_scf +# Check if an argument is provided +if [ $# -eq 0 ]; then + # No argument provided, use default value + argument="P5G_WNC_GH" +else + # Argument provided, use it + argument="$1" +fi + +sudo -E "$cuBB_Path"/build.$(uname -m)/cuPHY-CP/cuphycontroller/examples/cuphycontroller_scf "$argument" +sudo -E ./build.$(uname -m)/cuPHY-CP/gt_common_libs/nvIPC/tests/pcap/pcap_collect diff --git a/ci-scripts/yaml_files/sa_gnb_aerial_30MHz/cuphycontroller_P5G_WNC_GH.yaml b/ci-scripts/yaml_files/sa_gnb_aerial_30MHz/cuphycontroller_P5G_WNC_GH.yaml new file mode 100644 index 0000000000..d43e2b17ad --- /dev/null +++ b/ci-scripts/yaml_files/sa_gnb_aerial_30MHz/cuphycontroller_P5G_WNC_GH.yaml @@ -0,0 +1,243 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +aerial_sdk_version: 25-3-cubb +l2adapter_filename: l2_adapter_config_P5G_GH.yaml +aerial_metrics_backend_address: 127.0.0.1:8081 + +# CPU core shared by all low-priority threads +low_priority_core: 10 +enable_ptp_svc_monitoring: 0 +ptp_rms_threshold: 20 #ns +nic_tput_alert_threshold_mbps: 85000 + +cuphydriver_config: + standalone: 0 + validation: 0 + num_slots: 8 + log_level: DBG + profiler_sec: 0 + dpdk_thread: 10 + dpdk_verbose_logs: 0 + accu_tx_sched_res_ns: 500 + accu_tx_sched_disable: 0 #Flag applicable only for CX6-DX : BF3/CX7 HW and beyond support accurate send scheduling directly on timestamp, for CX6-DX this is implemented via software emulation + fh_stats_dump_cpu_core: -1 + pdump_client_thread: -1 + use_green_contexts: 0 + use_batched_memcpy: 0 # Experimental feature; requires >= CUDA 12.8 + mps_sm_pusch: 100 + mps_sm_pucch: 2 + mps_sm_prach: 2 + mps_sm_ul_order: 20 + mps_sm_pdsch: 102 + mps_sm_pdcch: 10 + mps_sm_pbch: 2 + mps_sm_gpu_comms: 16 + mps_sm_srs: 16 + pdsch_fallback: 0 + dpdk_file_prefix: cuphycontroller + nics: + - nic: '0000:01:00.0' + mtu: 9216 + cpu_mbufs: 196608 + uplane_tx_handles: 64 + txq_size: 8192 + rxq_size: 16384 + gpu: 0 + cus_port_failover: 0 + gpus: + - 0 + # Set GPUID to the GPU sharing the PCIe switch as NIC + # run nvidia-smi topo -m to find out which GPU + workers_ul: [4,5] + workers_dl: [6,7,8] + debug_worker: -1 + workers_sched_priority: 95 + prometheus_thread: -1 + start_section_id_srs: 3072 + start_section_id_prach: 2048 + enable_ul_cuphy_graphs: 1 + enable_dl_cuphy_graphs: 1 + ul_order_kernel_mode: 0 # 0: Ping-Pong, 1: dual CTA + ul_order_timeout_cpu_ns: 8000000 + ul_order_timeout_log_interval_ns: 1000000000 + ul_order_timeout_gpu_ns: 3000000 + ul_order_timeout_gpu_srs_ns: 5200000 + ul_srs_aggr3_task_launch_offset_ns: 500000 + ul_order_timeout_gpu_log_enable: 0 + ul_order_max_rx_pkts: 512 + ul_order_rx_pkts_timeout_ns: 100000 + cplane_disable: 0 + gpu_init_comms_dl: 1 + cell_group: 1 + cell_group_num: 1 + fix_beta_dl: 0 + bfw_beta_prescaler: 16384 + pusch_workCancelMode: 2 # set cuphyPuschStatPrms_t workCancelMode field to PUSCH_DEVICE_GRAPHS; this only sets the mode and does not cancel work; + # work cancellation (i.e., not launching some of the device graphs) can only occur after an explicit internal + # memory write is timely observed by a PUSCH graph. + pusch_sinr: 2 + pusch_rssi: 1 + pusch_tdi: 1 + pusch_cfo: 1 + pusch_dftsofdm: 0 + pusch_to: 1 + pusch_select_eqcoeffalgo: 3 + pusch_select_chestalgo: 1 + pusch_enable_perprgchest: 0 + pusch_tbsizecheck: 1 + pusch_deviceGraphLaunchEn: 1 + pusch_waitTimeOutPreEarlyHarqUs: 3000 + pusch_waitTimeOutPostEarlyHarqUs: 3000 + puxch_polarDcdrListSz: 8 + enable_cpu_task_tracing: 0 + enable_prepare_tracing: 0 + disable_empw: 0 #1=>Disables Multi packet WQE feature + cqe_tracer_config: + enable_dl_cqe_tracing: 0 + cqe_trace_cell_mask: 1 #[64 bit mask: Bit0->Cell0, Bit1->Cell1...] + cqe_trace_slot_mask: 196800 #[20 bit mask: Bit0->Slot0, Bit1->Slot1...] 196800=>All *6,*7 DL Slots + ul_rx_pkt_tracing_level: 0 + ul_rx_pkt_tracing_level_srs: 0 + pmu_metrics: 0 #Enable and select PMU metrics, 0=disabled, 1=General Counters (platform agnostic), 2=Topdown Metrics (Grace only), 3=Cache Metrics (Grace only) + enable_h2d_copy_thread: 1 + h2d_copy_thread_cpu_affinity : 11 + h2d_copy_thread_sched_priority : 95 #0->SCHED_OTHER, >0->Actual + split_ul_cuda_streams: 0 # 1=Put UL slot 4 and slot 5 on different streams for DDDSUUDDDD pattern + serialize_pucch_pusch: 0 # 1=Force serialization of PUSCH/PUCCH + # Note: for Early Harq (EH) order is PUSCH EH -> PUCCH -> PUSCH non EH + # for non-Early Harq order is PUCCH -> all PUSCH processing + aggr_obj_non_avail_th: 5 # Threshold for consecutive non-availability of Aggregated objects(UL/DL) or DL/UL buffers + dl_wait_th_ns: + - 500000 #H2D copy wait threshold + - 4000000 #cuPHY DL channel wait threshold + sendCPlane_timing_error_th_ns : 0 + sendCPlane_ulbfw_backoff_th_ns: 300000 # ULBFW must be completed by cplane send time - this is the backoff time + sendCPlane_dlbfw_backoff_th_ns: 300000 # DLBFW must be completed by cplane send time - this is the backoff time + pusch_forcedNumCsi2Bits: 0 + mMIMO_enable: 0 + enable_srs: 1 + ue_mode: 0 + mCh_segment_proc_enable: 0 + pusch_aggr_per_ctx: 3 + prach_aggr_per_ctx: 2 + pucch_aggr_per_ctx: 4 + srs_aggr_per_ctx: 3 + ul_input_buffer_per_cell: 10 + ul_input_buffer_per_cell_srs: 6 + max_harq_pools: 384 + max_harq_tx_count_bundled: 10 + max_harq_tx_count_non_bundled: 4 + ok_testbench_config: + enable_ok_tb: 0 + num_ok_tb_slot: 0 #Presently not used + max_ru_unhealthy_ul_slots: 100 + srs_chest_algo_type: 0 + srs_chest_tol2_normalization_algo_type: 1 + srs_chest_tol2_constant_scaler: 32768.0 + bfw_power_normalization_alg_selector: 1 + total_num_srs_chest_buffers: 6144 + send_static_bfw_wt_all_cplane: 1 + ul_pcap_capture_enable: 0 + ul_pcap_capture_thread_cpu_affinity: 10 + ul_pcap_capture_thread_sched_priority: 95 + pcap_logger_ul_cplane_enable: 0 + pcap_logger_dl_cplane_enable: 0 + pcap_logger_thread_cpu_affinity: 10 + pcap_logger_thread_sched_prio: 95 + pcap_logger_file_save_dir: ./ + dlc_bfw_enable_divide_per_cell: 0 # Enable/disable dividing DL BFW C-Plane transmission window among multiple cells in a slot + ulc_bfw_enable_divide_per_cell: 0 # Enable/disable dividing UL BFW C-Plane transmission window among multiple cells in a slot + dlc_alloc_cplane_bfw_txq: 0 # Allocates a second separate queue for BFW DL C-Plane transmission + ulc_alloc_cplane_bfw_txq: 1 # Allocates a second separate queue for BFW UL C-Plane transmission + #static beam id range + static_beam_id_start: 1 + static_beam_id_end: 16527 + #dynamic beam id range + dynamic_beam_id_start: 16528 #Dynamic beam ID start should be after static beam ID end + dynamic_beam_id_end: 32767 #15bit max value + bfw_c_plane_chaining_mode: 0 # 0: Default memcpy of BFW weights, 1: CPU mbuf chaining of BFW weights, 2: GPU mbuf chaining + enable_l1_param_sanity_check: 0 + pusch_nMaxLdpcHetConfigs: 32 + notify_ul_harq_buffer_release: 0 + + # data_config: + # datalake_core: 12 # This must be set for Data Lake and/or E3 Agent to be used + # datalake_db_write_enable: 1 # Enable/disable ClickHouse writes based on datalake_data_types + # datalake_samples: 1000000 + # datalake_address: localhost + # datalake_engine: "MergeTree() PRIMARY KEY (TsTaiNs)" + # # datalake_drop_tables: 0 # Set to 1 to drop Clickhouse tables at startup + # datalake_data_types: [fh, pusch, hest] # Data types to write to ClickHouse DB (all types always collected in memory for E3 Agent): + # fh = Fronthaul IQ samples,pusch = PUSCH/FAPI data, hest = channel estimates + # datalake_store_failed_pdu: 0 # Set to 1 to store PDU data even when CRC fails + # e3_agent_enable: 0 # Enable/disable E3 Agent and dApp capabilities + # num_rows_fh: 120 + # num_rows_pusch: 200 + # num_rows_hest: 140 + # e3_pub_port: 5555 # E3 publisher port for indication messages + # e3_rep_port: 5556 # E3 reply port for E3AP requests + # e3_sub_port: 5560 # E3 subscriber port for Manager messages + + cells: + - name: O-RU 0 + cell_id: 1 + ru_type: 1 + # set to 00:00:00:00:00:00 to use the MAC address of the NIC port to use + src_mac_addr: 00:00:00:00:00:00 + dst_mac_addr: e8:c7:cf:ad:12:0b #WNC n78 + nic: '0000:01:00.0' + vlan: 500 + pcp: 7 + txq_count_uplane: 1 + eAxC_id_ssb_pbch: [0, 1, 2, 3] + eAxC_id_pdcch: [0, 1, 2, 3] + eAxC_id_pdsch: [0, 1, 2, 3] + eAxC_id_csirs: [0, 1, 2, 3] + eAxC_id_pusch: [0, 1, 2, 3] + eAxC_id_pucch: [0, 1, 2, 3] + eAxC_id_srs: [8, 9, 10, 11] + eAxC_id_prach: [4, 5, 6, 7] + dl_iq_data_fmt: {comp_meth: 1, bit_width: 9} + ul_iq_data_fmt: {comp_meth: 1, bit_width: 9} + section_3_time_offset: 484 + fs_offset_dl: 10 + exponent_dl: 4 + ref_dl: 0 + fs_offset_ul: -5 + exponent_ul: 4 + max_amp_ul: 65504 + mu: 1 + T1a_max_up_ns: 280000 + T1a_max_cp_ul_ns: 405000 + Ta4_min_ns: 50000 + Ta4_max_ns: 331000 + Tcp_adv_dl_ns: 125000 + ul_u_plane_tx_offset_ns: 280000 + fh_len_range: 0 + pusch_prb_stride: 273 + prach_prb_stride: 12 + srs_prb_stride: 273 + pusch_ldpc_max_num_itr_algo_type: 1 + pusch_fixed_max_num_ldpc_itrs: 10 + pusch_ldpc_early_termination: 0 + pusch_ldpc_algo_index: 0 + pusch_ldpc_flags: 2 + pusch_ldpc_use_half: 1 + pusch_nMaxPrb: 273 + pusch_nMaxRx: 4 + ul_gain_calibration: 78.68 + lower_guard_bw: 845 + tv_pusch: cuPhyChEstCoeffs.h5 diff --git a/ci-scripts/yaml_files/sa_gnb_aerial_30MHz/docker-compose.yaml b/ci-scripts/yaml_files/sa_gnb_aerial_30MHz/docker-compose.yaml new file mode 100644 index 0000000000..7842077ab3 --- /dev/null +++ b/ci-scripts/yaml_files/sa_gnb_aerial_30MHz/docker-compose.yaml @@ -0,0 +1,67 @@ +services: + nv-cubb: + container_name: nv-cubb + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: all + capabilities: + - gpu + network_mode: host + shm_size: 4096m + privileged: true + stdin_open: true + tty: true + volumes: + - /lib/modules:/lib/modules + - /dev/hugepages:/dev/hugepages + - /usr/src:/usr/src + - ./cuphycontroller_P5G_WNC_GH.yaml:/opt/nvidia/cuBB/cuPHY-CP/cuphycontroller/config/cuphycontroller_P5G_WNC_GH.yaml + - ./aerial_l1_entrypoint.sh:/opt/nvidia/cuBB/aerial_l1_entrypoint.sh + - /var/log/aerial:/var/log/aerial + - ../../../cmake_targets/share:/opt/cuBB/share + userns_mode: host + ipc: "shareable" + image: cubb-build:25-3 + environment: + - cuBB_SDK=/opt/nvidia/cuBB + command: bash -c "sudo rm -rf /tmp/phy.log && sudo chmod +x /opt/nvidia/cuBB/aerial_l1_entrypoint.sh && /opt/nvidia/cuBB/aerial_l1_entrypoint.sh" + healthcheck: + test: ["CMD-SHELL",'grep -q "L1 is ready!" /tmp/phy.log && echo 0 || echo 1'] + interval: 20s + timeout: 5s + retries: 5 + oai-gnb-aerial: + cpuset: "13-16" + image: ${REGISTRY-oaisoftwarealliance/}${GNB_IMG:-oai-gnb-aerial}:${TAG:-develop} + depends_on: + nv-cubb: + condition: service_healthy + cap_drop: + - ALL + cap_add: + - SYS_NICE + - IPC_LOCK + ipc: "container:nv-cubb" + environment: + USE_ADDITIONAL_OPTIONS: --log_config.global_log_options level,nocolor,utc_time + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: all + capabilities: + - gpu + network_mode: host + shm_size: 4096m + volumes: + - ../../conf_files/gnb-vnf.sa.band78.78prb.aerial.conf:/opt/oai-gnb/etc/gnb.conf + container_name: oai-gnb-aerial + healthcheck: + test: /bin/bash -c "ps aux | grep -v grep | grep -c softmodem" + interval: 10s + timeout: 5s + retries: 5 diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 64c171276c..2652b29634 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -105,19 +105,9 @@ check_supported_distribution() { case "$distribution" in "ubuntu24.04") return 0 ;; "ubuntu22.04") return 0 ;; - "ubuntu20.04") return 0 ;; "debian11") return 0 ;; "debian12") return 0 ;; - "fedora41") return 0 ;; - "fedora40") return 0 ;; - "rhel8.2") return 0 ;; - "rhel8.3") return 0 ;; - "rhel8.4") return 0 ;; - "rhel8.5") return 0 ;; - "rhel8.6") return 0 ;; - "rhel8.7") return 0 ;; - "rhel8.8") return 0 ;; - "rhel8.9") return 0 ;; + "fedora43") return 0 ;; "rhel9.0") return 0 ;; "rhel9.1") return 0 ;; "rhel9.2") return 0 ;; @@ -127,9 +117,6 @@ check_supported_distribution() { "rhel9.6") return 0 ;; "rhel9.7") return 0 ;; "centos9") return 0 ;; # CentOS stream - "rocky8.7") return 0 ;; - "rocky8.8") return 0 ;; - "rocky8.9") return 0 ;; "rocky9.1") return 0 ;; "rocky9.2") return 0 ;; "rocky9.3") return 0 ;; @@ -281,7 +268,7 @@ check_install_usrp_uhd_driver(){ $SUDO apt-get update $SUDO apt-get -y install python3-tk $boost_libs_ubuntu libusb-1.0-0-dev case "$(get_distribution_release)" in - "ubuntu20.04" | "ubuntu22.04") + "ubuntu22.04") $SUDO apt-get -y install libuhd-dev libuhd4.5.0 uhd-host ;; esac @@ -441,7 +428,7 @@ check_install_additional_tools (){ local optional_packages="" if [[ "$OS_BASEDISTRO" == "debian" ]]; then case "$(get_distribution_release)" in - "ubuntu20.04" | "ubuntu22.04" | "debian11" | "debian12" ) + "ubuntu22.04" | "debian11" | "debian12" ) optional_packages="python3 python3-pip python3-dev python3-scipy python3-matplotlib python3-pyroute2 universal-ctags" ;; esac diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h index a9db2e9c5c..837c6897a6 100644 --- a/common/utils/LOG/log.h +++ b/common/utils/LOG/log.h @@ -165,6 +165,7 @@ static const char *const flag_name[] = {FOREACH_FLAG(FLAG_TEXT) ""}; COMP_DEF(M2AP, ) \ COMP_DEF(M3AP, ) \ COMP_DEF(NGAP, ) \ + COMP_DEF(NRPPA, ) \ COMP_DEF(GNB_APP, log) \ COMP_DEF(NR_RRC, log) \ COMP_DEF(NR_MAC, log) \ diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index d2405f9033..818b30b7d0 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -586,6 +586,27 @@ ID = LEGACY_NGAP_TRACE GROUP = ALL:LEGACY_NGAP:LEGACY_GROUP_TRACE:LEGACY FORMAT = string,log +ID = LEGACY_NRPPA_INFO + DESC = NRPPA legacy logs - info level + GROUP = ALL:LEGACY_NRPPA:LEGACY_GROUP_INFO:LEGACY + FORMAT = string,log +ID = LEGACY_NRPPA_ERROR + DESC = NRPPA legacy logs - error level + GROUP = ALL:LEGACY_NRPPA:LEGACY_GROUP_ERROR:LEGACY + FORMAT = string,log +ID = LEGACY_NRPPA_WARNING + DESC = NRPPA legacy logs - warning level + GROUP = ALL:LEGACY_NRPPA:LEGACY_GROUP_WARNING:LEGACY + FORMAT = string,log +ID = LEGACY_NRPPA_DEBUG + DESC = NRPPA legacy logs - debug level + GROUP = ALL:LEGACY_NRPPA:LEGACY_GROUP_DEBUG:LEGACY + FORMAT = string,log +ID = LEGACY_NRPPA_TRACE + DESC = NRPPA legacy logs - trace level + GROUP = ALL:LEGACY_NRPPA:LEGACY_GROUP_TRACE:LEGACY + FORMAT = string,log + ID = LEGACY_X2AP_INFO DESC = X2AP legacy logs - info level GROUP = ALL:LEGACY_X2AP:LEGACY_GROUP_INFO:LEGACY @@ -1404,7 +1425,7 @@ ID = UE_PHY_PDCCH_ENERGY ID = UE_PHY_PDSCH_IQ DESC = UE PDSCH received IQ data GROUP = ALL:PHY:GRAPHIC:HEAVY:UE - FORMAT = int,eNB_ID : int,frame : int,subframe : int,nb_rb : int,N_RB_UL : int,symbols_per_tti : buffer,pusch_comp + FORMAT = int,eNB_ID : int,frame : int,subframe : int,nb_rb : int,N_RB_UL : int,symbols_per_tti : buffer,pdsch_comp ID = UE_PHY_PDSCH_ENERGY DESC = UE PDSCH 1 energy and threshold GROUP = ALL:PHY:GRAPHIC:HEAVY:UE diff --git a/common/utils/T/tracer/CMakeLists.txt b/common/utils/T/tracer/CMakeLists.txt index e347552d31..d64ea840a9 100644 --- a/common/utils/T/tracer/CMakeLists.txt +++ b/common/utils/T/tracer/CMakeLists.txt @@ -37,11 +37,65 @@ add_subdirectory(filter) add_subdirectory(logger) add_subdirectory(view) +# Option to enable record_db tracer tool with ClickHouse database support +add_boolean_option(T_RECORD_DB OFF "Compile record_db tracer tool with ClickHouse support" OFF) + +if(T_RECORD_DB) + # Save current BUILD_SHARED_LIBS setting + set(SAVED_BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS}) + + # Configure options for clickhouse-cpp + set(BUILD_SHARED_LIBS ON CACHE BOOL "" FORCE) + + # Save current compiler flags and disable -Werror for zstd + set(SAVED_CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") + + # Check if system zstd library is available + find_library(ZSTD_LIBRARY NAMES zstd) + if(ZSTD_LIBRARY) + # Use system zstd library to avoid building legacy zstd code with warnings + set(WITH_SYSTEM_ZSTD ON CACHE BOOL "" FORCE) + else() + # Fall back to bundled zstd and suppress warnings from legacy code + # https://github.com/ClickHouse/clickhouse-cpp/blob/master/contrib/zstd/zstd/legacy/zstd_v01.c#L1935 + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-maybe-uninitialized -Wno-uninitialized") + endif() + + CPMAddPackage( + NAME clickhouse-cpp + GITHUB_REPOSITORY ClickHouse/clickhouse-cpp + GIT_TAG master + ) + + # Restore original compiler flags and BUILD_SHARED_LIBS + set(CMAKE_C_FLAGS "${SAVED_CMAKE_C_FLAGS}") + set(BUILD_SHARED_LIBS ${SAVED_BUILD_SHARED_LIBS} CACHE BOOL "" FORCE) + + CPMAddPackage( + NAME fmtlog + GITHUB_REPOSITORY MengRao/fmtlog + GIT_TAG main + GIT_SHALLOW FALSE + ) + + add_executable(record_db record_db.cpp) + + target_include_directories(record_db PRIVATE ${fmtlog_SOURCE_DIR} ${fmtlog_SOURCE_DIR}/fmt/include) + target_link_libraries(record_db PRIVATE tracer_utils clickhouse-cpp-lib fmtlog-shared fmt) + +endif() # T_RECORD_DB + add_custom_target(T_tools) add_dependencies(T_tools record replay extract_config extract_input_subframe extract_output_subframe extract macpdu2wireshark multi textlog csv) + +# Add record_db to T_tools if it was built +if(TARGET record_db) + add_dependencies(T_tools record_db) +endif() + add_dependencies(nr-softmodem T_tools) add_dependencies(nr-uesoftmodem T_tools) add_dependencies(lte-softmodem T_tools) diff --git a/common/utils/T/tracer/Makefile b/common/utils/T/tracer/Makefile index cedf8fdbcf..5d0aed4029 100644 --- a/common/utils/T/tracer/Makefile +++ b/common/utils/T/tracer/Makefile @@ -1,18 +1,23 @@ CC=gcc +CXX=g++ CFLAGS=-Wall -g -pthread -DT_TRACER -I. -I../incgen +CXXFLAGS=-Wall -g -pthread -DT_TRACER -I. -I../incgen -std=c++11 #CFLAGS += -O3 -ffast-math -fomit-frame-pointer LIBS=-lm XLIBS=-lX11 -lpng -lXft -all: record replay extract_config textlog enb ue vcd macpdu2wireshark \ +all: record record_db replay extract_config textlog enb ue vcd macpdu2wireshark \ extract_input_subframe extract_output_subframe to_vcd extract multi \ gnb t_tracer_app_gnb t_tracer_app_ue gnb_mac csv record: utils.o record.o database.o configuration.o $(CC) $(CFLAGS) -o record $^ $(LIBS) +record_db: utils.o record_db.o database.o configuration.o + $(CXX) $(CXXFLAGS) -o record_db $^ $(LIBS) -lclickhouse-cpp-lib $(FMTLOG_LIBS) + replay: utils.o replay.o $(CC) $(CFLAGS) -o replay $^ $(LIBS) @@ -102,8 +107,11 @@ filter/filter.a: %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< +%.o: %.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + clean: - rm -f *.o core tracer_remote textlog enb ue vcd record replay + rm -f *.o core tracer_remote textlog enb ue vcd record record_db replay rm -f extract_config macpdu2wireshark extract_input_subframe rm -f extract_output_subframe to_vcd extract multi gnb rm -f t_tracer_app_gnb t_tracer_app_ue gnb_mac csv diff --git a/common/utils/T/tracer/record_db.cpp b/common/utils/T/tracer/record_db.cpp new file mode 100644 index 0000000000..b450f617db --- /dev/null +++ b/common/utils/T/tracer/record_db.cpp @@ -0,0 +1,1324 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "fmtlog.h" + +namespace ch = clickhouse; + +extern "C" { // For connect_to(), socket_send(), parse_database(), etc. +#include +#include +#include +#include +#include +#include "database.h" +#include "utils.h" +#include "../T_defs.h" +#include "configuration.h" +} + +const int MAX_QUERY_SIZE = 65536; +const char *DEFAULT_CLICKHOUSE_HOST = "localhost"; +const int DEFAULT_CLICKHOUSE_PORT = 9000; +const char *DEFAULT_CLICKHOUSE_DB = "oai"; + +// Buffer multiple rows per event type and insert when: +// 1. Buffer reaches BATCH_SIZE rows, OR +// 2. INSERT_INTERVAL_MS milliseconds have elapsed since last insert +// This reduces insertion time from ~30ms/event to <1ms/event amortized +const size_t BATCH_SIZE = 500; // Number of rows to buffer before inserting +const uint64_t INSERT_INTERVAL_MS = 500; // Insert every 500ms +const size_t BUFFER_SIZE = 10 * 1024 * 1024; // 10MB +const size_t BUFFER_MARGIN = 183'456; // UE_PHY_PDSCH_IQ size + +// 5G NR timing constants +const uint64_t NS_PER_SEC = 1000000000ULL; +const uint64_t FRAME_PERIOD_NS = 10000000ULL; // 10ms per frame +const int SFN_MAX = 1024; +// Duration of one full SFN cycle (1024 frames = 10.24 seconds) +const uint64_t SFN_CYCLE_NS = FRAME_PERIOD_NS * SFN_MAX; + +// TAI to UTC offset in seconds (37 leap seconds as of 2017) +// This may need to be updated when new leap seconds are added +const int TAI_UTC_OFFSET_SEC = 37; + +// GPS epoch is January 6, 1980 00:00:00 UTC +// Unix epoch is January 1, 1970 00:00:00 UTC +// Offset = 315964800 seconds +const uint64_t UNIX_TO_GPS_OFFSET_SEC = 315964800ULL; +const uint64_t UNIX_TO_GPS_OFFSET_NS = UNIX_TO_GPS_OFFSET_SEC * NS_PER_SEC; +const uint8_t UTC_TO_GPS_OFFSET_SEC = 18; // As of 2017, GPS time is 18 seconds ahead of UTC time. +const uint64_t UTC_TO_GPS_OFFSET_NS = UTC_TO_GPS_OFFSET_SEC * NS_PER_SEC; + +/** + * Calculate duration between two timestamps in nanoseconds + * Works with both std::chrono::high_resolution_clock::time_point and uint64_t nanosecond timestamps + */ +#define DURATION_NS(start, end) (std::chrono::duration_cast((end) - (start)).count()) +#define DURATION_US(start, end) (std::chrono::duration_cast((end) - (start)).count()) +#define DURATION_MS(start, end) (std::chrono::duration_cast((end) - (start)).count()) + +/** + * Calculate duration between two uint64_t nanosecond timestamps + */ +#define DURATION_NS_U64(end_ns, start_ns) ((int64_t)(end_ns) - (int64_t)(start_ns)) +/** + * Get slot duration in nanoseconds for a given numerology + * mu=0 (15kHz): 1ms, mu=1 (30kHz): 0.5ms, mu=2 (60kHz): 0.25ms, etc. + */ +inline uint64_t get_slot_duration_ns(int mu) +{ + static const uint64_t slot_durations_ns[] = { + 1000000, // mu=0: 1ms + 500000, // mu=1: 0.5ms + 250000, // mu=2: 0.25ms + 125000, // mu=3: 0.125ms + 62500 // mu=4: 0.0625ms + }; + if (mu < 0 || mu > 4) { + loge("Invalid numerology mu={}, using mu=0", mu); + return slot_durations_ns[0]; + } + return slot_durations_ns[mu]; +} + +/** + * Get number of slots per frame for a given numerology + */ +inline int get_slots_per_frame(int mu) +{ + static const int slots_per_frame[] = {10, 20, 40, 80, 160}; + if (mu < 0 || mu > 4) { + loge("Invalid numerology mu={}, using mu=0", mu); + return slots_per_frame[0]; + } + return slots_per_frame[mu]; +} + +/** + * Convert Unix/Linux time to GPS time + * + * @param unix_time_ns Unix time in nanoseconds since Unix epoch (Jan 1, 1970) + * @return GPS time in nanoseconds since GPS epoch (Jan 6, 1980) + */ +inline uint64_t unix_to_gps_ns(uint64_t unix_time_ns) +{ + return unix_time_ns - UNIX_TO_GPS_OFFSET_NS + UTC_TO_GPS_OFFSET_NS; +} + +/** + * Convert GPS time to Unix/Linux time + * + * @param gps_time_ns GPS time in nanoseconds since GPS epoch + * @return GPS time in nanoseconds since Unix epoch + */ +inline uint64_t gps_to_posix_ns(uint64_t gps_time_ns) +{ + return gps_time_ns + UNIX_TO_GPS_OFFSET_NS; +} + +/** + * Convert GPS time to Unix/Linux time + * + * @param gps_time_ns GPS time in nanoseconds since GPS epoch + * @return UTC time in nanoseconds since Unix epoch + */ +inline uint64_t gps_to_utc_ns(uint64_t gps_time_ns) +{ + return gps_to_posix_ns(gps_time_ns) - UTC_TO_GPS_OFFSET_NS; +} + +/** + * Calculate the absolute GPS timestamp for a given SFN and slot, given a close time reference in Unix time. + * + * @param sfn System Frame Number (0-1023) + * @param slot Slot number within the frame (depends on numerology) + * @param mu Numerology (0-4): 0=15kHz, 1=30kHz, 2=60kHz, 3=120kHz, 4=240kHz + * @param reference_utc_ns Reference UTC time in nanoseconds since Unix epoch + * @return UTC timestamp in nanoseconds when the SFN/slot was transmitted + */ +uint64_t calculate_sfn_slot_gps_time(int sfn, int slot, int mu, uint64_t reference_unix_ns) +{ + // Validate inputs + if (sfn < 0 || sfn >= SFN_MAX) { + loge("Invalid SFN={} (must be 0-1023)", sfn); + sfn = sfn % SFN_MAX; + return 0; + } + + int slots_per_frame = get_slots_per_frame(mu); + if (slot < 0 || slot >= slots_per_frame) { + loge("Invalid slot={} for mu={} (must be 0-{})", slot, mu, slots_per_frame - 1); + slot = slot % slots_per_frame; + } + // Nanoseconds since GPS epoch start, should be slightly larger than actual transmit time. + uint64_t reference_gps_ns = unix_to_gps_ns(reference_unix_ns); + + // Calculate the offset within one SFN cycle for the given SFN/slot + uint64_t slot_duration_ns = get_slot_duration_ns(mu); + uint64_t offset_in_cycle_ns = (sfn * FRAME_PERIOD_NS) + (slot * slot_duration_ns); + + // Find the number of complete SFN cycles since GPS epoch + // We'll use the reference time to determine which SFN cycle we're in + uint64_t cycles_since_epoch = reference_gps_ns / SFN_CYCLE_NS; + + // Calculate the base time for the current SFN cycle + uint64_t current_cycle_base_ns = cycles_since_epoch * SFN_CYCLE_NS; + + // Calculate the target time within this cycle + uint64_t gps_time_ns = current_cycle_base_ns + offset_in_cycle_ns; + + // Check if the GPS time is too far in the future (more than 1 second) + // If so, it probably occurred in the previous cycle + if (gps_time_ns > reference_gps_ns + NS_PER_SEC) { + gps_time_ns -= SFN_CYCLE_NS; + } + // Check if the target is too far in the past (more than 9.24 seconds) + // If so, it probably occurs in the next cycle + if (gps_time_ns < reference_gps_ns - (SFN_CYCLE_NS - NS_PER_SEC)) { + gps_time_ns += SFN_CYCLE_NS; + } + return gps_time_ns; +} + +void calculate_sfn_slot_from_gps(uint64_t gps_time_ns, int mu, int *sfn, int *slot) +{ + uint64_t phase_ns = gps_time_ns % SFN_CYCLE_NS; + + *sfn = phase_ns / FRAME_PERIOD_NS; // Truncate to integer + uint64_t position_in_frame_ns = phase_ns % FRAME_PERIOD_NS; // Remainder + + uint64_t slot_duration_ns = get_slot_duration_ns(mu); + *slot = position_in_frame_ns / slot_duration_ns; + + if (*sfn >= SFN_MAX) + *sfn = SFN_MAX - 1; + int max_slot = get_slots_per_frame(mu) - 1; + if (*slot > max_slot) + *slot = max_slot; +} + +void calculate_sfn_slot_from_unix(uint64_t unix_time_ns, int mu, int *sfn, int *slot) +{ + uint64_t gps_time_ns = unix_to_gps_ns(unix_time_ns); + calculate_sfn_slot_from_gps(gps_time_ns, mu, sfn, slot); +} + +void usage(void) +{ + printf( + "options:\n" + " -d this option is mandatory\n" + " -on turn log ON for given GROUP or ID\n" + " -off turn log OFF for given GROUP or ID\n" + " -ON turn all logs ON\n" + " -OFF turn all logs OFF\n" + " note: you may pass several -on/-off/-ON/-OFF,\n" + " they will be processed in order\n" + " by default, all is off\n" + " -ip connect to given IP address (default %s)\n" + " -p connect to given port (default %d)\n" + " -ch-host ClickHouse host (default %s)\n" + " -ch-port ClickHouse native port (default %d)\n" + " -ch-db ClickHouse database name (default %s)\n" + " -ch-user ClickHouse user (optional)\n" + " -ch-pass ClickHouse password (optional)\n" + " -ch-droptables drop the ClickHouse database before run\n" + " -debug enable debug logging\n", + DEFAULT_REMOTE_IP, + DEFAULT_REMOTE_PORT, + DEFAULT_CLICKHOUSE_HOST, + DEFAULT_CLICKHOUSE_PORT, + DEFAULT_CLICKHOUSE_DB); + exit(1); +} + +volatile int run = 1; + +static int socket_fd = -1; + +void force_stop(int x) +{ + logi("gently quit..."); + close(socket_fd); + socket_fd = -1; + run = 0; +} + +struct clickhouse_config_t { + std::string host; + int port; + std::string database; + std::string user; + std::string password; + std::unique_ptr client; + int drop_tables; +}; + +// Buffer management structures +struct DataBuffer { + uint8_t *buffer; // Large preallocated buffer + size_t buffer_size; // Total size of buffer + size_t current_offset; // Current write position in buffer + std::shared_ptr inner_col; // Reusable inner column for ClickHouse + std::shared_ptr offsets_col; // Reusable offsets column for ClickHouse (cumulative end offsets) + bool insert_now; + + DataBuffer(size_t size) : buffer_size(size - BUFFER_MARGIN), current_offset(0), insert_now(false) + { + buffer = (uint8_t *)malloc(size); + if (!buffer) { + throw std::bad_alloc(); + } + + // Create and reserve ClickHouse columns for reuse + inner_col = std::make_shared(); + auto &inner_data = inner_col->GetWritableData(); + inner_data.reserve(size); + + offsets_col = std::make_shared(); + offsets_col->Reserve(BATCH_SIZE); + } + + ~DataBuffer() + { + if (buffer) { + free(buffer); + buffer = nullptr; + } + } + + // Disable copy constructor and assignment operator + DataBuffer(const DataBuffer &) = delete; + DataBuffer &operator=(const DataBuffer &) = delete; + + // Copy data into buffer and return offset + size_t append(const void *data, size_t length) + { + if (current_offset + length > buffer_size) { + insert_now = true; // If this puts the buffer into the margin, insert it immediately + if (length > BUFFER_MARGIN) { + loge("DataBuffer full: current_offset={} length={} buffer_size={}", current_offset, length, buffer_size); + return (size_t)-1; + } // Else we have margin + } + + size_t offset = current_offset; + memcpy(buffer + current_offset, data, length); + current_offset += length; + + offsets_col->Append(current_offset); + + return offset; + } + + // Get pointer to data at a specific offset + const uint8_t *get_data(size_t offset) const + { + if (offset >= current_offset) { + return nullptr; + } + return buffer + offset; + } + + // Clear buffer for reuse + void clear() + { + current_offset = 0; + insert_now = false; + inner_col->Clear(); + offsets_col->Clear(); + } + + // Get number of entries + size_t entry_count() const + { + return offsets_col->Size(); + } + + // Get current usage + size_t usage() const + { + return current_offset; + } +}; + +struct EventBuffer { + std::vector columns; // Ordered list of columns + std::vector column_names; // Column names in same order + std::string event_table_name; + size_t row_count; + bool insert_now; + std::chrono::steady_clock::time_point last_insert_time; + database_event_format format; + std::string event_name; + bool has_frame_slot; + std::unordered_map> data_buffers; + + // Cached typed column pointers to avoid expensive As<> casts on every insert + std::shared_ptr ts_sw_col; + std::shared_ptr ts_tx_col; + std::vector> int_cols; + std::vector> ulong_cols; + std::vector> string_cols; + std::unordered_map field_idx_to_typed_col_idx; // Maps format field index to typed column index + + // Performance metrics + uint64_t last_column_build_duration_ns; + uint64_t last_block_append_duration_ns; + uint64_t last_insertion_duration_ns; + + // Statistics tracking + uint64_t total_rows; // Total rows inserted since start + uint64_t rows_since_print; // Rows since last print + + EventBuffer() + : row_count(0), + insert_now(false), + last_insert_time(std::chrono::steady_clock::now()), + has_frame_slot(false), + last_column_build_duration_ns(0), + last_block_append_duration_ns(0), + last_insertion_duration_ns(0), + total_rows(0), + rows_since_print(0) + { + } +}; + +// Global buffer map: event_id -> EventBuffer +std::unordered_map g_event_buffers; + +/* Convert T format type to ClickHouse type */ +const char *get_clickhouse_type(const char *t_type) +{ + if (strcmp(t_type, "int") == 0) + return "Int32"; + if (strcmp(t_type, "ulong") == 0) + return "UInt64"; + if (strcmp(t_type, "string") == 0) + return "String"; + if (strcmp(t_type, "buffer") == 0) + return "Array(UInt8)"; // Store as byte array + if (strncmp(t_type, "int", 3) == 0) + return "Int32"; + return "String"; // default +} + +/* Execute ClickHouse query */ +int clickhouse_execute(clickhouse_config_t *ch, const char *query) +{ + try { + ch->client->Execute(query); + return 0; + } catch (const std::exception &e) { + loge("ClickHouse query failed: {}", e.what()); + return -1; + } +} + +/* Initialize ClickHouse connection and create database */ +int clickhouse_init(clickhouse_config_t *ch) +{ + char query[1024]; + + try { + // Set connection options + ch::ClientOptions options; + options.SetHost(ch->host); + options.SetPort(ch->port); + + if (!ch->user.empty()) { + options.SetUser(ch->user); + } + if (!ch->password.empty()) { + options.SetPassword(ch->password); + } + + // Create client + ch->client = std::make_unique(options); + /* Handle drop database option */ + if (ch->drop_tables) { + logi("Dropping database: {}", ch->database.c_str()); + snprintf(query, sizeof(query), "DROP DATABASE IF EXISTS %s", ch->database.c_str()); + + if (clickhouse_execute(ch, query) != 0) { + loge("Failed to drop database {}", ch->database); + exit(1); + } + } + + // Create database if not exists + snprintf(query, sizeof(query), "CREATE DATABASE IF NOT EXISTS %s", ch->database.c_str()); + if (clickhouse_execute(ch, query) != 0) { + loge("Failed to create database"); + return -1; + } + + logi("ClickHouse connection initialized"); + return 0; + } catch (const std::exception &e) { + loge("Failed to create ClickHouse client: {}", e.what()); + return -1; + } +} + +/* Create table schema from database format */ +char *create_table_schema(char *schema_buf, const char *event_name, database_event_format format, const char *database) +{ + char *p = schema_buf; + bool has_frame = false; + bool has_slot = false; + int i; + + // Start CREATE TABLE statement + p += snprintf(p, + MAX_QUERY_SIZE - (p - schema_buf), + "CREATE TABLE IF NOT EXISTS %s.%s (\n TsSwNs DateTime64(9) DEFAULT now64(9)", + database, + event_name); + + for (i = 0; i < format.count; i++) { + if (strcmp(format.name[i], "frame") == 0) + has_frame = true; + if (strcmp(format.name[i], "slot") == 0) + has_slot = true; + if (strcmp(format.name[i], "subframe") == 0) + has_slot = true; + } + if (has_frame && has_slot) { + p += snprintf(p, MAX_QUERY_SIZE - (p - schema_buf), ",\n TsTxUtcNs DateTime64(9)"); + uint64_t timestamp_ns = std::chrono::system_clock::now().time_since_epoch().count() / NS_PER_SEC; + if (timestamp_ns > 1861920000) { + // 1861920000 -> 2029-01-01 00:00:00 + logw("WARNING: Linux time {} is greater than 2029-01-01 00:00:00.", timestamp_ns); + logw(" Check if a negative leap second has been announced and change UTC_TO_GPS_OFFSET_NS accordingly.", + timestamp_ns); + } + } + + // Add columns from format + for (i = 0; i < format.count; i++) { + const char *ch_type = get_clickhouse_type(format.type[i]); + p += snprintf(p, MAX_QUERY_SIZE - (p - schema_buf), ",\n %s %s", format.name[i], ch_type); + } + + p += snprintf(p, MAX_QUERY_SIZE - (p - schema_buf), "\n) ENGINE = Memory();"); + +#ifdef DB_DEBUG + logd("schema: {}", schema_buf); +#endif + return schema_buf; +} + +/* Initialize buffer for an event */ +void init_event_buffer(int event_id, void *database, const char *database_name) +{ + char *event_name = event_name_from_id(database, event_id); + database_event_format format = get_format(database, event_id); + + if (!event_name) + return; + + EventBuffer &buf = g_event_buffers[event_id]; + buf.event_name = std::string(event_name); + buf.event_table_name = std::string(database_name) + "." + event_name; + buf.format = format; + buf.row_count = 0; + buf.last_insert_time = std::chrono::steady_clock::now(); + + // Check if this event has frame/slot fields + buf.has_frame_slot = false; + bool has_frame = false; + bool has_slot = false; + for (int i = 0; i < format.count; i++) { + if (strcmp(format.name[i], "frame") == 0) + has_frame = true; + if (strcmp(format.name[i], "slot") == 0 || strcmp(format.name[i], "subframe") == 0) + has_slot = true; + } + buf.has_frame_slot = has_frame && has_slot; + + // Create TsSwNs column + auto ts_col = std::make_shared(9); + ts_col->Reserve(BATCH_SIZE); + buf.columns.push_back(ts_col); + buf.column_names.push_back("TsSwNs"); + buf.ts_sw_col = ts_col; // Cache typed pointer + + // Add data columns + for (int i = 0; i < format.count; i++) { + if (strcmp(format.type[i], "int") == 0) { + auto col = std::make_shared(); + col->Reserve(BATCH_SIZE); + buf.columns.push_back(col); + buf.column_names.push_back(format.name[i]); + buf.field_idx_to_typed_col_idx[i] = buf.int_cols.size(); + buf.int_cols.push_back(col); + } else if (strcmp(format.type[i], "ulong") == 0) { + auto col = std::make_shared(); + col->Reserve(BATCH_SIZE); + buf.columns.push_back(col); + buf.column_names.push_back(format.name[i]); + buf.field_idx_to_typed_col_idx[i] = buf.ulong_cols.size(); + buf.ulong_cols.push_back(col); + } else if (strcmp(format.type[i], "buffer") == 0) { + buf.data_buffers[i] = std::make_unique(BUFFER_SIZE); + + // Placeholder - array column will be created from DataBuffer at flush time + buf.columns.push_back(nullptr); + buf.column_names.push_back(format.name[i]); + + } else if (strcmp(format.type[i], "string") == 0) { + auto col = std::make_shared(); + col->Reserve(BATCH_SIZE); + buf.columns.push_back(col); + buf.column_names.push_back(format.name[i]); + buf.field_idx_to_typed_col_idx[i] = buf.string_cols.size(); + buf.string_cols.push_back(col); + } else { + // Default: treat as int + auto col = std::make_shared(); + col->Reserve(BATCH_SIZE); + buf.columns.push_back(col); + buf.column_names.push_back(format.name[i]); + buf.field_idx_to_typed_col_idx[i] = buf.int_cols.size(); + buf.int_cols.push_back(col); + } + } + + // Add TsTxUtcNs column if event has frame/slot + if (buf.has_frame_slot) { + auto gps_col = std::make_shared(9); + gps_col->Reserve(BATCH_SIZE); + buf.columns.push_back(gps_col); + buf.column_names.push_back("TsTxUtcNs"); + buf.ts_tx_col = gps_col; // Cache typed pointer + } + + logi("Initialized buffer for event_id:{:<4} name:{:<31} has_frame_slot:{} columns:{}", + event_id, + event_name, + buf.has_frame_slot, + buf.columns.size()); + + // Print sizes of buffer fields + for (int i = 0; i < format.count; i++) { + if (strcmp(format.type[i], "buffer") == 0) { + logd(" Buffer field '{}' size={} MB", format.name[i], BUFFER_SIZE / (1024 * 1024)); + } + } +} + +/* Create tables for enabled events */ +int create_tables(clickhouse_config_t *ch, void *database, int *is_on, int number_of_events) +{ + int i; + size_t longest_table_name = 0; + + for (i = 0; i < number_of_events; i++) { + if (!is_on[i]) + continue; + + char *event_name = event_name_from_id(database, i); + database_event_format format = get_format(database, i); + if (strlen(event_name) > longest_table_name) + longest_table_name = strlen(event_name); + + if (!event_name) + continue; + + logd("Creating table for event: {:<31}", event_name); + + char schema[MAX_QUERY_SIZE]; + create_table_schema(schema, event_name, format, ch->database.c_str()); + + if (clickhouse_execute(ch, schema) != 0) { + loge("Failed to create table {}", event_name); + return -1; + } + + // Initialize buffer for this event + init_event_buffer(i, database, ch->database.c_str()); + } + + return (int)longest_table_name; +} + +int insert_buffer(clickhouse_config_t *ch, int event_id) +{ + auto it = g_event_buffers.find(event_id); + if (it == g_event_buffers.end() || it->second.row_count == 0) { + return 0; // Nothing to flush + } + + EventBuffer &buf = it->second; + buf.insert_now = false; + + auto t_reconstruct_start = std::chrono::high_resolution_clock::now(); + size_t total_data_size = 0; + for (auto &dbuf_pair : buf.data_buffers) { + int field_idx = dbuf_pair.first; + DataBuffer *dbuf = dbuf_pair.second.get(); + int col_idx = field_idx + 1; // +1 because TsSwNs is at index 0 + + // Build the array column from the DataBuffer + size_t num_entries = dbuf->offsets_col->Size(); + + if (num_entries != buf.row_count) { + loge("DataBuffer entry count mismatch for field '{}': {} entries vs {} rows", + buf.format.name[field_idx], + num_entries, + buf.row_count); + } + + // Copy all data to the DataBuffer's inner column (space already reserved in constructor) + if (dbuf->current_offset > 0) { + auto &inner_data = dbuf->inner_col->GetWritableData(); + inner_data.resize(dbuf->current_offset); // Set size (doesn't reallocate since already reserved) + memcpy(inner_data.data(), dbuf->buffer, dbuf->current_offset); + } + + // Create the array column from DataBuffer's columns and store it + auto array_col = std::make_shared>(dbuf->inner_col, dbuf->offsets_col); + buf.columns[col_idx] = array_col; + + total_data_size += dbuf->current_offset; + } + auto t_reconstruct_end = std::chrono::high_resolution_clock::now(); + + ch::Block block; + for (size_t i = 0; i < buf.columns.size(); i++) { + if (buf.columns[i]) { + block.AppendColumn(buf.column_names[i], buf.columns[i]); + } else { + loge("Column '{}' at index {} is null when creating block", buf.column_names[i], i); + exit(1); + } + } + try { + auto t_insert_start = std::chrono::high_resolution_clock::now(); + ch->client->Insert(buf.event_table_name.c_str(), block); + auto t_insert_end = std::chrono::high_resolution_clock::now(); + + buf.last_column_build_duration_ns = DURATION_NS(t_reconstruct_start, t_reconstruct_end); + buf.last_block_append_duration_ns = DURATION_NS(t_reconstruct_end, t_insert_start); + buf.last_insertion_duration_ns = DURATION_NS(t_insert_start, t_insert_end); + + // Clear all columns and re-reserve (skip buffer-type columns which are rebuilt each time) + for (size_t i = 0; i < buf.columns.size(); i++) { + if (buf.columns[i]) { // Skip nullptr placeholders for buffer-type columns + auto col = std::const_pointer_cast(buf.columns[i]); + col->Clear(); + col->Reserve(BATCH_SIZE); + } + } + + // Reset buffer-type columns back to nullptr + for (auto &dbuf_pair : buf.data_buffers) { + int field_idx = dbuf_pair.first; + int col_idx = field_idx + 1; + buf.columns[col_idx] = nullptr; + } + + // Clear all DataBuffers + for (auto &pair : buf.data_buffers) { + pair.second->clear(); + } + + int rows = buf.row_count; + buf.row_count = 0; + buf.last_insert_time = std::chrono::steady_clock::now(); + + // Update statistics + buf.total_rows += rows; + buf.rows_since_print += rows; + + return rows; + } catch (const std::exception &e) { + loge("Failed to insert buffer for event {}: {}", buf.event_name, e.what()); + return -1; + } +} + +/* Flush all buffers to ClickHouse */ +int insert_all_buffers(clickhouse_config_t *ch) +{ + int errors = 0; + for (auto &pair : g_event_buffers) { + if (insert_buffer(ch, pair.first) <= 0) { + errors++; + } + } + return errors > 0 ? -1 : 0; +} + +/* Check if buffer should be inserted based on size or time */ +uint8_t should_insert(EventBuffer &buf) +{ + if (buf.row_count == 0) { + return 0; + } + + if (buf.row_count >= BATCH_SIZE) { + return 1; + } + + if (static_cast(DURATION_MS(buf.last_insert_time, std::chrono::steady_clock::now())) >= INSERT_INTERVAL_MS) { + return 2; + } + + if (buf.insert_now) { + return 3; + } + + return 0; +} + +int insert_event(clickhouse_config_t *ch, + void *database, + int event_id, + const char *event_data, + int data_length, + std::chrono::high_resolution_clock::time_point t_start) +{ + auto t_fn_start = std::chrono::high_resolution_clock::now(); + + // Get buffer for this event + auto it = g_event_buffers.find(event_id); + if (it == g_event_buffers.end()) { + loge("Buffer not found for event_id {}", event_id); + return -1; + } + + EventBuffer &buf = it->second; + database_event_format format = buf.format; + const char *event_name = buf.event_name.c_str(); + auto t_names_done = std::chrono::high_resolution_clock::now(); + + int16_t frame = -1; + int16_t slot = -1; + + try { + const char *data_ptr = event_data; + int remaining = data_length; + int buf_len = 0; + int i; + + auto t_append_start = std::chrono::high_resolution_clock::now(); + + // Append to TsSwNs column using cached pointer + buf.ts_sw_col->Append(std::chrono::system_clock::now().time_since_epoch().count()); + + // Process data columns + for (i = 0; i < format.count && remaining > 0; i++) { + if (strcmp(format.type[i], "int") == 0) { + int val = 0; + if (remaining >= 4) { + memcpy(&val, data_ptr, 4); + if (strcmp(format.name[i], "frame") == 0) + frame = val; + else if (strcmp(format.name[i], "slot") == 0) + slot = val; + else if (strcmp(format.name[i], "subframe") == 0) + slot = val; + data_ptr += 4; + remaining -= 4; + } + + int typed_col_idx = buf.field_idx_to_typed_col_idx[i]; + buf.int_cols[typed_col_idx]->Append(val); + + } else if (strcmp(format.type[i], "ulong") == 0) { + uint64_t val = 0; + if (remaining >= 8) { + memcpy(&val, data_ptr, 8); + data_ptr += 8; + remaining -= 8; + } + + int typed_col_idx = buf.field_idx_to_typed_col_idx[i]; + buf.ulong_cols[typed_col_idx]->Append(val); + + } else if (strcmp(format.type[i], "buffer") == 0) { + buf_len = 0; + const char *buf_data = nullptr; + + if (remaining >= 4) { + memcpy(&buf_len, data_ptr, 4); + data_ptr += 4; + remaining -= 4; + + if (buf_len > remaining) + buf_len = remaining; + if (buf_len > 0) + buf_data = data_ptr; + + data_ptr += buf_len; + remaining -= buf_len; + } + + auto it_dbuf = buf.data_buffers.find(i); + if (it_dbuf != buf.data_buffers.end()) { + size_t offset = it_dbuf->second->append(buf_data, buf_len); + + buf.insert_now |= it_dbuf->second->insert_now; + + if (offset == (size_t)-1) { + loge("DataBuffer full for field '{}', cannot append {} bytes", format.name[i], buf_len); + // Handle dropping tail for other columns and insert + } + } + } else if (strcmp(format.type[i], "string") == 0) { + std::string str_val; + if (remaining >= 4) { + int str_len; + memcpy(&str_len, data_ptr, 4); + data_ptr += 4; + remaining -= 4; + + if (str_len > remaining) + str_len = remaining; + if (str_len > 0) + str_val = std::string(data_ptr, str_len); + + data_ptr += str_len; + remaining -= str_len; + } + + int typed_col_idx = buf.field_idx_to_typed_col_idx[i]; + buf.string_cols[typed_col_idx]->Append(str_val); + + } else { + // Default: treat as int + int val = 0; + if (remaining >= 4) { + memcpy(&val, data_ptr, 4); + data_ptr += 4; + remaining -= 4; + } + + int typed_col_idx = buf.field_idx_to_typed_col_idx[i]; + buf.int_cols[typed_col_idx]->Append(val); + } + } + auto t_append_data_end = std::chrono::high_resolution_clock::now(); + + // Add TsTxUtcNs column if event has frame/slot + if (buf.has_frame_slot) { + uint64_t timestamp_ns = std::chrono::system_clock::now().time_since_epoch().count(); + uint64_t gps_elapsed_ns; + uint64_t transmit_time_in_utc_ns; + auto t_time_calc_start = std::chrono::high_resolution_clock::now(); + + if (frame == -1 || slot == -1) { // nr_ue_decode_BCCH_DL_SCH sets frame and slot to -1 + transmit_time_in_utc_ns = timestamp_ns; + } else { + gps_elapsed_ns = calculate_sfn_slot_gps_time(frame, slot, 1, timestamp_ns); + transmit_time_in_utc_ns = gps_to_utc_ns(gps_elapsed_ns); + + if (0) { + int check_frame, check_slot; + calculate_sfn_slot_from_unix(transmit_time_in_utc_ns, 1, &check_frame, &check_slot); + if (check_frame != frame || check_slot != slot) { + loge("ERROR1: sfn/slot check failed: {} {} {} {}", event_name, frame, slot, check_frame, check_slot); + } + } + + auto t_time_calc_end = std::chrono::high_resolution_clock::now(); + + int64_t ref_to_t0_offset_ns = (int64_t)timestamp_ns - (int64_t)transmit_time_in_utc_ns; + // Handle sign separately to properly display negative fractional seconds + const char *sign = (ref_to_t0_offset_ns < 0) ? "-" : " "; + int64_t abs_offset = (ref_to_t0_offset_ns < 0) ? -ref_to_t0_offset_ns : ref_to_t0_offset_ns; + int64_t offset_sec = abs_offset / NS_PER_SEC; + int64_t offset_ns = abs_offset % NS_PER_SEC; + + if (abs_offset > 50'000'000) { // 50ms + logi("{:<31} {:4d}.{:2d} TsSwNs={}.{:09} TsTxUtcNs={}.{:09} delta={}{}.{:09d}, {}", + event_name, + frame, + slot, + timestamp_ns / NS_PER_SEC, + timestamp_ns % NS_PER_SEC, + transmit_time_in_utc_ns / NS_PER_SEC, + transmit_time_in_utc_ns % NS_PER_SEC, + sign, + offset_sec, + offset_ns, + DURATION_NS(t_time_calc_start, t_time_calc_end)); + } + } + + // Append to TsTxUtcNs column using cached pointer + buf.ts_tx_col->Append(transmit_time_in_utc_ns); + } + auto t_append_ts_end = std::chrono::high_resolution_clock::now(); + + // Increment row count + buf.row_count++; + + // Check if we should insert this buffer + int rows = 0; + auto t_insert_start = std::chrono::high_resolution_clock::now(); + uint8_t insert = should_insert(buf); + auto t_insert_should_insert_end = std::chrono::high_resolution_clock::now(); + if (insert) { + rows = insert_buffer(ch, event_id); + } + auto t_insert_end = std::chrono::high_resolution_clock::now(); + + if (insert) { + if (DURATION_MS(t_insert_start, t_insert_end) > 5) { + logi("Slow Insert: {:<31} {:4d}.{:2d}: {:3d} {:3d} {:5d} {:4d} {:5d} {:4d} {:8d} (ns) {:3d} (ms) rows:{:3d} reason: {}", + event_name, + frame, + slot, + DURATION_NS(t_fn_start, t_names_done), + DURATION_NS(t_names_done, t_append_start), + DURATION_NS(t_append_start, t_append_data_end), + DURATION_NS(t_append_data_end, t_append_ts_end), + buf.last_column_build_duration_ns, + buf.last_block_append_duration_ns, + buf.last_insertion_duration_ns, + DURATION_MS(t_insert_start, t_insert_end), + rows, + insert); + } + } else if (DURATION_US(t_fn_start, t_insert_end) > 50) { + logd("Slow saving data: {:<31} {:4d}.{:2d}: {:3d} {:3d} {:5d} {:4d} {:5d} {:4d} {:8d} (ns) buf_len:{:3d} rows:{:3d} ---", + event_name, + frame, + slot, + DURATION_NS(t_fn_start, t_names_done), + DURATION_NS(t_names_done, t_append_start), + DURATION_NS(t_append_start, t_append_data_end), + DURATION_NS(t_append_data_end, t_append_ts_end), + DURATION_NS(t_append_ts_end, t_insert_start), + DURATION_NS(t_insert_start, t_insert_should_insert_end), + DURATION_NS(t_insert_should_insert_end, t_insert_end), + buf_len, + buf.row_count); + } + + return 0; + } catch (const std::exception &e) { + loge("Failed to insert event {}: {}", event_name, e.what()); + return -1; + } +} + +int main(int n, char **v) +{ + const char *default_database_filename = "T_messages.txt"; + char *database_filename = NULL; + void *database; + const char *ip = DEFAULT_REMOTE_IP; + int port = DEFAULT_REMOTE_PORT; + char **on_off_name; + int *on_off_action; + int on_off_n = 0; + int *is_on; + int number_of_events; + int i; + char mt; + int debug_mode = 0; + + clickhouse_config_t ch_config; + ch_config.drop_tables = 0; + ch_config.host = DEFAULT_CLICKHOUSE_HOST; + ch_config.port = DEFAULT_CLICKHOUSE_PORT; + ch_config.database = DEFAULT_CLICKHOUSE_DB; + + /* write on a socket fails if the other end is closed and we get SIGPIPE */ + if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) + abort(); + + on_off_name = (char **)malloc(n * sizeof(char *)); + if (on_off_name == NULL) + abort(); + on_off_action = (int *)malloc(n * sizeof(int)); + if (on_off_action == NULL) + abort(); + + for (i = 1; i < n; i++) { + if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) + usage(); + if (!strcmp(v[i], "-d")) { + if (i > n - 2) + usage(); + database_filename = v[++i]; + continue; + } + if (!strcmp(v[i], "-ip")) { + if (i > n - 2) + usage(); + ip = v[++i]; + continue; + } + if (!strcmp(v[i], "-p")) { + if (i > n - 2) + usage(); + port = atoi(v[++i]); + continue; + } + if (!strcmp(v[i], "-ch-host")) { + if (i > n - 2) + usage(); + ch_config.host = v[++i]; + continue; + } + if (!strcmp(v[i], "-ch-port")) { + if (i > n - 2) + usage(); + ch_config.port = atoi(v[++i]); + continue; + } + if (!strcmp(v[i], "-ch-db")) { + if (i > n - 2) + usage(); + ch_config.database = v[++i]; + continue; + } + if (!strcmp(v[i], "-ch-user")) { + if (i > n - 2) + usage(); + ch_config.user = v[++i]; + continue; + } + if (!strcmp(v[i], "-ch-pass")) { + if (i > n - 2) + usage(); + ch_config.password = v[++i]; + continue; + } + if (!strcmp(v[i], "-ch-droptables")) { + ch_config.drop_tables = 1; + continue; + } + if (!strcmp(v[i], "-debug")) { + debug_mode = 1; + continue; + } + if (!strcmp(v[i], "-on")) { + if (i > n - 2) + usage(); + on_off_name[on_off_n] = v[++i]; + on_off_action[on_off_n++] = 1; + logi("on: item: {}, on_off_name: {}, on_off_action: {}", v[i], on_off_name[on_off_n - 1], on_off_action[on_off_n - 1]); + continue; + } + if (!strcmp(v[i], "-off")) { + if (i > n - 2) + usage(); + on_off_name[on_off_n] = v[++i]; + on_off_action[on_off_n++] = 0; + continue; + } + if (!strcmp(v[i], "-ON")) { + on_off_name[on_off_n] = NULL; + on_off_action[on_off_n++] = 1; + continue; + } + if (!strcmp(v[i], "-OFF")) { + on_off_name[on_off_n] = NULL; + on_off_action[on_off_n++] = 0; + continue; + } + usage(); + } + + if (database_filename == NULL) { + logi("No database file provided, using default: {}", default_database_filename); + database_filename = strdup(default_database_filename); + } + + database = parse_database(database_filename); + + load_config_file(database_filename); + + number_of_events = number_of_ids(database); + logi("Number of events: {}", number_of_events); + is_on = (int *)calloc(number_of_events, sizeof(int)); + if (is_on == NULL) { + loge("aborting"); + abort(); + } + + for (i = 0; i < on_off_n; i++) { + on_off(database, on_off_name[i], is_on, on_off_action[i]); + } + + /* Initialize fmtlog for benchmarking */ + fmtlog::setLogLevel(debug_mode ? fmtlog::DBG : fmtlog::INF); + fmtlog::setThreadName("main"); + + /* Initialize ClickHouse */ + if (clickhouse_init(&ch_config) != 0) { + loge("Failed to initialize ClickHouse connection"); + exit(1); + } + + /* Create tables for enabled events */ + int longest_table_name = create_tables(&ch_config, database, is_on, number_of_events); + if (longest_table_name < 0) { + loge("Failed to create tables"); + exit(1); + } + + socket_fd = connect_to(const_cast(ip), port); + + /* activate selected traces */ + mt = 1; + if (socket_send(socket_fd, &mt, 1) == -1 || socket_send(socket_fd, &number_of_events, sizeof(int)) == -1 + || socket_send(socket_fd, is_on, number_of_events * sizeof(int)) == -1) + abort(); + + /* exit on ctrl+c and ctrl+z */ + if (signal(SIGQUIT, force_stop) == SIG_ERR) + abort(); + if (signal(SIGINT, force_stop) == SIG_ERR) + abort(); + if (signal(SIGTSTP, force_stop) == SIG_ERR) + abort(); + + OBUF ebuf = {.osize = 0, .omaxsize = 0, .obuf = NULL}; + + /* read messages */ + logi("Tables created, waiting for messages..."); + int poll_count = 0; + auto last_periodic_insert = std::chrono::steady_clock::now(); + auto last_stats_print = std::chrono::steady_clock::now(); + const uint64_t STATS_PRINT_INTERVAL_MS = 5000; // Print stats every 5 seconds + + while (run) { + int type; + int32_t length; + char *v; + int vpos = 0; + + // Poll fmtlog periodically to insert buffered logs + if (++poll_count % 10 == 0) { + fmtlog::poll(); + } + + // Periodic insert check (every 10 messages) + if (poll_count % 10 == 0) { + auto now = std::chrono::steady_clock::now(); + auto elapsed_ms = + static_cast(std::chrono::duration_cast(now - last_periodic_insert).count()); + + if (elapsed_ms >= INSERT_INTERVAL_MS) { + for (auto &pair : g_event_buffers) { + if (should_insert(pair.second)) { + insert_buffer(&ch_config, pair.first); + } + } + last_periodic_insert = now; + } + if (static_cast(DURATION_MS(last_stats_print, now)) >= STATS_PRINT_INTERVAL_MS) { + for (auto &pair : g_event_buffers) { + EventBuffer &buf = pair.second; + if (buf.rows_since_print > 0) + logi(" {:<31} rows: {:8d} total: {:10d}", buf.event_name, buf.rows_since_print, buf.total_rows); + buf.rows_since_print = 0; + } + last_stats_print = now; + logi(""); + } + } + + if (fullread(socket_fd, &length, 4) == -1) + goto read_error; + if (ebuf.omaxsize < length + 4) { + ebuf.omaxsize = (length + 4 + 65535) & ~65535; + ebuf.obuf = (char *)realloc(ebuf.obuf, ebuf.omaxsize); + if (ebuf.obuf == NULL) { + loge("out of memory"); + exit(1); + } + } + v = ebuf.obuf; + memcpy(v + vpos, &length, 4); + vpos += 4; +#ifdef T_SEND_TIME + if (length < (int32_t)sizeof(struct timespec)) + goto read_error; + if (fullread(socket_fd, v + vpos, sizeof(struct timespec)) == -1) + goto read_error; + // memcpy(v+vpos, &ts, sizeof(struct timespec)); + vpos += sizeof(struct timespec); + length -= sizeof(struct timespec); +#endif + if (length < (int32_t)sizeof(int)) + goto read_error; + if (fullread(socket_fd, &type, sizeof(int)) == -1) + goto read_error; + memcpy(v + vpos, &type, sizeof(int)); + vpos += sizeof(int); + length -= sizeof(int); + if (fullread(socket_fd, v + vpos, length) == -1) + goto read_error; + + auto t_start = std::chrono::high_resolution_clock::now(); + + if (type == -1) { + append_received_config_chunk(v + vpos, length); + } else if (type == -2) { + verify_config(); + } else if (type >= 0 && type < number_of_events && is_on[type]) { + if (insert_event(&ch_config, database, type, v + vpos, length, t_start) != 0) { + loge("Failed to insert event type {}", type); + } + } + } + +read_error: + // Flush all remaining buffers before exit + logi("Inserting all buffers before exit..."); + insert_all_buffers(&ch_config); + + // Print final statistics + size_t total_rows = 0; + for (const auto& pair : g_event_buffers) { + total_rows += pair.second.row_count; + } + logi("Final buffer state: {} events with {} uninserted rows", + g_event_buffers.size(), total_rows); + + // Client cleanup is automatic via std::unique_ptr + logi("Exiting..."); + + // Flush and close fmtlog + fmtlog::poll(); + fmtlog::closeLogFile(); + + return 0; +} diff --git a/common/utils/actor/actor.h b/common/utils/actor/actor.h index 023533d2d7..8993916d39 100644 --- a/common/utils/actor/actor.h +++ b/common/utils/actor/actor.h @@ -29,7 +29,7 @@ #define SHUTDOWN_ACTOR(ptr) shutdown_actor((Actor_t *)ptr); -typedef struct Actor_t { +typedef struct { notifiedFIFO_t fifo; bool terminate; pthread_t thread; diff --git a/common/utils/actor/tests/test_actor.cpp b/common/utils/actor/tests/test_actor.cpp index 5f613846a2..a38046e5f8 100644 --- a/common/utils/actor/tests/test_actor.cpp +++ b/common/utils/actor/tests/test_actor.cpp @@ -93,7 +93,7 @@ TEST(DISABLED_actor, thread_safety_with_core_affinity) // Thread safety can be ensured through data separation, here using C inheritance-like // model -typedef struct TestActor_t { +typedef struct { Actor_t actor; int count; } TestActor_t; diff --git a/common/utils/barrier/barrier.h b/common/utils/barrier/barrier.h index e27b56e766..78fc36264d 100644 --- a/common/utils/barrier/barrier.h +++ b/common/utils/barrier/barrier.h @@ -27,7 +27,7 @@ typedef void (*callback_t)(void*); /// @brief This thread barrier allows modifying the maximum joins after it is initialized -typedef struct dynamic_barrier_t { +typedef struct { pthread_mutex_t barrier_lock; int completed_jobs; int max_joins; diff --git a/common/utils/ocp_itti/all_msg.h b/common/utils/ocp_itti/all_msg.h index 377bfc4343..8b74409a3c 100644 --- a/common/utils/ocp_itti/all_msg.h +++ b/common/utils/ocp_itti/all_msg.h @@ -14,4 +14,4 @@ #include "openair2/COMMON/f1ap_messages_def.h" #include "openair2/COMMON/e1ap_messages_def.h" #include "openair2/COMMON/ngap_messages_def.h" - +#include "openair2/COMMON/nrppa_messages_def.h" diff --git a/common/utils/ocp_itti/intertask_interface.h b/common/utils/ocp_itti/intertask_interface.h index d23e62365d..353a0bae5a 100644 --- a/common/utils/ocp_itti/intertask_interface.h +++ b/common/utils/ocp_itti/intertask_interface.h @@ -230,6 +230,7 @@ typedef struct IttiMsgText_s { #include #include #include +#include #include #include #include @@ -294,6 +295,7 @@ typedef struct { TASK_DEF(TASK_RAL_ENB, 200) \ TASK_DEF(TASK_S1AP, 200) \ TASK_DEF(TASK_NGAP, 200) \ + TASK_DEF(TASK_NRPPA, 200) \ TASK_DEF(TASK_X2AP, 200) \ TASK_DEF(TASK_M2AP_ENB, 200) \ TASK_DEF(TASK_M2AP_MCE, 200) \ diff --git a/doc/README.md b/doc/README.md index 8fc53eea24..13a9669f76 100644 --- a/doc/README.md +++ b/doc/README.md @@ -121,8 +121,9 @@ The other SDRs (AW2S, LimeSDR, ...) have no READMEs. ## Testing - [UnitTests.md](./UnitTests.md) explains the unit testing setup -- Component tests are under `tests/`. Currently, there is a simple CU-UP - tester, see the corresponding [README.md](../tests/nr-cuup/README.md). +- Component tests are under `tests/`. Currently, the following component tests are supported + - A simple CU-UP tester, see the corresponding [README.md](../tests/nr-cuup/README.md). + - A CU-NRPPA tester, see the corresponding [README.md](../tests/nr-cu-nrppa/README.md). - [TESTBenches.md](./TESTBenches.md) lists the CI setup and links to pipelines - The CI setup uses a [custom framework](../ci-scripts/README.md) to run end-to-end tests. diff --git a/doc/TESTBenches.md b/doc/TESTBenches.md index f91321012c..c48cdfe5d3 100644 --- a/doc/TESTBenches.md +++ b/doc/TESTBenches.md @@ -27,6 +27,7 @@ | groot | Groot | gNB (n77) | B210 (30AD30F) | | rocket | Rocket | gNB (n77) | B210 (31F8010) | | raspix | Raspix | COTS UE | Quectel RM520N | +| jetson1-oai | Jetson1-oai | nrUE | USRP B210 | > **Note:** The available resources, and their current usage, is indicated here: > - [Lockable resources of jenkins-oai](https://jenkins-oai.eurecom.fr/lockable-resources/): @@ -238,6 +239,10 @@ information on how the images are built. ~5G-NR - gracehopper1-oai - run channel simulation on CPU and GPU using test_channel_scalability +- [RAN-SA-AERIAL-OAIUE-CN5G](https://jenkins-oai.eurecom.fr/job/RAN-SA-AERIAL-OAIUE-CN5G/) + ~5G-NR ~nrUE + - 5G-NR SA test setup: OAI VNF + PNF/NVIDIA CUBB on gracehopper1-oai + WNC RU, OAIUE on jetson1-oai + B210, OAI CN5G + - OpenShift cluster for CN deployment and container images for gNB and UE deployment ### RAN-CI-NSA-Trigger diff --git a/doc/tutorial_resources/oai-cn5g/conf/config.yaml b/doc/tutorial_resources/oai-cn5g/conf/config.yaml index f18c965ed1..6e55c95bb3 100644 --- a/doc/tutorial_resources/oai-cn5g/conf/config.yaml +++ b/doc/tutorial_resources/oai-cn5g/conf/config.yaml @@ -100,6 +100,12 @@ nfs: port: 8080 api_version: v1 interface_name: eth0 + lmf: + host: oai-lmf + sbi: + port: 8080 + api_version: v1 + interface_name: eth0 #### Common for UDR and AMF database: @@ -220,6 +226,20 @@ upf: - dnn: "ims" - dnn: "default" +lmf: + http_threads_count: 8 + gnb_id_bits_count: 28 + num_gnb: 1 + trp_info_wait_ms: 500 + positioning_wait_ms: 500 + measurement_wait_ms: 500 + support_features: + request_trp_info: no + determine_num_gnb: yes + use_http2: yes + use_fqdn_dns: no + register_nrf: yes + ## DNN configuration dnns: - dnn: "oai" diff --git a/doc/tutorial_resources/oai-cn5g/docker-compose-positioning.yaml b/doc/tutorial_resources/oai-cn5g/docker-compose-positioning.yaml new file mode 100644 index 0000000000..6b75c22b6b --- /dev/null +++ b/doc/tutorial_resources/oai-cn5g/docker-compose-positioning.yaml @@ -0,0 +1,195 @@ +services: + mysql: + container_name: "mysql" + image: mysql:8.0 + volumes: + - ./database/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql + - ./healthscripts/mysql-healthcheck.sh:/tmp/mysql-healthcheck.sh + environment: + - TZ=Europe/Paris + - MYSQL_DATABASE=oai_db + - MYSQL_USER=test + - MYSQL_PASSWORD=test + - MYSQL_ROOT_PASSWORD=linux + healthcheck: + test: /bin/bash -c "/tmp/mysql-healthcheck.sh" + interval: 5s + timeout: 2s + retries: 10 + networks: + public_net: + ipv4_address: 192.168.70.131 + + ims: + container_name: "ims" + image: oaisoftwarealliance/ims:latest + volumes: + - ./conf/sip.conf:/etc/asterisk/sip.conf + - ./conf/users.conf:/etc/asterisk/users.conf + healthcheck: + test: /bin/bash -c "pgrep asterisk" + interval: 5s + timeout: 2s + retries: 10 + networks: + public_net: + ipv4_address: 192.168.70.139 + oai-udr: + container_name: "oai-udr" + image: oaisoftwarealliance/oai-udr:develop + expose: + - 80/tcp + - 8080/tcp + volumes: + - ./conf/config.yaml:/openair-udr/etc/config.yaml + environment: + - TZ=Europe/Paris + depends_on: + - mysql + - oai-nrf + networks: + public_net: + ipv4_address: 192.168.70.136 + oai-udm: + container_name: "oai-udm" + image: oaisoftwarealliance/oai-udm:develop + expose: + - 80/tcp + - 8080/tcp + volumes: + - ./conf/config.yaml:/openair-udm/etc/config.yaml + environment: + - TZ=Europe/Paris + depends_on: + - oai-udr + networks: + public_net: + ipv4_address: 192.168.70.137 + oai-ausf: + container_name: "oai-ausf" + image: oaisoftwarealliance/oai-ausf:develop + expose: + - 80/tcp + - 8080/tcp + volumes: + - ./conf/config.yaml:/openair-ausf/etc/config.yaml + environment: + - TZ=Europe/Paris + depends_on: + - oai-udm + networks: + public_net: + ipv4_address: 192.168.70.138 + oai-nrf: + container_name: "oai-nrf" + image: oaisoftwarealliance/oai-nrf:develop + expose: + - 80/tcp + - 8080/tcp + volumes: + - ./conf/config.yaml:/openair-nrf/etc/config.yaml + environment: + - TZ=Europe/Paris + networks: + public_net: + ipv4_address: 192.168.70.130 + oai-amf: + container_name: "oai-amf" + image: oaisoftwarealliance/oai-amf:develop + expose: + - 80/tcp + - 8080/tcp + - 38412/sctp + volumes: + - ./conf/config.yaml:/openair-amf/etc/config.yaml + environment: + - TZ=Europe/Paris + depends_on: + - mysql + - oai-nrf + - oai-ausf + networks: + public_net: + ipv4_address: 192.168.70.132 + oai-lmf: + container_name: "oai-lmf" + image: oaisoftwarealliance/oai-lmf:develop + #image: oai-lmf:psoElementwiseTdoAmeanVarTDoAfilter + expose: + - 80/tcp + - 8080/tcp + volumes: + - ./conf/config.yaml:/openair-lmf/etc/config.yaml + environment: + - TZ=Europe/Paris + depends_on: + - mysql + - oai-nrf + - oai-amf + networks: + public_net: + ipv4_address: 192.168.70.141 + oai-smf: + container_name: "oai-smf" + image: oaisoftwarealliance/oai-smf:develop + expose: + - 80/tcp + - 8080/tcp + - 8805/udp + volumes: + - ./conf/config.yaml:/openair-smf/etc/config.yaml + environment: + - TZ=Europe/Paris + depends_on: + - oai-nrf + - oai-amf + networks: + public_net: + ipv4_address: 192.168.70.133 + oai-upf: + container_name: "oai-upf" + image: oaisoftwarealliance/oai-upf:develop + expose: + - 2152/udp + - 8805/udp + volumes: + - ./conf/config.yaml:/openair-upf/etc/config.yaml + environment: + - TZ=Europe/Paris + depends_on: + - oai-nrf + - oai-smf + cap_add: + - NET_ADMIN + - SYS_ADMIN + cap_drop: + - ALL + privileged: true + networks: + public_net: + ipv4_address: 192.168.70.134 + oai-ext-dn: + privileged: true + init: true + container_name: oai-ext-dn + image: oaisoftwarealliance/trf-gen-cn5g:jammy + entrypoint: /bin/bash -c \ + "ip route add 10.0.0.0/16 via 192.168.70.134 dev eth0; ip route; sleep infinity" + command: ["/bin/bash", "-c", "trap : SIGTERM SIGINT; sleep infinity & wait"] + healthcheck: + test: /bin/bash -c "ip r | grep 10.0.0" + interval: 5s + timeout: 2s + retries: 10 + networks: + public_net: + ipv4_address: 192.168.70.135 +networks: + public_net: + driver: bridge + name: oai-cn5g-public-net + ipam: + config: + - subnet: 192.168.70.128/26 + driver_opts: + com.docker.network.bridge.name: "oai-cn5g" diff --git a/doc/tutorial_resources/positioning/InputData.json b/doc/tutorial_resources/positioning/InputData.json new file mode 100644 index 0000000000..0caebbabba --- /dev/null +++ b/doc/tutorial_resources/positioning/InputData.json @@ -0,0 +1,43 @@ +{ + "externalClientType": "VALUE_ADDED_SERVICES", + "amfId": "128:1:1", + "locationQoS": { + "hAccuracy": 1.5, + "vAccuracy": 1.5, + "verticalRequested": true, + "responseTime": "LOW_DELAY", + "lcsQosClass": "BEST_EFFORT" + }, + "supportedGADShapes": [ + "POINT", + "POINT_UNCERTAINTY_CIRCLE" + ], + "supi": "imsi-001010000000001", + "ncgi": { + "plmnId": { + "mcc": "001", + "mnc": "01" + }, + "nrCellId": "14680064", + "nid": "0" + }, + "priority": "HIGHEST_PRIORITY", + "velocityRequested": "VELOCITY_IS_NOT_REQUESTED", + "lcsServiceType": 127, + "ldrType": "UE_AVAILABLE", + "hgmlcCallBackURI": "198.168.70.129", + "ldrReference": "11", + "lirReference": "1", + "periodicEventInfo": { + "reportingAmount": 10, + "reportingInterval": 60 + }, + "reportingAccessTypes": [ + "NR", + "NON_3GPP_CONNECTED_TO_5GC" + ], + "ueConnectivityStates": { + "accessType": "3GPP_ACCESS", + "connectivitystate": "IDLE" + } +} diff --git a/docker/Dockerfile.base.ubuntu b/docker/Dockerfile.base.ubuntu index e13170d303..a51d99bcc5 100644 --- a/docker/Dockerfile.base.ubuntu +++ b/docker/Dockerfile.base.ubuntu @@ -51,6 +51,8 @@ RUN apt-get update && \ bison \ flex \ m4 \ + # libzstd-dev for ClickHouse C++ library + libzstd-dev \ # python3-pip for conf template generation python3-pip \ wget \ diff --git a/docker/Dockerfile.build.ubuntu b/docker/Dockerfile.build.ubuntu index 2fb391c9cf..b919a1aefc 100644 --- a/docker/Dockerfile.build.ubuntu +++ b/docker/Dockerfile.build.ubuntu @@ -52,6 +52,7 @@ RUN \ --cmake-opt -DOAI_VRTSIM_TAPS_CLIENT=ON \ --noavx512 \ --build-tool-opt -k10 \ + --cmake-opt -DT_RECORD_DB=ON \ --cmake-opt -DCMAKE_C_FLAGS="-Werror" --cmake-opt -DCMAKE_CXX_FLAGS="-Werror" $BUILD_OPTION && \ # Mainly to see if the sanitize option was perfectly executed echo "---- ldd on executables ----" && \ diff --git a/docker/Dockerfile.gNB.aerial.ubuntu b/docker/Dockerfile.gNB.aerial.ubuntu index 1e2b41a71d..ac59370b4d 100644 --- a/docker/Dockerfile.gNB.aerial.ubuntu +++ b/docker/Dockerfile.gNB.aerial.ubuntu @@ -56,13 +56,15 @@ RUN /bin/sh oaienv && \ cd cmake_targets && \ mkdir -p log && \ ./build_oai -c -w AERIAL --gNB --ninja --build-tool-opt -k10 \ - --cmake-opt -DCMAKE_C_FLAGS="-Werror" --cmake-opt -DCMAKE_CXX_FLAGS="-Werror" + --cmake-opt -DCMAKE_C_FLAGS="-Werror" --cmake-opt -DCMAKE_CXX_FLAGS="-Werror" \ + --cmake-opt -DT_RECORD_DB=ON #start from scratch for target executable FROM ${UBUNTU_IMAGE} AS oai-gnb-aerial ENV DEBIAN_FRONTEND=noninteractive ENV TZ=Europe +ENV PATH="/opt/oai-gnb/bin:$PATH" RUN apt-get update && \ apt-get upgrade --yes && \ @@ -85,17 +87,20 @@ RUN apt-get update && \ WORKDIR /opt/oai-gnb/bin COPY --from=ran-build \ - /oai-ran/cmake_targets/ran_build/build/nr-softmodem ./ + /oai-ran/cmake_targets/ran_build/build/nr-softmodem \ + /oai-ran/cmake_targets/ran_build/build/common/utils/T/tracer/record* \ + ./ + COPY ./docker/scripts/gnb_entrypoint.sh ./entrypoint.sh COPY --from=ran-build \ /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \ /oai-ran/cmake_targets/ran_build/build/libparams_yaml.so \ + /oai-ran/cmake_targets/ran_build/build/_deps*/fmtlog-build*/libfmtlog-shared*.so \ + /oai-ran/cmake_targets/ran_build/build/_deps*/clickhouse-cpp-build*/clickhouse/libclickhouse*.so \ /usr/local/lib/ -#copy files from nvIPC COPY --from=ran-build \ - /usr/local/lib/libfmtlog-shared.so \ /usr/local/lib/libnvlog.so \ /usr/local/lib/libnvipc.so \ /usr/local/lib/ @@ -113,5 +118,6 @@ WORKDIR /opt/oai-gnb COPY --from=ran-build /usr/local/bin/yq /usr/local/bin/yq COPY --from=ran-build /tini /tini +COPY --from=ran-build /oai-ran/common/utils/T/T_messages.txt ./ ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-gnb/bin/entrypoint.sh"] CMD ["/opt/oai-gnb/bin/nr-softmodem"] diff --git a/docker/Dockerfile.nrORU.fhi72.ubuntu b/docker/Dockerfile.nrORU.fhi72.ubuntu index 67d2fc2da9..637dd941c1 100644 --- a/docker/Dockerfile.nrORU.fhi72.ubuntu +++ b/docker/Dockerfile.nrORU.fhi72.ubuntu @@ -25,7 +25,6 @@ FROM ran-build-fhi72:latest AS ran-build #start from scratch for target executable FROM ${UBUNTU_IMAGE} AS oai-nr-oru -ARG BUILD_OPTION ENV DEBIAN_FRONTEND=noninteractive ENV TZ=Europe diff --git a/docker/Dockerfile.nrUE.ubuntu b/docker/Dockerfile.nrUE.ubuntu index 08c83899b7..c75acf3b41 100644 --- a/docker/Dockerfile.nrUE.ubuntu +++ b/docker/Dockerfile.nrUE.ubuntu @@ -36,6 +36,7 @@ FROM ${UBUNTU_IMAGE} AS oai-nr-ue ARG BUILD_OPTION ENV DEBIAN_FRONTEND=noninteractive ENV TZ=Europe/Paris +ENV PATH="/opt/oai-nr-ue/bin:$PATH" RUN apt-get update && \ apt-get upgrade --yes && \ @@ -66,6 +67,7 @@ RUN apt-get update && \ iperf3 \ iperf \ libyaml-cpp-dev \ + libzstd1 \ libnanomsg5 && \ # if the --sanitize option was used to build, additional packages are required /bin/bash -c 'if [[ "$BUILD_OPTION" = "--sanitize" ]]; then DEBIAN_FRONTEND=noninteractive apt-get install --yes \ @@ -77,6 +79,7 @@ RUN apt-get update && \ WORKDIR /opt/oai-nr-ue/bin COPY --from=nr-ue-build \ /oai-ran/cmake_targets/ran_build/build/nr-uesoftmodem \ + /oai-ran/cmake_targets/ran_build/build/common/utils/T/tracer/record* \ ./ COPY ./docker/scripts/nr_ue_entrypoint.sh ./entrypoint.sh @@ -93,10 +96,17 @@ COPY --from=nr-ue-build \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv_ciUE.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv_5Gue.so \ + /oai-ran/cmake_targets/ran_build/build/libnrscope.so \ + /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ /oai-ran/cmake_targets/ran_build/build/libparams_yaml.so \ /oai-ran/cmake_targets/ran_build/build/libvrtsim.so \ + # Wildcards so it doesn't fail if not present + /oai-ran/cmake_targets/ran_build/build/_deps*/fmtlog-build*/libfmtlog-shared*.so \ + /oai-ran/cmake_targets/ran_build/build/_deps*/clickhouse-cpp-build*/clickhouse/libclickhouse*.so \ /usr/local/lib/ +# /oai-ran/cmake_targets/ran_build/build/libimscope.so \ + # Now we are copying from builder-image the UHD files. COPY --from=nr-ue-base /usr/local/bin/uhd_find_devices /usr/local/bin COPY --from=nr-ue-base /usr/local/lib/libuhd.so.4.8.0 /usr/local/lib @@ -123,5 +133,6 @@ WORKDIR /opt/oai-nr-ue COPY --from=nr-ue-base /usr/local/bin/yq /usr/local/bin/yq COPY --from=nr-ue-base /tini /tini +COPY --from=nr-ue-build /oai-ran/common/utils/T/T_messages.txt ./ CMD ["/opt/oai-nr-ue/bin/nr-uesoftmodem"] ENTRYPOINT ["/tini", "-v", "--", "/opt/oai-nr-ue/bin/entrypoint.sh"] diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index c5c1dee427..5413108209 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -120,13 +120,7 @@ static void tx_func(processingData_L1tx_t *info) 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_bf_vendor_ext.value) { start_meas(&info->gNB->phy_proc_tx); - phy_procedures_gNB_TX(info->gNB, - &sched_response.DL_req, - &sched_response.TX_req, - &sched_response.UL_dci_req, - frame_tx, - slot_tx, - 1); + phy_procedures_gNB_TX(info->gNB, &sched_response.DL_req, &sched_response.TX_req, &sched_response.UL_dci_req, frame_tx,slot_tx); PHY_VARS_gNB *gNB = info->gNB; processingData_RU_t syncMsgRU; diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 88a8ff84c8..75814596d3 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -225,7 +225,7 @@ static void UE_synch(void *arg) { ret = sl_nr_slss_search(UE, &syncD->proc, SL_NR_SSB_REPETITION_IN_FRAMES); } else { nr_get_carrier_frequencies(UE, &dl_carrier, &ul_carrier); - ret = nr_initial_sync(&syncD->proc, UE, 2, IS_SA_MODE(get_softmodem_params()), syncD->gscnInfo, syncD->numGscn); + ret = nr_initial_sync(&syncD->proc, UE, 2, syncD->gscnInfo, syncD->numGscn); } if (ret.cell_detected) { @@ -486,12 +486,13 @@ static int handle_sync_req_from_mac(PHY_VARS_NR_UE *UE) UE->UE_scan_carrier = false; UE->target_Nid_cell = UE->synch_request.synch_req.target_Nid_cell; - const fapi_nr_ue_carrier_config_t *cfg = &UE->nrUE_config.carrier_config; + const fapi_nr_config_request_t *config = &UE->nrUE_config; + const fapi_nr_ue_carrier_config_t *cfg = &config->carrier_config; uint64_t dl_CarrierFreq = get_carrier_frequency(fp->N_RB_DL, fp->numerology_index, cfg->dl_frequency); uint64_t ul_CarrierFreq = get_carrier_frequency(fp->N_RB_UL, fp->numerology_index, cfg->uplink_frequency); if (dl_CarrierFreq != fp->dl_CarrierFreq || ul_CarrierFreq != fp->ul_CarrierFreq) { LOG_I(NR_PHY, - "[UE %d] RF frequency change: dl %lu->%lu Hz, ul %lu->%lu Hz (from dl_frequency=%u kHz, target_Nid_cell=%d)\n", + "[UE %d] SYNC REQ: RF frequency change: dl %lu->%lu Hz, ul %lu->%lu Hz (from dl_frequency=%u kHz, target_Nid_cell=%d)\n", UE->Mod_id, fp->dl_CarrierFreq, dl_CarrierFreq, @@ -505,6 +506,16 @@ static int handle_sync_req_from_mac(PHY_VARS_NR_UE *UE) init_symbol_rotation(fp); } + int ssb_start_subcarrier = nr_get_ssb_start_sc(fp->numerology_index, + config->ssb_table.ssb_offset_point_a, + config->ssb_table.ssb_subcarrier_offset, + fp->freq_range); + // SSB location can change during for ex: handover on the target cell + if (ssb_start_subcarrier != fp->ssb_start_subcarrier) { + fp->ssb_start_subcarrier = ssb_start_subcarrier; + LOG_I(NR_PHY, "SYNC REQ: SSB location changed:%d\n", fp->ssb_start_subcarrier); + } + // Apply Doppler based on NTN-Config for target cell if (UE->nrUE_config.ntn_config.is_targetcell) apply_ntn_timing_advance_and_doppler(UE, fp, -1); @@ -726,7 +737,6 @@ void *UE_thread(void *arg) PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *)arg; const NR_DL_FRAME_PARMS *fp = &UE->frame_parms; // int tx_enabled = 0; - c16_t *rxp[fp->nb_antennas_rx]; enum stream_status_e stream_status = STREAM_STATUS_UNSYNC; fapi_nr_config_request_t *cfg = &UE->nrUE_config; sl_nr_phy_config_request_t *sl_cfg = NULL; @@ -780,6 +790,7 @@ void *UE_thread(void *arg) readFrame(UE, &tmp, duration_rx_to_tx, true); } + c16_t *rxp[fp->nb_antennas_rx]; while (!oai_exit) { if (syncRunning) { notifiedFIFO_elt_t *res = pollNotifiedFIFO(&nf); diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 1631332e5e..df4088a87d 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -240,6 +240,13 @@ static void trigger_deregistration(int sig) } } +void *nrue_ru_start_thread(void *arg) +{ + (void)arg; + nrue_ru_start(); + return NULL; +} + int NB_UE_INST = 1; configmodule_interface_t *uniqCfg = NULL; nrLDPC_coding_interface_t nrLDPC_coding_interface = {0}; @@ -450,7 +457,11 @@ int main(int argc, char **argv) load_module_shlib("imscope_record", NULL, 0, PHY_vars_UE_g[0][0]); } - nrue_ru_start(); + // Launch a temporary high-priority thread to start the UE RU, ensuring radio library threads inherit this priority + pthread_t ru_start_thread; + threadCreate(&ru_start_thread, nrue_ru_start_thread, NULL, "ru_start_thread", -1, OAI_PRIORITY_RT_MAX); + int ret = pthread_join(ru_start_thread, NULL); + AssertFatal(ret == 0, "pthread_join error %d, errno %d (%s)\n", ret, errno, strerror(errno)); for (int inst = 0; inst < NB_UE_INST; inst++) { LOG_I(PHY,"Intializing UE Threads for instance %d ...\n", inst); diff --git a/nfapi/open-nFAPI/pnf/inc/pnf.h b/nfapi/open-nFAPI/pnf/inc/pnf.h index 2dc2ce9de6..380890e07d 100644 --- a/nfapi/open-nFAPI/pnf/inc/pnf.h +++ b/nfapi/open-nFAPI/pnf/inc/pnf.h @@ -20,20 +20,17 @@ #include "nfapi_pnf_interface.h" +typedef struct pnf_s { + nfapi_pnf_config_t _public; -struct pnf_t { - - nfapi_pnf_config_t _public; - - int p5_sock; + int p5_sock; uint8_t tx_message_buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE]; uint8_t sctp; uint8_t terminate; -}; - +} pnf_t; int pnf_connect(pnf_t *pnf); int pnf_message_pump(pnf_t *pnf); diff --git a/nfapi/open-nFAPI/pnf/inc/pnf_p7.h b/nfapi/open-nFAPI/pnf/inc/pnf_p7.h index 3040d9de09..3f6678fc65 100644 --- a/nfapi/open-nFAPI/pnf/inc/pnf_p7.h +++ b/nfapi/open-nFAPI/pnf/inc/pnf_p7.h @@ -80,12 +80,10 @@ typedef struct { } pnf_p7_rx_reassembly_queue_t; +typedef struct pnf_p7_s { + nfapi_pnf_p7_config_t _public; -struct pnf_p7_t { - - nfapi_pnf_p7_config_t _public; - - //private data + //private data int p7_sock; uint8_t terminate; @@ -138,7 +136,7 @@ struct pnf_p7_t { pnf_p7_stats_t stats; pnf_p7_nr_stats_t nr_stats; -}; +} pnf_p7_t; int pnf_p7_message_pump(pnf_p7_t* pnf_p7); int pnf_nr_p7_message_pump(pnf_p7_t* pnf_p7); diff --git a/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h b/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h index 306216a1d5..e4f863d7e2 100644 --- a/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h +++ b/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h @@ -31,8 +31,8 @@ extern "C" { #include #include "openair1/PHY/defs_gNB.h" -typedef struct pnf_t pnf_t; -typedef struct pnf_p7_t pnf_p7_t; +typedef struct pnf_s pnf_t; +typedef struct pnf_p7_s pnf_p7_t; /*! This enum is used to describe the states of the pnf */ diff --git a/nfapi/open-nFAPI/vnf/inc/vnf.h b/nfapi/open-nFAPI/vnf/inc/vnf.h index 39769314f4..98dd9df84d 100644 --- a/nfapi/open-nFAPI/vnf/inc/vnf.h +++ b/nfapi/open-nFAPI/vnf/inc/vnf.h @@ -20,19 +20,16 @@ #include "nfapi_vnf_interface.h" -struct vnf_t -{ +typedef struct vnf_s { + nfapi_vnf_config_t _public; - nfapi_vnf_config_t _public; - - uint8_t terminate; + uint8_t terminate; uint8_t sctp; uint8_t tx_message_buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE]; - uint16_t next_phy_id; - -}; + uint16_t next_phy_id; +} vnf_t; int vnf_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len); diff --git a/nfapi/open-nFAPI/vnf/inc/vnf_p7.h b/nfapi/open-nFAPI/vnf/inc/vnf_p7.h index 7e04d69b49..47fa6053f1 100644 --- a/nfapi/open-nFAPI/vnf/inc/vnf_p7.h +++ b/nfapi/open-nFAPI/vnf/inc/vnf_p7.h @@ -107,11 +107,10 @@ typedef struct nfapi_vnf_p7_connection_info { } nfapi_vnf_p7_connection_info_t; -struct vnf_p7_t{ +typedef struct vnf_p7_s { + nfapi_vnf_p7_config_t _public; - nfapi_vnf_p7_config_t _public; - - // private data + // private data uint8_t terminate; nfapi_vnf_p7_connection_info_t* p7_connections; int socket; @@ -119,8 +118,8 @@ struct vnf_p7_t{ uint32_t slot_start_time_hr; uint8_t* rx_message_buffer; // would this be better put in the p7 conenction info? uint16_t rx_message_buffer_size; - -}; + +} vnf_p7_t; uint32_t vnf_get_current_time_hr(void); diff --git a/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h b/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h index 3f326e841c..7ddc19010d 100644 --- a/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h +++ b/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h @@ -30,9 +30,8 @@ extern "C" { #endif -typedef struct vnf_t vnf_t; -typedef struct vnf_p7_t vnf_p7_t; - +typedef struct vnf_s vnf_t; +typedef struct vnf_p7_s vnf_p7_t; /*! The nfapi VNF phy configuration information */ diff --git a/openair1/PHY/CODING/nr_segmentation.c b/openair1/PHY/CODING/nr_segmentation.c index 57c21a5980..8312471b34 100644 --- a/openair1/PHY/CODING/nr_segmentation.c +++ b/openair1/PHY/CODING/nr_segmentation.c @@ -24,9 +24,9 @@ author: Hongzhi WANG (TCL) date: 12.09.2017 */ -#include "PHY/defs_nr_UE.h" -//#include "SCHED/extern.h" +#include "common/utils/LOG/log.h" +#include "openair1/PHY/CODING/coding_defs.h" //#define DEBUG_SEGMENTATION int32_t nr_segmentation(unsigned char *input_buffer, @@ -174,8 +174,6 @@ else return Kb; } - - #ifdef MAIN main() { diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index e137bf5b4c..19977b01e3 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -291,7 +291,7 @@ static void sl_ue_free(PHY_VARS_NR_UE *UE) } } -void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) +void term_nr_ue_signal(PHY_VARS_NR_UE *ue) { const NR_DL_FRAME_PARMS* fp = &ue->frame_parms; phy_term_nr_top(); diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index 66f766571d..0e39e19d9e 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -24,6 +24,7 @@ #include "common/utils/LOG/log.h" #include "executables/softmodem-common.h" #include "PHY/MODULATION/nr_modulation.h" +#include "PHY/nr_phy_common/inc/nr_phy_common.h" /// Subcarrier spacings in Hz indexed by numerology index static const uint32_t nr_subcarrier_spacing[MAX_NUM_SUBCARRIER_SPACING] = {15e3, 30e3, 60e3, 120e3, 240e3}; @@ -421,16 +422,11 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, fapi_nr_config_request_t* conf fp->samples_per_frame = 10 * fp->samples_per_subframe; fp->freq_range = get_freq_range_from_freq(fp->dl_CarrierFreq); - uint8_t sco = 0; - if (((fp->freq_range == FR1) && (config->ssb_table.ssb_subcarrier_offset < 24)) || - ((fp->freq_range == FR2) && (config->ssb_table.ssb_subcarrier_offset < 12))) { - if (fp->freq_range == FR1) - sco = config->ssb_table.ssb_subcarrier_offset>>config->ssb_config.scs_common; - else - sco = config->ssb_table.ssb_subcarrier_offset; - } + fp->ssb_start_subcarrier = nr_get_ssb_start_sc(config->ssb_config.scs_common, + config->ssb_table.ssb_offset_point_a, + config->ssb_table.ssb_subcarrier_offset, + fp->freq_range); - fp->ssb_start_subcarrier = (12 * config->ssb_table.ssb_offset_point_a + sco); set_Lmax(fp); fp->L_ssb = (((uint64_t) config->ssb_table.ssb_mask_list[0].ssb_mask)<<32) | config->ssb_table.ssb_mask_list[1].ssb_mask; diff --git a/openair1/PHY/INIT/nr_phy_init.h b/openair1/PHY/INIT/nr_phy_init.h index ec4a8de71b..ee3122e6e3 100644 --- a/openair1/PHY/INIT/nr_phy_init.h +++ b/openair1/PHY/INIT/nr_phy_init.h @@ -34,7 +34,7 @@ int nr_init_frame_parms_ue_sl(NR_DL_FRAME_PARMS *fp, int threequarter_fs, uint32_t ofdm_offset_divisor); int init_nr_ue_signal(PHY_VARS_NR_UE *ue,int nb_connected_eNB); -void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB); +void term_nr_ue_signal(PHY_VARS_NR_UE *ue); void init_nr_ue_transport(PHY_VARS_NR_UE *ue); void nr_dump_frame_parms(NR_DL_FRAME_PARMS *frame_parms); void phy_init_nr_gNB(PHY_VARS_gNB *gNB); diff --git a/openair1/PHY/LTE_ESTIMATION/lte_eNB_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_eNB_measurements.c index f1b26c8d4e..755c67435d 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_eNB_measurements.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_eNB_measurements.c @@ -87,12 +87,12 @@ void lte_eNB_I0_measurements(PHY_VARS_eNB *eNB, measurements->n0_power[aarx] = ((k1*signal_energy(&common_vars->rxdata[aarx][(frame_parms->samples_per_tti<<1) -frame_parms->ofdm_symbol_size], frame_parms->ofdm_symbol_size)) + k2*measurements->n0_power[aarx])>>10; //measurements->n0_power[aarx] = (measurements->n0_power[aarx]) * 12*frame_parms->N_RB_DL)/(frame_parms->ofdm_symbol_size); - measurements->n0_power_dB[aarx] = (unsigned short) dB_fixed(measurements->n0_power[aarx]); + measurements->n0_power_dB[aarx] = dB_fixed(measurements->n0_power[aarx]); measurements->n0_power_tot += measurements->n0_power[aarx]; } - measurements->n0_power_tot_dB = (unsigned short) dB_fixed(measurements->n0_power_tot); + measurements->n0_power_tot_dB = dB_fixed(measurements->n0_power_tot); measurements->n0_power_tot_dBm = measurements->n0_power_tot_dB - eNB->rx_total_gain_dB; // printf("n0_power %d\n",measurements->n0_power_tot_dB); @@ -183,14 +183,14 @@ void lte_eNB_srs_measurements(PHY_VARS_eNB *eNB, measurements->rx_spatial_power[srs_id][0][aarx]<<=1; // because of noise only in odd samples - measurements->rx_spatial_power_dB[srs_id][0][aarx] = (unsigned short) dB_fixed(measurements->rx_spatial_power[srs_id][0][aarx]); + measurements->rx_spatial_power_dB[srs_id][0][aarx] = dB_fixed(measurements->rx_spatial_power[srs_id][0][aarx]); measurements->wideband_cqi[srs_id][aarx] = measurements->rx_spatial_power[srs_id][0][aarx]; // measurements->rx_power[UE_id][aarx]/=frame_parms->nb_antennas_tx; - measurements->wideband_cqi_dB[srs_id][aarx] = (unsigned short) dB_fixed(measurements->wideband_cqi[srs_id][aarx]); + measurements->wideband_cqi_dB[srs_id][aarx] = dB_fixed(measurements->wideband_cqi[srs_id][aarx]); rx_power += measurements->wideband_cqi[srs_id][aarx]; // measurements->rx_avg_power_dB[UE_id] += measurements->rx_power_dB[UE_id][aarx]; } @@ -206,7 +206,7 @@ void lte_eNB_srs_measurements(PHY_VARS_eNB *eNB, measurements->wideband_cqi_tot[srs_id] = dB_fixed2(rx_power,2*measurements->n0_power_tot); // times 2 since we have noise only in the odd carriers of the srs comb - measurements->rx_rssi_dBm[srs_id] = (int32_t)dB_fixed(rx_power_avg_eNB[srs_id])-eNB->rx_total_gain_dB; + measurements->rx_rssi_dBm[srs_id] = dB_fixed(rx_power_avg_eNB[srs_id])-eNB->rx_total_gain_dB; diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c index 86af5fb81c..9abaeb789c 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c @@ -254,13 +254,13 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, // ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-64]*rxF_pss[-64])+((int32_t)rxF_pss[-63]*rxF_pss[-63])); // printf("pssm32 %d\n",ue->measurements.n0_power[aarx]); - ue->measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(ue->measurements.n0_power[aarx]/12); + ue->measurements.n0_power_dB[aarx] = dB_fixed(ue->measurements.n0_power[aarx]/12); ue->measurements.n0_power_tot /*+=*/ = ue->measurements.n0_power[aarx]; } //LOG_I(PHY,"Subframe %d RRC UE MEAS Noise Level %d \n", subframe, ue->measurements.n0_power_tot); - ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/(12*aarx)); + ue->measurements.n0_power_tot_dB = dB_fixed(ue->measurements.n0_power_tot/(12*aarx)); ue->measurements.n0_power_tot_dBm = ue->measurements.n0_power_tot_dB - ue->rx_total_gain_dB - dB_fixed(ue->frame_parms.ofdm_symbol_size); } else { LOG_E(PHY, "Not yet implemented: noise power calculation when prefix length == EXTENDED\n"); @@ -311,11 +311,11 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-66]*rxF_pss[-66])+((int32_t)rxF_pss[-65]*rxF_pss[-65])); // ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-64]*rxF_pss[-64])+((int32_t)rxF_pss[-63]*rxF_pss[-63])); // printf("pssm32 %d\n",ue->measurements.n0_power[aarx]); - ue->measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(ue->measurements.n0_power[aarx]/12); + ue->measurements.n0_power_dB[aarx] = dB_fixed(ue->measurements.n0_power[aarx]/12); ue->measurements.n0_power_tot /*+=*/ = ue->measurements.n0_power[aarx]; } - ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/(12*aarx)); + ue->measurements.n0_power_tot_dB = dB_fixed(ue->measurements.n0_power_tot/(12*aarx)); ue->measurements.n0_power_tot_dBm = ue->measurements.n0_power_tot_dB - ue->rx_total_gain_dB - dB_fixed(ue->frame_parms.ofdm_symbol_size); //LOG_I(PHY,"Subframe %d RRC UE MEAS Noise Level %d \n", subframe, ue->measurements.n0_power_tot); @@ -1034,7 +1034,7 @@ void lte_ue_measurements(PHY_VARS_UE *ue, if (ue->measurements.rx_spatial_power[eNB_id][aatx][aarx]<0) ue->measurements.rx_spatial_power[eNB_id][aatx][aarx] = 0; //ue->measurements.n0_power[aarx]; - ue->measurements.rx_spatial_power_dB[eNB_id][aatx][aarx] = (unsigned short) dB_fixed(ue->measurements.rx_spatial_power[eNB_id][aatx][aarx]); + ue->measurements.rx_spatial_power_dB[eNB_id][aatx][aarx] = dB_fixed(ue->measurements.rx_spatial_power[eNB_id][aatx][aarx]); if (aatx==0) ue->measurements.rx_power[eNB_id][aarx] = ue->measurements.rx_spatial_power[eNB_id][aatx][aarx]; @@ -1042,7 +1042,7 @@ void lte_ue_measurements(PHY_VARS_UE *ue, ue->measurements.rx_power[eNB_id][aarx] += ue->measurements.rx_spatial_power[eNB_id][aatx][aarx]; } //aatx - ue->measurements.rx_power_dB[eNB_id][aarx] = (unsigned short) dB_fixed(ue->measurements.rx_power[eNB_id][aarx]); + ue->measurements.rx_power_dB[eNB_id][aarx] = dB_fixed(ue->measurements.rx_power[eNB_id][aarx]); if (aarx==0) ue->measurements.rx_power_tot[eNB_id] = ue->measurements.rx_power[eNB_id][aarx]; @@ -1050,7 +1050,7 @@ void lte_ue_measurements(PHY_VARS_UE *ue, ue->measurements.rx_power_tot[eNB_id] += ue->measurements.rx_power[eNB_id][aarx]; } //aarx - ue->measurements.rx_power_tot_dB[eNB_id] = (unsigned short) dB_fixed(ue->measurements.rx_power_tot[eNB_id]); + ue->measurements.rx_power_tot_dB[eNB_id] = dB_fixed(ue->measurements.rx_power_tot[eNB_id]); } //eNB_id diff --git a/openair1/PHY/LTE_TRANSPORT/prach.c b/openair1/PHY/LTE_TRANSPORT/prach.c index 6cb2de68d2..e357825ac6 100644 --- a/openair1/PHY/LTE_TRANSPORT/prach.c +++ b/openair1/PHY/LTE_TRANSPORT/prach.c @@ -48,7 +48,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, uint16_t *max_preamble, uint16_t *max_preamble_energy, uint16_t *max_preamble_delay, - uint16_t *avg_preamble_energy, + int16_t *avg_preamble_energy, uint16_t Nf, uint8_t tdd_mapindex, uint8_t br_flag, @@ -639,7 +639,7 @@ void rx_prach(PHY_VARS_eNB *eNB, uint16_t *max_preamble, uint16_t *max_preamble_energy, uint16_t *max_preamble_delay, - uint16_t *avg_preamble_energy, + int16_t *avg_preamble_energy, uint16_t Nf, uint8_t tdd_mapindex, uint8_t br_flag) { diff --git a/openair1/PHY/LTE_TRANSPORT/transport_proto.h b/openair1/PHY/LTE_TRANSPORT/transport_proto.h index 9cf09d7b52..7fad5aa5db 100644 --- a/openair1/PHY/LTE_TRANSPORT/transport_proto.h +++ b/openair1/PHY/LTE_TRANSPORT/transport_proto.h @@ -593,7 +593,7 @@ void rx_prach(PHY_VARS_eNB *phy_vars_eNB,RU_t *ru, uint16_t *max_preamble, uint16_t *max_preamble_energy, uint16_t *max_preamble_delay, - uint16_t *avg_preamble_energy, + int16_t *avg_preamble_energy, uint16_t Nf, uint8_t tdd_mapindex, uint8_t br_flag ); diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index c534ed7eea..99cbf1c652 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -19,12 +19,10 @@ * contact@openairinterface.org */ -#include "PHY/defs_nr_UE.h" #include "PHY/defs_gNB.h" #include "PHY/defs_nr_common.h" #include "modulation_UE.h" #include "nr_modulation.h" -#include "PHY/LTE_ESTIMATION/lte_estimation.h" #include "PHY/NR_UE_ESTIMATION/nr_estimation.h" #include "PHY/nr_phy_common/inc/nr_phy_common.h" #include diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index b078d2be1c..45fe87e040 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -500,7 +500,6 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, float beta_dmrs_pusch = get_beta_dmrs(pusch_pdu->num_dmrs_cdm_grps_no_data, pusch_pdu->dmrs_config_type == pusch_dmrs_type2); int16_t dmrs_scaling = (1 / beta_dmrs_pusch) * (1 << 14); nr_pusch_dmrs_rx(fp->Ncp, - Ns, gold, pilot, (1000 + p), @@ -520,7 +519,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, "Num RBs not configured according to 3GPP 38.211 section 6.3.1.4. For PUSCH with transform precoding, num RBs " "cannot be multiple of any other primenumber other than 2,3,5\n"); AssertFatal(dmrs_seq != NULL, "DMRS low PAPR seq not found, check if DMRS sequences are generated"); - nr_pusch_lowpaprtype1_dmrs_rx(fp->Ncp, Ns, dmrs_seq, pilot, 1000, 0, nb_rb_pusch, 0, pusch_pdu->dmrs_config_type); + nr_pusch_lowpaprtype1_dmrs_rx(fp->Ncp, dmrs_seq, pilot, 1000, 0, nb_rb_pusch, 0, pusch_pdu->dmrs_config_type); #ifdef DEBUG_PUSCH printf("NR_UL_CHANNEL_EST: index %d, u %d,v %d\n", index, u, v); LOG_M("gNb_DMRS_SEQ.m", "gNb_DMRS_SEQ", dmrs_seq, 6 * nb_rb_pusch, 1, 1); @@ -725,8 +724,6 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, *ptrsReOffset, *nb_rb, rel15_ul->rnti, - nr_tti_rx, - symbol, frame_parms->ofdm_symbol_size, (int16_t *)&pusch_vars->rxdataF_comp[aarx][(symbol * nb_re_pusch)], gold, diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.h b/openair1/PHY/NR_REFSIG/dmrs_nr.h index 5f17478874..8e275568e3 100644 --- a/openair1/PHY/NR_REFSIG/dmrs_nr.h +++ b/openair1/PHY/NR_REFSIG/dmrs_nr.h @@ -33,24 +33,11 @@ #ifndef DMRS_NR_H #define DMRS_NR_H -#include "PHY/defs_nr_UE.h" #include "PHY/types.h" #include "PHY/NR_REFSIG/ss_pbch_nr.h" #include "PHY/NR_REFSIG/pss_nr.h" #include "PHY/NR_REFSIG/sss_nr.h" -/************** CODE GENERATION ***********************************/ - -/************** DEFINE ********************************************/ - - -/************* STRUCTURES *****************************************/ - - -/************** VARIABLES *****************************************/ - -/************** FUNCTION ******************************************/ - int pseudo_random_sequence(int M_PN, uint32_t *c, uint32_t cinit); void lte_gold_new(LTE_DL_FRAME_PARMS *frame_parms, uint32_t lte_gold_table[20][2][14], uint16_t Nid_cell); uint16_t get_dmrs_freq_idx_ul(uint16_t n, uint8_t k_prime, uint8_t delta, uint8_t dmrs_type); diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c index d06ce6d917..bb81bd5ad5 100644 --- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c +++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c @@ -64,7 +64,6 @@ static inline c16_t get_modulated(const uint32_t *gold_sequence, const int idx_g } int nr_pusch_dmrs_rx(nr_prefix_type_t Ncp, - unsigned int Ns, const uint32_t *nr_gold_pusch, c16_t *output, unsigned short p, @@ -108,7 +107,6 @@ int nr_pusch_dmrs_rx(nr_prefix_type_t Ncp, } int nr_pdsch_dmrs_rx(nr_prefix_type_t Ncp, - unsigned int Ns, const unsigned int *nr_gold_pdsch, c16_t *output, unsigned short p, @@ -213,7 +211,6 @@ void nr_gen_ref_conj_symbols(const uint32_t *in, uint32_t length, c16_t *output, } int nr_pusch_lowpaprtype1_dmrs_rx(nr_prefix_type_t Ncp, - unsigned int Ns, c16_t *dmrs_seq, c16_t *output, unsigned short p, diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h index e5a5e73229..87f12adc5a 100644 --- a/openair1/PHY/NR_REFSIG/nr_refsig.h +++ b/openair1/PHY/NR_REFSIG/nr_refsig.h @@ -36,7 +36,6 @@ uint32_t *nr_gold_csi_rs(int N_RB_DL, int symbols_per_slot, int slot, int symb, uint32_t *nr_gold_prs(int nid, int slot, int symbol); int nr_pdsch_dmrs_rx(nr_prefix_type_t Ncp, - unsigned int Ns, const unsigned int *nr_gold_pdsch, c16_t *output, unsigned short p, @@ -56,7 +55,6 @@ void nr_pbch_dmrs_rx(int dmrss, const unsigned int *nr_gold_pbch, c16_t *output, void nr_pdcch_dmrs_ref(const unsigned int *nr_gold_pdcch, c16_t *output, unsigned short nb_rb_corset); int nr_pusch_dmrs_rx(nr_prefix_type_t Ncp, - unsigned int Ns, const uint32_t *nr_gold_pusch, c16_t *output, unsigned short p, @@ -71,7 +69,6 @@ void nr_generate_modulation_table(void); extern simde__m128i byte2m128i[256]; int nr_pusch_lowpaprtype1_dmrs_rx(nr_prefix_type_t Ncp, - unsigned int Ns, c16_t *dmrs_seq, c16_t *output, unsigned short p, diff --git a/openair1/PHY/NR_REFSIG/pss_nr.h b/openair1/PHY/NR_REFSIG/pss_nr.h index 07ab520e90..15ae316d74 100644 --- a/openair1/PHY/NR_REFSIG/pss_nr.h +++ b/openair1/PHY/NR_REFSIG/pss_nr.h @@ -32,9 +32,8 @@ #ifndef PSS_NR_H #define PSS_NR_H -#include "PHY/defs_nr_UE.h" +#include "PHY/defs_nr_common.h" #include "PHY/types.h" - #include "PHY/NR_REFSIG/ss_pbch_nr.h" /************** CODE GENERATION ***********************************/ diff --git a/openair1/PHY/NR_REFSIG/ptrs_nr.c b/openair1/PHY/NR_REFSIG/ptrs_nr.c index f73a01a2d6..53cc36cb26 100644 --- a/openair1/PHY/NR_REFSIG/ptrs_nr.c +++ b/openair1/PHY/NR_REFSIG/ptrs_nr.c @@ -194,8 +194,6 @@ void nr_ptrs_cpe_estimation(uint8_t K_ptrs, uint8_t ptrsReOffset, uint16_t nb_rb, uint16_t rnti, - unsigned char Ns, - unsigned char symbol, uint16_t ofdm_symbol_size, int16_t *rxF_comp, const uint32_t *gold_seq, diff --git a/openair1/PHY/NR_REFSIG/ptrs_nr.h b/openair1/PHY/NR_REFSIG/ptrs_nr.h index 75f526dad5..68e5f503b7 100644 --- a/openair1/PHY/NR_REFSIG/ptrs_nr.h +++ b/openair1/PHY/NR_REFSIG/ptrs_nr.h @@ -33,20 +33,6 @@ #ifndef PTRS_NR_H #define PTRS_NR_H -#include "PHY/defs_nr_UE.h" - -/************** CODE GENERATION ***********************************/ - -/************** DEFINE ********************************************/ - - -/************* STRUCTURES *****************************************/ - - -/************** VARIABLES *****************************************/ - -/************** FUNCTION ******************************************/ - void set_ptrs_symb_idx(uint16_t *ptrs_symbols, uint8_t duration_in_symbols, uint8_t start_symbol, @@ -86,15 +72,13 @@ int8_t nr_ptrs_process_slot(uint16_t dmrsSymbPos, uint16_t ptrsSymbPos, int16_t *estPerSymb, uint16_t startSymbIdx, - uint16_t noSymb - ); + uint16_t noSymb); + /* general function to estimate common phase error based upon PTRS */ void nr_ptrs_cpe_estimation(uint8_t K_ptrs, uint8_t ptrsReOffset, uint16_t nb_rb, uint16_t rnti, - unsigned char Ns, - unsigned char symbol, uint16_t ofdm_symbol_size, int16_t *rxF_comp, const uint32_t *gold_seq, diff --git a/openair1/PHY/NR_REFSIG/sss_nr.h b/openair1/PHY/NR_REFSIG/sss_nr.h index 8175869205..5bb55ebe2f 100644 --- a/openair1/PHY/NR_REFSIG/sss_nr.h +++ b/openair1/PHY/NR_REFSIG/sss_nr.h @@ -33,9 +33,7 @@ #define SSS_NR_H #include "limits.h" -#include "PHY/defs_nr_UE.h" #include "PHY/types.h" - #include "pss_nr.h" /************** DEFINE ********************************************/ diff --git a/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h b/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h index 9ed101f247..845a2cd830 100644 --- a/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h +++ b/openair1/PHY/NR_REFSIG/ul_ref_seq_nr.h @@ -33,11 +33,8 @@ #ifndef LOWPAPR_SEQUENCES_NR_H #define LOWPAPR_SEQUENCES_NR_H -#include "PHY/defs_nr_UE.h" #include "PHY/types.h" - #include "PHY/NR_REFSIG/ss_pbch_nr.h" - #include "PHY/defs_nr_common.h" #include "PHY/defs_gNB.h" diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index 9018aabfde..24cf6b72b6 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -37,6 +37,7 @@ #include "PHY/NR_REFSIG/dmrs_nr.h" #include "PHY/NR_REFSIG/ptrs_nr.h" #include "common/utils/nr/nr_common.h" +#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" #include "executables/softmodem-common.h" #include "SCHED_NR/sched_nr.h" @@ -261,7 +262,6 @@ static inline int dmrs_case00(c16_t *output, const int amp, int sz, int start_sc, - int remaining_re, int dmrs_port, const int dmrs_Type, int symbol_sz, @@ -438,7 +438,6 @@ static inline int do_onelayer(NR_DL_FRAME_PARMS *frame_parms, amp, sz, start_sc, - remaining_re, dmrs_port, dmrs_Type, symbol_sz, @@ -772,7 +771,6 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC void nr_generate_pdsch(PHY_VARS_gNB *gNB, int n_dlsch, NR_gNB_DLSCH_t *dlsch_array, int frame, int slot) { - NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; time_stats_t *dlsch_encoding_stats = &gNB->dlsch_encoding_stats; time_stats_t *tinput = &gNB->tinput; time_stats_t *tprep = &gNB->tprep; @@ -831,7 +829,6 @@ void nr_generate_pdsch(PHY_VARS_gNB *gNB, int n_dlsch, NR_gNB_DLSCH_t *dlsch_arr dlsch_array, frame, slot, - frame_parms, output, tinput, tprep, diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h index 0a82b2c47f..09de55da74 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h @@ -42,7 +42,6 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, NR_gNB_DLSCH_t *dlsch_array, int frame, uint8_t slot, - NR_DL_FRAME_PARMS *frame_parms, unsigned char *output, time_stats_t *tinput, time_stats_t *tprep, diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index 8a73d7754a..b2e7772a36 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -106,7 +106,6 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, NR_gNB_DLSCH_t *dlsch_array, int frame, uint8_t slot, - NR_DL_FRAME_PARMS *frame_parms, unsigned char *output, time_stats_t *tinput, time_stats_t *tprep, diff --git a/openair1/PHY/NR_TRANSPORT/nr_prs.c b/openair1/PHY/NR_TRANSPORT/nr_prs.c index be1bd8adb8..207a94447d 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prs.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prs.c @@ -27,12 +27,7 @@ //#define DEBUG_PRS_MOD //#define DEBUG_PRS_MAP -int nr_generate_prs(int slot, - c16_t *txdataF, - int16_t amp, - prs_config_t *prs_cfg, - nfapi_nr_config_request_scf_t *config, - const NR_DL_FRAME_PARMS *frame_parms) +int nr_generate_prs(int slot, c16_t *txdataF, int16_t amp, prs_config_t *prs_cfg, const NR_DL_FRAME_PARMS *frame_parms) { int k_prime = 0, k = 0, idx; diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index 29ae5bb612..a38bf9b6bb 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -40,12 +40,7 @@ NR_gNB_PHY_STATS_t *get_phy_stats(PHY_VARS_gNB *gNB, uint16_t rnti); -int nr_generate_prs(int slot, - c16_t *txdataF, - int16_t amp, - prs_config_t *prs_cfg, - nfapi_nr_config_request_scf_t *config, - const NR_DL_FRAME_PARMS *frame_parms); +int nr_generate_prs(int slot, c16_t *txdataF, int16_t amp, prs_config_t *prs_cfg, const NR_DL_FRAME_PARMS *frame_parms); /*! \fn int nr_generate_pss @@ -224,7 +219,6 @@ void nr_fill_srs(PHY_VARS_gNB *gNB, int nr_get_srs_signal(PHY_VARS_gNB *gNB, c16_t **rxdataF, - frame_t frame, slot_t slot, nfapi_nr_srs_pdu_t *srs_pdu, nr_srs_info_t *nr_srs_info, diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index 61bdce06b2..aa3a6e5907 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -1177,7 +1177,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, uint64_t decodedPayload[nb_symbols]; memset(decodedPayload,0,sizeof(decodedPayload)); - uint8_t corr_dB; + int8_t corr_dB; int decoderState = 2; if (pucch2_levdB < gNB->measurements.n0_subband_power_avg_dB + (gNB->pucch0_thres / 10)) decoderState = 1; // assuming missed detection, only attempt to decode for polar case (with CRC) @@ -1372,67 +1372,3 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, uci_pdu->pduBitmap|=8; } } - -void nr_dump_uci_stats(FILE *fd,PHY_VARS_gNB *gNB,int frame) { - int strpos = 0; - char output[16384]; - - for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { - NR_gNB_PHY_STATS_t *stats = &gNB->phy_stats[i]; - if (!stats->active) - return; - NR_gNB_UCI_STATS_t *uci_stats = &stats->uci_stats; - if (uci_stats->pucch0_sr_trials > 0) - strpos += sprintf(output + strpos, - "UCI %d RNTI %x: pucch0_sr_trials %d, pucch0_n00 %d dB, pucch0_n01 %d dB, pucch0_sr_thres %d dB, current " - "pucch1_stat0 %d dB, current pucch1_stat1 %d dB, positive SR count %d\n", - i, - stats->rnti, - uci_stats->pucch0_sr_trials, - uci_stats->pucch0_n00, - uci_stats->pucch0_n01, - uci_stats->pucch0_sr_thres, - dB_fixed(uci_stats->current_pucch0_sr_stat0), - dB_fixed(uci_stats->current_pucch0_sr_stat1), - uci_stats->pucch0_positive_SR); - if (uci_stats->pucch01_trials > 0) - strpos += sprintf(output + strpos, - "UCI %d RNTI %x: pucch01_trials %d, pucch0_n00 %d dB, pucch0_n01 %d dB, pucch0_thres %d dB, current " - "pucch0_stat0 %d dB, current pucch1_stat1 %d dB, pucch01_DTX %d\n", - i, - stats->rnti, - uci_stats->pucch01_trials, - uci_stats->pucch0_n01, - uci_stats->pucch0_n01, - uci_stats->pucch0_thres, - dB_fixed(uci_stats->current_pucch0_stat0), - dB_fixed(uci_stats->current_pucch0_stat1), - uci_stats->pucch01_DTX); - - if (uci_stats->pucch02_trials > 0) - strpos += sprintf(output + strpos, - "UCI %d RNTI %x: pucch01_trials %d, pucch0_n00 %d dB, pucch0_n01 %d dB, pucch0_thres %d dB, current " - "pucch0_stat0 %d dB, current pucch0_stat1 %d dB, pucch01_DTX %d\n", - i, - stats->rnti, - uci_stats->pucch02_trials, - uci_stats->pucch0_n00, - uci_stats->pucch0_n01, - uci_stats->pucch0_thres, - dB_fixed(uci_stats->current_pucch0_stat0), - dB_fixed(uci_stats->current_pucch0_stat1), - uci_stats->pucch02_DTX); - - if (uci_stats->pucch2_trials > 0) - strpos += sprintf(output + strpos, - "UCI %d RNTI %x: pucch2_trials %d, pucch2_DTX %d\n", - i, - stats->rnti, - uci_stats->pucch2_trials, - uci_stats->pucch2_DTX); - } - if (fd) - fprintf(fd, "%s", output); - else - printf("%s", output); -} diff --git a/openair1/PHY/NR_TRANSPORT/srs_rx.c b/openair1/PHY/NR_TRANSPORT/srs_rx.c index 5d84c11c99..0637a8abce 100644 --- a/openair1/PHY/NR_TRANSPORT/srs_rx.c +++ b/openair1/PHY/NR_TRANSPORT/srs_rx.c @@ -75,7 +75,6 @@ void nr_fill_srs(PHY_VARS_gNB *gNB, frame_t frame, slot_t slot, nfapi_nr_srs_pdu int nr_get_srs_signal(PHY_VARS_gNB *gNB, c16_t **rxdataF, - frame_t frame, slot_t slot, nfapi_nr_srs_pdu_t *srs_pdu, nr_srs_info_t *nr_srs_info, diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c index a407282c1b..1568c9e68e 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c @@ -34,7 +34,6 @@ int nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, PHY_VARS_NR_UE *ue, - module_id_t gNB_id, const int estimateSz, struct complex16 dl_ch_estimates_time[][estimateSz], uint8_t frame, 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 8978527095..f0e53a1c04 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -1295,7 +1295,7 @@ void nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, float beta_dmrs_pdsch = get_beta_dmrs(dlsch->n_dmrs_cdm_groups, config_type == NFAPI_NR_DMRS_TYPE2); int16_t dmrs_scaling = (int16_t)((1 / beta_dmrs_pdsch) * (1 << 14)); const uint32_t *gold = nr_gold_pdsch(fp->N_RB_DL, fp->symbols_per_slot, dlsch->dlDmrsScramblingId, dlsch->nscid, slot, symbol); - nr_pdsch_dmrs_rx(fp->Ncp, slot, gold, pilot, 1000 + p, 0, nb_rb_pdsch + rb_offset, config_type, dmrs_scaling); + nr_pdsch_dmrs_rx(fp->Ncp, gold, pilot, 1000 + p, 0, nb_rb_pdsch + rb_offset, config_type, dmrs_scaling); delay_t delay = {0}; @@ -1380,8 +1380,7 @@ void nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, * 2) Interpolate PTRS estimated value in TD after all PTRS symbols * 3) Compensate signal with PTRS estimation for slot *********************************************************************/ -void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, - int nbRx, +void nr_pdsch_ptrs_processing(int nbRx, c16_t ptrs_phase_per_slot[][14], int32_t ptrs_re_per_slot[][14], uint32_t rx_size_symbol, @@ -1389,7 +1388,6 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, NR_DL_FRAME_PARMS *frame_parms, NR_DL_UE_HARQ_t *dlsch0_harq, NR_DL_UE_HARQ_t *dlsch1_harq, - uint8_t gNB_id, uint8_t nr_slot_rx, unsigned char symbol, uint16_t rnti, @@ -1478,8 +1476,6 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, *ptrsReOffset, *nb_rb, rnti, - nr_slot_rx, - symbol, frame_parms->ofdm_symbol_size, (int16_t *)(rxdataF_comp[0][aarx] + symbol * rx_size_symbol), gold, diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h index 4a67f2956e..78657510d0 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h @@ -94,7 +94,6 @@ void nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, int nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, PHY_VARS_NR_UE *ue, - module_id_t gNB_id, int estimateSz, struct complex16 dl_ch_estimates_time[][estimateSz], uint8_t frame, @@ -108,7 +107,6 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue, int32_t dl_ch_estimates[][pdsch_est_size]); uint32_t nr_ue_calculate_ssb_rsrp(const NR_DL_FRAME_PARMS *fp, - const UE_nr_rxtx_proc_t *proc, const c16_t rxdataF[][fp->samples_per_slot_wCP], int symbol_offset, int ssb_start_subcarrier); @@ -122,7 +120,7 @@ void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue, typedef struct { UE_nr_rxtx_proc_t proc; PHY_VARS_NR_UE *ue; - c16_t *rxdata[NB_ANTENNAS_RX]; + c16_t **rxdata; uint32_t rxdata_size; c16_t rxdata_ant[]; } nr_meas_task_args_t; @@ -139,8 +137,7 @@ void phy_adjust_gain_nr(PHY_VARS_NR_UE *ue, uint32_t rx_power_fil_dB, uint8_t gNB_id); -void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, - int nbRx, +void nr_pdsch_ptrs_processing(int nbRx, c16_t ptrs_phase_per_slot[][14], int32_t ptrs_re_per_slot[][14], uint32_t rx_size_symbol, @@ -148,7 +145,6 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, NR_DL_FRAME_PARMS *frame_parms, NR_DL_UE_HARQ_t *dlsch0_harq, NR_DL_UE_HARQ_t *dlsch1_harq, - uint8_t gNB_id, uint8_t nr_slot_rx, unsigned char symbol, uint16_t rnti, diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c index 8a59470cbf..5190bbf83d 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c @@ -73,7 +73,7 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue, cmax(frame_parms->nb_antennas_rx, 1), false); allocCast3D(rx_spatial_power_dB, - unsigned short, + short, ue->measurements.rx_spatial_power_dB, NUMBER_OF_CONNECTED_gNB_MAX, cmax(frame_parms->nb_antenna_ports_gNB, 1), @@ -81,32 +81,21 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue, false); // signal measurements - for (gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++){ - + for (gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) { ue->measurements.rx_power_tot[gNB_id] = 0; - - for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++){ - - ue->measurements.rx_power[gNB_id][aarx] = 0; - - for (aatx = 0; aatx < frame_parms->nb_antenna_ports_gNB; aatx++){ + for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { + int rx_power = 0; + for (aatx = 0; aatx < frame_parms->nb_antenna_ports_gNB; aatx++) { const int z = signal_energy_nodc((c16_t*)&dl_ch_estimates[gNB_id][ch_offset], number_rbs * NR_NB_SC_PER_RB); rx_spatial_power[gNB_id][aatx][aarx] = z; - if (rx_spatial_power[gNB_id][aatx][aarx] < 0) rx_spatial_power[gNB_id][aatx][aarx] = 0; - - rx_spatial_power_dB[gNB_id][aatx][aarx] = (unsigned short)dB_fixed(rx_spatial_power[gNB_id][aatx][aarx]); - ue->measurements.rx_power[gNB_id][aarx] += rx_spatial_power[gNB_id][aatx][aarx]; + rx_spatial_power_dB[gNB_id][aatx][aarx] = dB_fixed(rx_spatial_power[gNB_id][aatx][aarx]); + rx_power += rx_spatial_power[gNB_id][aatx][aarx]; } - - ue->measurements.rx_power_dB[gNB_id][aarx] = (unsigned short) dB_fixed(ue->measurements.rx_power[gNB_id][aarx]); - ue->measurements.rx_power_tot[gNB_id] += ue->measurements.rx_power[gNB_id][aarx]; - + ue->measurements.rx_power_tot[gNB_id] += rx_power; } - - ue->measurements.rx_power_tot_dB[gNB_id] = (unsigned short) dB_fixed(ue->measurements.rx_power_tot[gNB_id]); - + ue->measurements.rx_power_tot_dB[gNB_id] = dB_fixed(ue->measurements.rx_power_tot[gNB_id]); } // filter to remove jitter @@ -154,7 +143,6 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue, // This function calculates: // - SS reference signal received digital power in dB/RE uint32_t nr_ue_calculate_ssb_rsrp(const NR_DL_FRAME_PARMS *fp, - const UE_nr_rxtx_proc_t *proc, const c16_t rxdataF[][fp->samples_per_slot_wCP], int symbol_offset, int ssb_start_subcarrier) @@ -242,7 +230,7 @@ void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue, if (fp->half_frame_bit) symbol_offset += (fp->slots_per_frame >> 1) * fp->symbols_per_slot; - uint32_t rsrp_avg = nr_ue_calculate_ssb_rsrp(fp, proc, rxdataF, symbol_offset, fp->ssb_start_subcarrier); + uint32_t rsrp_avg = nr_ue_calculate_ssb_rsrp(fp, rxdataF, symbol_offset, fp->ssb_start_subcarrier); float rsrp_db_per_re = 10 * log10(rsrp_avg); openair0_config_t *cfg0 = &openair0_cfg[ue->rf_map.card]; @@ -489,7 +477,7 @@ void do_neighboring_cell_measurements(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *u } // RSRP measurements - neighboring_cell_info->ssb_rsrp = nr_ue_calculate_ssb_rsrp(frame_parms, proc, rxdataF, 0, frame_parms->ssb_start_subcarrier); + neighboring_cell_info->ssb_rsrp = nr_ue_calculate_ssb_rsrp(frame_parms, rxdataF, 0, frame_parms->ssb_start_subcarrier); neighboring_cell_info->ssb_rsrp_dBm = 10 * log10(neighboring_cell_info->ssb_rsrp) + 30 - SQ15_SQUARED_NORM_FACTOR_DB @@ -533,9 +521,9 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue, LOG_D(PHY, "In %s doing measurements for ssb_offset %d l_sss %d \n", __FUNCTION__, ssb_offset, l_sss); - for (aarx = 0; aarxframe_parms.nb_antennas_rx; aarx++) { + for (aarx = 0; aarx < ue->frame_parms.nb_antennas_rx; aarx++) { - ue->measurements.n0_power[aarx] = 0; + uint32_t n0_power = 0; rxF_sss = (int16_t *)&rxdataF[aarx][l_sss*ue->frame_parms.ofdm_symbol_size]; //-ve spectrum from SSS @@ -547,8 +535,7 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue, LOG_I(PHY, "In %s -rxF_sss %d %d\n", __FUNCTION__, rxF_sss[re*2], rxF_sss[re*2 + 1]); #endif - ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[re*2]*rxF_sss[re*2]) + ((int32_t)rxF_sss[re*2 + 1]*rxF_sss[re*2 + 1])); - + n0_power += (((int32_t)rxF_sss[re * 2] * rxF_sss[re * 2]) + ((int32_t)rxF_sss[re * 2 + 1] * rxF_sss[re * 2 + 1])); } //+ve spectrum from SSS @@ -560,17 +547,14 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue, LOG_I(PHY, "In %s +rxF_sss %d %d\n", __FUNCTION__, rxF_sss[re*2], rxF_sss[re*2 + 1]); #endif - ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[re*2]*rxF_sss[re*2]) + ((int32_t)rxF_sss[re*2 + 1]*rxF_sss[re*2 + 1])); - + n0_power += (((int32_t)rxF_sss[re * 2]*rxF_sss[re * 2]) + ((int32_t)rxF_sss[re * 2 + 1] * rxF_sss[re * 2 + 1])); } - ue->measurements.n0_power[aarx] /= 2*k_length; - ue->measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(ue->measurements.n0_power[aarx]); - ue->measurements.n0_power_tot += ue->measurements.n0_power[aarx]; - + n0_power /= 2 * k_length; + ue->measurements.n0_power_tot += n0_power; } - ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot); + ue->measurements.n0_power_tot_dB = dB_fixed(ue->measurements.n0_power_tot); #ifdef DEBUG_MEAS_RRC const int psd_awgn = -174; diff --git a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c index d8604d4570..3004728091 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c +++ b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c @@ -581,7 +581,7 @@ int nr_csi_rs_pmi_estimation(const PHY_VARS_NR_UE *ue, const int16_t log2_re, uint8_t *i1, uint8_t *i2, - uint32_t *precoded_sinr_dB) + int32_t *precoded_sinr_dB) { const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; @@ -730,7 +730,6 @@ int nr_csi_rs_cqi_estimation(const uint32_t precoded_sinr, } static void nr_csi_im_power_estimation(const PHY_VARS_NR_UE *ue, - const UE_nr_rxtx_proc_t *proc, const fapi_nr_dl_config_csiim_pdu_rel15_t *csiim_config_pdu, uint32_t *interference_plus_noise_power, const c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) @@ -822,7 +821,7 @@ void nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue, LOG_I(NR_PHY, "csiim_config_pdu->l_csiim = %i.%i.%i.%i\n", csiim_config_pdu->l_csiim[0], csiim_config_pdu->l_csiim[1], csiim_config_pdu->l_csiim[2], csiim_config_pdu->l_csiim[3]); #endif - nr_csi_im_power_estimation(ue, proc, csiim_config_pdu, &ue->nr_csi_info->interference_plus_noise_power, rxdataF); + nr_csi_im_power_estimation(ue, csiim_config_pdu, &ue->nr_csi_info->interference_plus_noise_power, rxdataF); ue->nr_csi_info->csi_im_meas_computed = true; } @@ -948,7 +947,7 @@ void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, uint8_t i1[3] = {0}; uint8_t i2[1] = {0}; uint8_t cqi = 0; - uint32_t precoded_sinr_dB = 0; + int32_t precoded_sinr_dB = 0; // bit 3 in bitmap to indicate RI measurment if (csirs_config_pdu->measurement_bitmap & 8) { nr_csi_rs_pmi_estimation(ue, diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index b5f26266e5..65a0247046 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -324,7 +324,6 @@ static void nr_pdcch_detection_mrc(int nb_ant, int sz, c16_t rxdataF_comp[][sz]) 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, @@ -430,12 +429,6 @@ int get_max_pdcch_monOcc(const NR_UE_PDCCH_CONFIG *phy_pdcch_config) 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 @@ -478,7 +471,6 @@ void nr_pdcch_generate_llr(PHY_VARS_NR_UE *ue, nr_rx_pdcch_symbol(ue, proc, symbol, - rel_symb_monOcc, ss_idx, phy_data, llr_size_symbol, @@ -489,64 +481,6 @@ void nr_pdcch_generate_llr(PHY_VARS_NR_UE *ue, } } -/* 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); - const int llr_stride = llr_size / rel15->coreset.duration; - int n_rb, cset_start; - get_coreset_rballoc(rel15->coreset.frequency_domain_resource, &n_rb, &cset_start); - - 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, - llr_stride); - - 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, uint16_t scrambling_RNTI, uint32_t length, @@ -566,8 +500,7 @@ static void nr_pdcch_unscrambling(c16_t *e_rx, } } -static void nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue, - const UE_nr_rxtx_proc_t *proc, +static void nr_dci_decoding_procedure(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) @@ -659,3 +592,61 @@ static void nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue, e_rx_cand_idx += RE_PER_RB_OUT_DMRS * L * 6; // e_rx index for next candidate (L CCEs, 6 REGs per CCE and 9 REs per REG ) } } + +/* 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); + const int llr_stride = llr_size / rel15->coreset.duration; + int n_rb, cset_start; + get_coreset_rballoc(rel15->coreset.frequency_domain_resource, &n_rb, &cset_start); + + 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, + llr_stride); + + nr_dci_decoding_procedure(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; +} diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 73bcbfab46..b46d89943c 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -60,7 +60,6 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol, c16_t dl_ch_magb[][n_rx][rx_size_symbol], c16_t dl_ch_magr[][n_rx][rx_size_symbol], int32_t dl_ch_estimates_ext[][rx_size_symbol], - unsigned short nb_rb, unsigned char mod_order, int shift, unsigned char symbol, @@ -86,7 +85,6 @@ static void nr_dlsch_llr(uint32_t rx_size_symbol, c16_t dl_ch_mag[rx_size_symbol], c16_t dl_ch_magb[rx_size_symbol], c16_t dl_ch_magr[rx_size_symbol], - NR_DL_UE_HARQ_t *dlsch0_harq, NR_DL_UE_HARQ_t *dlsch1_harq, unsigned char symbol, uint32_t len, @@ -141,7 +139,6 @@ static void nr_dlsch_channel_level_median(uint32_t rx_size_symbol, @param rho Cross-correlation between two spatial channels on each RX antenna @param frame_parms Pointer to frame descriptor @param symbol Symbol on which to operate - @param first_symbol_flag set to 1 on first DLSCH symbol @param mod_order Modulation order of allocation @param nb_rb Number of RBs in allocation @param output_shift Rescaling for compensated output (should be energy-normalizing) @@ -161,7 +158,6 @@ static void nr_dlsch_channel_compensation(uint32_t rx_size_symbol, uint8_t n_layers, unsigned char symbol, int length, - bool first_symbol_flag, unsigned char mod_order, unsigned short nb_rb, unsigned char output_shift, @@ -555,7 +551,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, nl, symbol, nb_re_pdsch, - first_symbol_flag, dlsch_config->qamModOrder, nb_rb_pdsch, *log2_maxh, @@ -614,7 +609,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, dl_ch_magb, dl_ch_magr, dl_ch_estimates_ext, - nb_rb_pdsch, dlsch_config->qamModOrder, *log2_maxh, symbol, @@ -649,8 +643,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, /* Check for PTRS bitmap and process it respectively */ if((pduBitmap & 0x1) && (dlsch[0].rnti_type == TYPE_C_RNTI_)) { - nr_pdsch_ptrs_processing(ue, - nbRx, + nr_pdsch_ptrs_processing(nbRx, ptrs_phase_per_slot, ptrs_re_per_slot, rx_size_symbol, @@ -658,7 +651,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, fp, dlsch0_harq, dlsch1_harq, - gNB_id, nr_slot_rx, symbol, dlsch[0].rnti, @@ -674,7 +666,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, dl_ch_mag[0][0], dl_ch_magb[0][0], dl_ch_magr[0][0], - dlsch0_harq, dlsch1_harq, symbol, dl_valid_re[symbol], @@ -769,7 +760,6 @@ static void nr_dlsch_channel_compensation(uint32_t rx_size_symbol, uint8_t n_layers, unsigned char symbol, int length, - bool first_symbol_flag, unsigned char mod_order, unsigned short nb_rb, unsigned char output_shift, @@ -868,24 +858,11 @@ static void nr_dlsch_channel_compensation(uint32_t rx_size_symbol, for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { for (int l = 0; l < n_layers; l++) { for (int atx = 0; atx < n_layers; atx++) { - rho128 = (simde__m128i *)&rho[aarx][l * n_layers + atx][symbol * nb_rb * 12]; - dl_ch128 = (simde__m128i *)dl_ch_estimates_ext[l * frame_parms->nb_antennas_rx + aarx]; - dl_ch128_2 = (simde__m128i *)dl_ch_estimates_ext[atx * frame_parms->nb_antennas_rx + aarx]; - - // multiply by conjugated channel - mult_cpx_conj_vector((c16_t *)dl_ch128, (c16_t *)dl_ch128_2, (c16_t *)rho128, 12 * nb_rb_0, output_shift); - - if (first_symbol_flag) { - // rho_nm = H_arx_n.conj(H_arx_m) - // rho_rx_corr[arx][nm] = |H_arx_n|^2.|H_arx_m|^2 &rho[aarx][l*n_layers+atx][symbol*nb_rb*12] - measurements->rx_correlation[0][aarx][l * n_layers + atx] = - signal_energy(&rho[aarx][l * n_layers + atx][symbol * nb_rb * 12], length); - // avg_rho_re[aarx][l*n_layers+atx] = 16*avg_rho_re[aarx][l*n_layers+atx]/length; - // avg_rho_im[aarx][l*n_layers+atx] = 16*avg_rho_im[aarx][l*n_layers+atx]/length; - // printf("rho[rx]%d tx%d tx%d = Re: %d Im: %d\n",aarx, l,atx, avg_rho_re[aarx][l*n_layers+atx], - // avg_rho_im[aarx][l*n_layers+atx]); printf("rho_corr[rx]%d tx%d tx%d = %d ...\n",aarx, l,atx, - // measurements->rx_correlation[0][aarx][l*n_layers+atx]); - } + rho128 = (simde__m128i *)&rho[aarx][l * n_layers + atx][symbol * nb_rb * 12]; + dl_ch128 = (simde__m128i *)dl_ch_estimates_ext[l * frame_parms->nb_antennas_rx + aarx]; + dl_ch128_2 = (simde__m128i *)dl_ch_estimates_ext[atx * frame_parms->nb_antennas_rx + aarx]; + // multiply by conjugated channel + mult_cpx_conj_vector((c16_t *)dl_ch128, (c16_t *)dl_ch128_2, (c16_t *)rho128, 12 * nb_rb_0, output_shift); } } } @@ -1364,7 +1341,6 @@ static void nr_dlsch_mmse(uint32_t rx_size_symbol, c16_t dl_ch_magb[][n_rx][rx_size_symbol], c16_t dl_ch_magr[][n_rx][rx_size_symbol], int32_t dl_ch_estimates_ext[][rx_size_symbol], - unsigned short nb_rb, unsigned char mod_order, int shift, unsigned char symbol, @@ -1556,7 +1532,6 @@ static void nr_dlsch_llr(uint32_t rx_size_symbol, c16_t dl_ch_mag[rx_size_symbol], c16_t dl_ch_magb[rx_size_symbol], c16_t dl_ch_magr[rx_size_symbol], - NR_DL_UE_HARQ_t *dlsch0_harq, NR_DL_UE_HARQ_t *dlsch1_harq, unsigned char symbol, uint32_t len, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 9d2db73e66..31566fd3fd 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -374,7 +374,7 @@ void nr_scan_ssb(void *arg) &ssbInfo->pbchResult, rxdataF); // start pbch detection at first symbol after pss if (ssbInfo->syncRes.cell_detected) { - uint32_t rsrp_avg = nr_ue_calculate_ssb_rsrp(ssbInfo->fp, ssbInfo->proc, rxdataF, 0, ssbInfo->gscnInfo.ssbFirstSC); + uint32_t rsrp_avg = nr_ue_calculate_ssb_rsrp(ssbInfo->fp, rxdataF, 0, ssbInfo->gscnInfo.ssbFirstSC); int rsrp_db_per_re = 10 * log10(rsrp_avg); ssbInfo->adjust_rxgain = TARGET_RX_POWER - rsrp_db_per_re; LOG_I(PHY, "pbch rx ok. rsrp:%d dB/RE, adjust_rxgain:%d dB\n", rsrp_db_per_re, ssbInfo->adjust_rxgain); @@ -388,7 +388,6 @@ void nr_scan_ssb(void *arg) nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int n_frames, - int sa, nr_gscn_info_t gscnInfo[MAX_GSCN_BAND], int numGscn) { diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c index 321281fcda..e407459bc8 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync_sl.c @@ -151,7 +151,6 @@ static int sl_nr_pss_correlation(PHY_VARS_NR_UE *UE, int frame_index) } static void sl_nr_extract_sss(PHY_VARS_NR_UE *ue, - UE_nr_rxtx_proc_t *proc, int32_t *tot_metric, uint8_t *phase_max, c16_t rxdataF[][ue->SL_UE_PHY_PARAMS.sl_frame_params.samples_per_slot_wCP]) @@ -440,7 +439,7 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc, UE->common_vars.rxdata); } - sl_nr_extract_sss(UE, NULL, &metric_tdd_ncp, &phase_tdd_ncp, rxdataF); + sl_nr_extract_sss(UE, &metric_tdd_ncp, &phase_tdd_ncp, rxdataF); // save detected cell id to psbch rx_slss_id = UE->SL_UE_PHY_PARAMS.sync_params.N_sl_id; @@ -510,7 +509,7 @@ nr_initial_sync_t sl_nr_slss_search(PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc, sl_nr_rx_indication_t rx_ind = {0}; uint16_t number_pdus = 1; nr_fill_sl_indication(&sl_indication, &rx_ind, NULL, proc, UE, NULL); - nr_fill_sl_rx_indication(&rx_ind, SL_NR_RX_PDU_TYPE_SSB, UE, number_pdus, proc, (void *)decoded_output, rx_slss_id); + nr_fill_sl_rx_indication(&rx_ind, SL_NR_RX_PDU_TYPE_SSB, UE, number_pdus, (void *)decoded_output, rx_slss_id); LOG_D(PHY, "Sidelink SLSS SEARCH PSBCH RX OK. Send SL-SSB TO MAC\n"); 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 3daaaf0eee..6872306dfe 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -126,8 +126,7 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, const uint8_t slot, unsigned int *G, int nb_ulsch, - uint8_t *ULSCH_ids, - uint16_t number_dmrs_symbols); + uint8_t *ULSCH_ids); /*! \brief Perform PUSCH scrambling. TS 38.211 V15.4.0 subclause 6.3.1.1 @param[in] in Pointer to input bits @@ -242,7 +241,6 @@ double nr_ue_pbch_freq_offset(const NR_DL_FRAME_PARMS *frame_parms, nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *phy_vars_ue, int n_frames, - int sa, nr_gscn_info_t gscnInfo[MAX_GSCN_BAND], int numGscn); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index 852e87c071..4b769a8668 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -159,8 +159,7 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue, const uint8_t slot, unsigned int *G, int nb_ulsch, - uint8_t *ULSCH_ids, - uint16_t number_dmrs_symbols) + uint8_t *ULSCH_ids) { start_meas_nr_ue_phy(ue, ULSCH_ENCODING_STATS); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 94ee8022a8..881ce016bc 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -435,8 +435,7 @@ static void map_current_symbol(const nr_phy_pxsch_params_t p, /* TS 38.211 table 6.4.1.1.3-1 and 2 */ -static void dmrs_amp_mult(const uint32_t dmrs_port, - const int Wt, +static void dmrs_amp_mult(const int Wt, const int Wf[2], const c16_t *mod_dmrs, c16_t *mod_dmrs_out, @@ -493,9 +492,9 @@ static void map_symbols(const nr_phy_pxsch_params_t p, c16_t mod_dmrs[ALNARS_16_4(n_dmrs)] __attribute((aligned(16))); if (p.transform_precoding == transformPrecoder_disabled) { nr_modulation(gold, n_dmrs * 2, DMRS_MOD_ORDER, (int16_t *)mod_dmrs); - dmrs_amp_mult(p.dmrs_port, p.Wt, p.Wf, mod_dmrs, mod_dmrs_amp, n_dmrs, p.dmrs_type, p.num_cdm_no_data); + dmrs_amp_mult(p.Wt, p.Wf, mod_dmrs, mod_dmrs_amp, n_dmrs, p.dmrs_type, p.num_cdm_no_data); } else { - dmrs_amp_mult(p.dmrs_port, p.Wt, p.Wf, dmrs_seq, mod_dmrs_amp, n_dmrs, p.dmrs_type, p.num_cdm_no_data); + dmrs_amp_mult(p.Wt, p.Wf, dmrs_seq, mod_dmrs_amp, n_dmrs, p.dmrs_type, p.num_cdm_no_data); } } else if ((p.pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) && ptrs_symbol) { AssertFatal(p.transform_precoding == transformPrecoder_disabled, "PTRS NOT SUPPORTED IF TRANSFORM PRECODING IS ENABLED\n"); @@ -1190,7 +1189,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, rm_info = calc_rate_match_info_uci(pusch_pdu, harq_process_ul_ue, nl_qm, &G[pusch_id]); } - if (nr_ulsch_encoding(UE, &phy_data->ulsch, frame, slot, G, 1, ULSCH_ids, number_dmrs_symbols) == -1) { + if (nr_ulsch_encoding(UE, &phy_data->ulsch, frame, slot, G, 1, ULSCH_ids) == -1) { stop_meas_nr_ue_phy(UE, PUSCH_PROC_STATS); return; } diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c index 51285edd0b..5f54b916b1 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c @@ -52,8 +52,7 @@ //#define ONE_OVER_SQRT2 23170 // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2) //#define POLAR_CODING_DEBUG -void nr_generate_pucch0(const PHY_VARS_NR_UE *ue, - c16_t **txdataF, +void nr_generate_pucch0(c16_t **txdataF, const NR_DL_FRAME_PARMS *frame_parms, const int16_t amp16, const int nr_slot_tx, @@ -156,8 +155,7 @@ void nr_generate_pucch0(const PHY_VARS_NR_UE *ue, } } -void nr_generate_pucch1(const PHY_VARS_NR_UE *ue, - c16_t **txdataF, +void nr_generate_pucch1(c16_t **txdataF, const NR_DL_FRAME_PARMS *frame_parms, const int16_t amp16, const int nr_slot_tx, @@ -752,8 +750,7 @@ void nr_uci_encoding(uint64_t payload, uint8_t nr_bit, uint8_t nrofPRB, bool uci } } //#if 0 -void nr_generate_pucch2(const PHY_VARS_NR_UE *ue, - c16_t **txdataF, +void nr_generate_pucch2(c16_t **txdataF, const NR_DL_FRAME_PARMS *frame_parms, const int16_t amp16, const int nr_slot_tx, @@ -937,8 +934,7 @@ void nr_generate_pucch2(const PHY_VARS_NR_UE *ue, } } //#if 0 -void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue, - c16_t **txdataF, +void nr_generate_pucch3_4(c16_t **txdataF, const NR_DL_FRAME_PARMS *frame_parms, const int16_t amp16, const int nr_slot_tx, diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h index 7f769872de..47b86c31c0 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h +++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h @@ -42,29 +42,25 @@ #include "T.h" #define ONE_OVER_SQRT2 23170 // 32767/sqrt(2) = 23170 (ONE_OVER_SQRT2) -void nr_generate_pucch0(const PHY_VARS_NR_UE *ue, - c16_t **txdataF, +void nr_generate_pucch0(c16_t **txdataF, const NR_DL_FRAME_PARMS *frame_parms, const int16_t amp, const int nr_slot_tx, const fapi_nr_ul_config_pucch_pdu *pucch_pdu); -void nr_generate_pucch1(const PHY_VARS_NR_UE *ue, - c16_t **txdataF, +void nr_generate_pucch1(c16_t **txdataF, const NR_DL_FRAME_PARMS *frame_parms, const int16_t amp, const int nr_slot_tx, const fapi_nr_ul_config_pucch_pdu *pucch_pdu); -void nr_generate_pucch2(const PHY_VARS_NR_UE *ue, - c16_t **txdataF, +void nr_generate_pucch2(c16_t **txdataF, const NR_DL_FRAME_PARMS *frame_parms, const int16_t amp, const int nr_slot_tx, const fapi_nr_ul_config_pucch_pdu *pucch_pdu); -void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue, - c16_t **txdataF, +void nr_generate_pucch3_4(c16_t **txdataF, const NR_DL_FRAME_PARMS *frame_parms, const int16_t amp, const int nr_slot_tx, diff --git a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c index da27ca8603..34751c1742 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c @@ -189,8 +189,8 @@ void insert_sss_nr(int16_t *sss_time, static int pss_ch_est_nr(const NR_DL_FRAME_PARMS *frame_parms, int nid2, - c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR], - c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR]) + c16_t pss_ext[frame_parms->nb_antennas_rx][LENGTH_PSS_NR], + c16_t sss_ext[frame_parms->nb_antennas_rx][LENGTH_SSS_NR]) { int16_t *pss = get_primary_synchro_nr2(nid2); @@ -250,15 +250,13 @@ static int pss_ch_est_nr(const NR_DL_FRAME_PARMS *frame_parms, * *********************************************************************/ -static int do_pss_sss_extract_nr( - const NR_DL_FRAME_PARMS *frame_parms, - c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR], - c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR], - uint8_t doPss, - uint8_t doSss, - uint8_t subframe, - int ssb_start_subcarrier, - c16_t rxdataF[][frame_parms->samples_per_slot_wCP]) // add flag to indicate extracting only PSS, only SSS, or both +static int do_pss_sss_extract_nr(const NR_DL_FRAME_PARMS *frame_parms, + c16_t pss_ext[frame_parms->nb_antennas_rx][LENGTH_PSS_NR], + c16_t sss_ext[frame_parms->nb_antennas_rx][LENGTH_SSS_NR], + uint8_t doPss, + uint8_t doSss, + int ssb_start_subcarrier, + c16_t rxdataF[][frame_parms->samples_per_slot_wCP]) // add flag to indicate extracting only PSS, only SSS, or both { AssertFatal(frame_parms->nb_antennas_rx > 0, "UB as sss_ext is not set to any value\n"); @@ -331,9 +329,8 @@ static int do_pss_sss_extract_nr( *********************************************************************/ static int pss_sss_extract_nr(const NR_DL_FRAME_PARMS *frame_parms, - c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR], - c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR], - uint8_t subframe, + c16_t pss_ext[frame_parms->nb_antennas_rx][LENGTH_PSS_NR], + c16_t sss_ext[frame_parms->nb_antennas_rx][LENGTH_SSS_NR], int ssb_start_subcarrier, c16_t rxdataF[][frame_parms->samples_per_slot_wCP]) { @@ -342,7 +339,6 @@ static int pss_sss_extract_nr(const NR_DL_FRAME_PARMS *frame_parms, sss_ext, 1 /* doPss */, 1 /* doSss */, - subframe, ssb_start_subcarrier, rxdataF); } @@ -371,8 +367,8 @@ bool rx_sss_nr(const NR_DL_FRAME_PARMS *frame_parms, c16_t rxdataF[][frame_parms->samples_per_slot_wCP]) { uint8_t i; - c16_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR] = {0}; - c16_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR] = {0}; + c16_t pss_ext[frame_parms->nb_antennas_rx][LENGTH_PSS_NR]; + c16_t sss_ext[frame_parms->nb_antennas_rx][LENGTH_SSS_NR]; uint8_t Nid2 = GET_NID2(nid2); uint16_t Nid1; uint8_t phase; @@ -381,7 +377,7 @@ bool rx_sss_nr(const NR_DL_FRAME_PARMS *frame_parms, // pss sss extraction - pss_sss_extract_nr(frame_parms, pss_ext, sss_ext, 0, ssb_start_subcarrier, rxdataF); /* subframe */ + pss_sss_extract_nr(frame_parms, pss_ext, sss_ext, ssb_start_subcarrier, rxdataF); /* subframe */ #ifdef DEBUG_PLOT_SSS diff --git a/openair1/PHY/TOOLS/dB_routines.c b/openair1/PHY/TOOLS/dB_routines.c index 6d56e6d124..13172da86b 100644 --- a/openair1/PHY/TOOLS/dB_routines.c +++ b/openair1/PHY/TOOLS/dB_routines.c @@ -21,7 +21,7 @@ #include "tools_defs.h" -// Approximate 10*log10(x) in fixed point : x = 0...(2^32)-1 +// Approximate 10*log10(x) in fixed point : x = 0...(2^32)-1, where the output is truncated to 10*log10(2^30) = 90 dB static const int8_t dB_table[256] = { 0, 3, 5, 6, 7, 8, 8, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, @@ -131,60 +131,60 @@ int16_t dB_fixed_x10(uint32_t x) { int16_t dB_fixed_times10(uint32_t x) { - int16_t dB_power=0; + int16_t dB_power = 0; - if (x==0) { - dB_power = 0; - } else if ( (x&0xff000000) != 0 ) { - dB_power = dB_table_times10[((x>>24)&255)-1]; - dB_power += 3*dB_table_times10[255]; - } else if ( (x&0x00ff0000) != 0 ) { - dB_power = dB_table_times10[((x>>16)&255)-1]; - dB_power += 2*dB_table_times10[255]; - } else if ( (x&0x0000ff00) != 0 ) { - dB_power = dB_table_times10[((x>>8)&255)-1]; + if (x == 0) { + dB_power = -900; // 0 in dB is -INF, but since we're dealing with integer variables, we'll put 10*log10(2^-30) x 10 in the output + } else if ((x & 0xff000000) != 0) { + dB_power = dB_table_times10[((x >> 24) & 255) - 1]; + dB_power += 3 * dB_table_times10[255]; + } else if ((x & 0x00ff0000) != 0) { + dB_power = dB_table_times10[((x >> 16) & 255) - 1]; + dB_power += 2 * dB_table_times10[255]; + } else if ((x & 0x0000ff00) != 0) { + dB_power = dB_table_times10[((x >> 8) & 255) - 1]; dB_power += dB_table_times10[255]; } else { - dB_power = dB_table_times10[(x&255)-1]; + dB_power = dB_table_times10[(x & 255) - 1]; } if (dB_power > 900) - return(900); + return (900); return dB_power; } - int8_t dB_fixed(uint32_t x) { - int8_t dB_power=0; + int8_t dB_power = 0; - if (x==0) { - dB_power = 0; - } else if ( (x&0xff000000) != 0 ) { - dB_power = dB_table[((x>>24)&255)-1]; - dB_power += 3*dB_table[255]; - } else if ( (x&0x00ff0000) != 0 ) { - dB_power = dB_table[((x>>16)&255)-1]; - dB_power += 2*dB_table[255]; - } else if ( (x&0x0000ff00) != 0 ) { - dB_power = dB_table[((x>>8)&255)-1]; + if (x == 0) { + dB_power = -90; // 0 in dB is -INF, but since we're dealing with integer variables, we'll put 10*log10(2^-30) in the output + } else if ((x & 0xff000000) != 0) { + dB_power = dB_table[((x >> 24) & 255) - 1]; + dB_power += 3 * dB_table[255]; + } else if ((x & 0x00ff0000) != 0) { + dB_power = dB_table[((x >> 16) & 255) - 1]; + dB_power += 2 * dB_table[255]; + } else if ((x & 0x0000ff00) != 0) { + dB_power = dB_table[((x >> 8) & 255) - 1]; dB_power += dB_table[255]; } else { - dB_power = dB_table[(x&255)-1]; + dB_power = dB_table[(x & 255) - 1]; } if (dB_power > 90) - return(90); + return (90); return dB_power; } - -uint8_t dB_fixed64(uint64_t x) +int8_t dB_fixed64(uint64_t x) { - if ((x<(((uint64_t)1)<<32))) return(dB_fixed((uint32_t)x)); - else return(4*dB_table[255]+dB_fixed((uint32_t)(x>>32))); + if ((x < (((uint64_t)1) << 32))) + return (dB_fixed((uint32_t)x)); + else + return (4 * dB_table[255] + dB_fixed((uint32_t)(x >> 32))); } diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h index 40f6ca46f6..abe2ded220 100644 --- a/openair1/PHY/TOOLS/tools_defs.h +++ b/openair1/PHY/TOOLS/tools_defs.h @@ -961,7 +961,7 @@ uint32_t angle(struct complex16 perrror); unsigned char factor2(unsigned int x); int8_t dB_fixed(uint32_t x); -uint8_t dB_fixed64(uint64_t x); +int8_t dB_fixed64(uint64_t x); int8_t dB_fixed2(uint32_t x,uint32_t y); int16_t dB_fixed_times10(uint32_t x); int16_t dB_fixed_x10(uint32_t x); diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h index 851d417804..0873340445 100644 --- a/openair1/PHY/defs_RU.h +++ b/openair1/PHY/defs_RU.h @@ -45,7 +45,7 @@ #define MAX_BANDS_PER_RRU 4 #define MAX_RRU_CONFIG_SIZE 1024 - +typedef struct NR_DL_FRAME_PARMS_s NR_DL_FRAME_PARMS; typedef enum { normal_txrx=0, @@ -176,7 +176,7 @@ typedef struct { int slot; const c16_t *rxdata; c16_t *rxdataF; - const struct NR_DL_FRAME_PARMS *fp; + const NR_DL_FRAME_PARMS *fp; int32_t sample_offet; task_ans_t *ans; } feprx_cmd_t; @@ -491,8 +491,8 @@ typedef struct RU_t_s { /// FAPI confiuration nfapi_nr_config_request_scf_t config; /// Frame parameters - struct LTE_DL_FRAME_PARMS *frame_parms; - struct NR_DL_FRAME_PARMS *nr_frame_parms; + struct LTE_DL_FRAME_PARMS_s *frame_parms; + struct NR_DL_FRAME_PARMS_s *nr_frame_parms; ///timing offset used in TDD int N_TA_offset; /// SF extension used in TDD (unit: number of samples at 30.72MHz) (this is an expert option) diff --git a/openair1/PHY/defs_UE.h b/openair1/PHY/defs_UE.h index 82cc747581..c6521e0c74 100644 --- a/openair1/PHY/defs_UE.h +++ b/openair1/PHY/defs_UE.h @@ -206,15 +206,15 @@ typedef struct { //! estimated noise power (linear) unsigned int n0_power[NB_ANTENNAS_RX]; //! estimated noise power (dB) - unsigned short n0_power_dB[NB_ANTENNAS_RX]; + short n0_power_dB[NB_ANTENNAS_RX]; //! total estimated noise power (linear) unsigned int n0_power_tot; //! total estimated noise power (dB) - unsigned short n0_power_tot_dB; + short n0_power_tot_dB; //! average estimated noise power (linear) unsigned int n0_power_avg; //! average estimated noise power (dB) - unsigned short n0_power_avg_dB; + short n0_power_avg_dB; //! total estimated noise power (dBm) short n0_power_tot_dBm; @@ -222,24 +222,24 @@ typedef struct { //! estimated received spatial signal power (linear) int rx_spatial_power[NUMBER_OF_CONNECTED_eNB_MAX][2][2]; //! estimated received spatial signal power (dB) - unsigned short rx_spatial_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][2][2]; + short rx_spatial_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][2][2]; /// estimated received signal power (sum over all TX antennas) //int wideband_cqi[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; int rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; /// estimated received signal power (sum over all TX antennas) //int wideband_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; - unsigned short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; /// estimated received signal power (sum over all TX/RX antennas) int rx_power_tot[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW /// estimated received signal power (sum over all TX/RX antennas) - unsigned short rx_power_tot_dB[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW + short rx_power_tot_dB[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW //! estimated received signal power (sum of all TX/RX antennas, time average) int rx_power_avg[NUMBER_OF_CONNECTED_eNB_MAX]; //! estimated received signal power (sum of all TX/RX antennas, time average, in dB) - unsigned short rx_power_avg_dB[NUMBER_OF_CONNECTED_eNB_MAX]; + short rx_power_avg_dB[NUMBER_OF_CONNECTED_eNB_MAX]; /// SINR (sum of all TX/RX antennas, in dB) int wideband_cqi_tot[NUMBER_OF_CONNECTED_eNB_MAX]; diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h index 04d99108a1..b728fe89f0 100644 --- a/openair1/PHY/defs_common.h +++ b/openair1/PHY/defs_common.h @@ -598,8 +598,7 @@ typedef struct { int non_mbsfn_SubframeConfig; } NonMBSFN_config_t; - -typedef struct LTE_DL_FRAME_PARMS { +typedef struct LTE_DL_FRAME_PARMS_s { /// Number of resource blocks (RB) in DL uint8_t N_RB_DL; /// Number of resource blocks (RB) in UL diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h index 441c7b8f96..ebb7013cc0 100644 --- a/openair1/PHY/defs_eNB.h +++ b/openair1/PHY/defs_eNB.h @@ -419,17 +419,17 @@ typedef struct { //! estimated noise power (linear) unsigned int n0_power[MAX_NUM_RU_PER_eNB]; //! estimated noise power (dB) - unsigned short n0_power_dB[MAX_NUM_RU_PER_eNB]; + short n0_power_dB[MAX_NUM_RU_PER_eNB]; //! total estimated noise power (linear) unsigned int n0_power_tot; //! estimated avg noise power (dB) - unsigned short n0_power_tot_dB; + short n0_power_tot_dB; //! estimated avg noise power (dB) short n0_power_tot_dBm; //! estimated avg noise power per RB per RX ant (lin) unsigned short n0_subband_power[MAX_NUM_RU_PER_eNB][100]; //! estimated avg noise power per RB per RX ant (dB) - unsigned short n0_subband_power_dB[MAX_NUM_RU_PER_eNB][100]; + short n0_subband_power_dB[MAX_NUM_RU_PER_eNB][100]; //! estimated avg noise power per RB (dB) short n0_subband_power_tot_dB[100]; //! estimated avg noise power per RB (dBm) @@ -440,7 +440,7 @@ typedef struct { //! estimated received spatial signal power (linear) unsigned int rx_spatial_power[NUMBER_OF_SRS_MAX][2][2]; //! estimated received spatial signal power (dB) - unsigned short rx_spatial_power_dB[NUMBER_OF_SRS_MAX][2][2]; + short rx_spatial_power_dB[NUMBER_OF_SRS_MAX][2][2]; //! estimated rssi (dBm) short rx_rssi_dBm[NUMBER_OF_SRS_MAX]; //! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation) @@ -453,7 +453,7 @@ typedef struct { /// Wideband CQI in dB (= SINR dB) int wideband_cqi_dB[NUMBER_OF_SRS_MAX][MAX_NUM_RU_PER_eNB]; /// Wideband CQI (sum of all RX antennas, in dB) - char wideband_cqi_tot[NUMBER_OF_SRS_MAX]; + int wideband_cqi_tot[NUMBER_OF_SRS_MAX]; /// Subband CQI per RX antenna and RB (= SINR) int subband_cqi[NUMBER_OF_SRS_MAX][MAX_NUM_RU_PER_eNB][100]; /// Total Subband CQI and RB (= SINR) diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index b1113517c6..92523d94ee 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -319,17 +319,17 @@ typedef struct { //! estimated noise power (linear) unsigned int n0_power[MAX_NUM_RU_PER_gNB]; //! estimated noise power (dB) - unsigned int n0_power_dB[MAX_NUM_RU_PER_gNB]; + int n0_power_dB[MAX_NUM_RU_PER_gNB]; //! total estimated noise power (linear) unsigned int n0_power_tot; //! estimated avg noise power (dB) - unsigned int n0_power_tot_dB; + int n0_power_tot_dB; //! estimated avg noise power per RB per RX ant (lin) fourDimArray_t *n0_subband_power; //! estimated avg subband noise power (dB) - unsigned int n0_subband_power_avg_dB; + int n0_subband_power_avg_dB; //! estimated avg subband noise power per antenna (dB) - unsigned int n0_subband_power_avg_perANT_dB[MAX_ANT]; + int n0_subband_power_avg_perANT_dB[MAX_ANT]; //! estimated avg noise power per RB (dB) int n0_subband_power_tot_dB[275]; /// PRACH background noise level diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index c14751a050..eb0403a2ba 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -104,18 +104,11 @@ /// Context data structure for gNB subframe processing typedef struct { /// Component Carrier index - uint8_t CC_id; + uint8_t CC_id; /// Last RX timestamp openair0_timestamp_t timestamp_rx; } UE_nr_proc_t; -typedef enum { - NR_PBCH_EST=0, - NR_PDCCH_EST, - NR_PDSCH_EST, - NR_SSS_EST, -} NR_CHANNEL_EST_t; - #define debug_msg if (((mac_xface->frame%100) == 0) || (mac_xface->frame < 50)) msg #define NEIGHBOR_CELL_MAX_CONSECUTIVE_FAILURES 10 @@ -144,18 +137,14 @@ typedef struct { int ssb_rsrp_dBm[64]; float ssb_sinr_dB[64]; // common measurements - //! estimated noise power (linear) - unsigned int n0_power[NB_ANTENNAS_RX]; - //! estimated noise power (dB) - unsigned short n0_power_dB[NB_ANTENNAS_RX]; //! total estimated noise power (linear) unsigned int n0_power_tot; //! total estimated noise power (dB) - unsigned short n0_power_tot_dB; + short n0_power_tot_dB; //! average estimated noise power (linear) unsigned int n0_power_avg; //! average estimated noise power (dB) - unsigned short n0_power_avg_dB; + short n0_power_avg_dB; //! total estimated noise power (dBm) short n0_power_tot_dBm; @@ -165,59 +154,27 @@ typedef struct { //! estimated received spatial signal power (dB) fourDimArray_t *rx_spatial_power_dB; - /// estimated received signal power (sum over all TX antennas) - int rx_power[NUMBER_OF_CONNECTED_gNB_MAX][NB_ANTENNAS_RX]; - /// estimated received signal power (sum over all TX antennas) - unsigned short rx_power_dB[NUMBER_OF_CONNECTED_gNB_MAX][NB_ANTENNAS_RX]; - /// estimated received signal power (sum over all TX/RX antennas) - int rx_power_tot[NUMBER_OF_CONNECTED_gNB_MAX]; //NEW + int rx_power_tot[NUMBER_OF_CONNECTED_gNB_MAX]; //NEW /// estimated received signal power (sum over all TX/RX antennas) - unsigned short rx_power_tot_dB[NUMBER_OF_CONNECTED_gNB_MAX]; //NEW + short rx_power_tot_dB[NUMBER_OF_CONNECTED_gNB_MAX]; //NEW //! estimated received signal power (sum of all TX/RX antennas, time average) - int rx_power_avg[NUMBER_OF_CONNECTED_gNB_MAX]; + int rx_power_avg[NUMBER_OF_CONNECTED_gNB_MAX]; //! estimated received signal power (sum of all TX/RX antennas, time average, in dB) - unsigned short rx_power_avg_dB[NUMBER_OF_CONNECTED_gNB_MAX]; + short rx_power_avg_dB[NUMBER_OF_CONNECTED_gNB_MAX]; /// SINR (sum of all TX/RX antennas, in dB) - int wideband_cqi_tot[NUMBER_OF_CONNECTED_gNB_MAX]; + int wideband_cqi_tot[NUMBER_OF_CONNECTED_gNB_MAX]; /// SINR (sum of all TX/RX antennas, time average, in dB) - int wideband_cqi_avg[NUMBER_OF_CONNECTED_gNB_MAX]; + int wideband_cqi_avg[NUMBER_OF_CONNECTED_gNB_MAX]; //! estimated rssi (dBm) - short rx_rssi_dBm[NUMBER_OF_CONNECTED_gNB_MAX]; - //! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation) - int rx_correlation[NUMBER_OF_CONNECTED_gNB_MAX][NB_ANTENNAS_RX][NR_MAX_NB_LAYERS*NR_MAX_NB_LAYERS];// - //! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation) - int rx_correlation_dB[NUMBER_OF_CONNECTED_gNB_MAX][2]; + short rx_rssi_dBm[NUMBER_OF_CONNECTED_gNB_MAX]; - /// Wideband CQI (sum of all RX antennas, in dB, for precoded transmission modes (3,4,5,6), up to 4 spatial streams) - int precoded_cqi_dB[NUMBER_OF_CONNECTED_gNB_MAX+1][4]; - /// Subband CQI per RX antenna (= SINR) - int subband_cqi[NUMBER_OF_CONNECTED_gNB_MAX][NB_ANTENNAS_RX][NUMBER_OF_SUBBANDS_MAX]; - /// Total Subband CQI (= SINR) - int subband_cqi_tot[NUMBER_OF_CONNECTED_gNB_MAX][NUMBER_OF_SUBBANDS_MAX]; - /// Subband CQI in dB (= SINR dB) - int subband_cqi_dB[NUMBER_OF_CONNECTED_gNB_MAX][NB_ANTENNAS_RX][NUMBER_OF_SUBBANDS_MAX]; - /// Total Subband CQI - int subband_cqi_tot_dB[NUMBER_OF_CONNECTED_gNB_MAX][NUMBER_OF_SUBBANDS_MAX]; - /// Wideband PMI for each RX antenna - int wideband_pmi_re[NUMBER_OF_CONNECTED_gNB_MAX][NB_ANTENNAS_RX]; - /// Wideband PMI for each RX antenna - int wideband_pmi_im[NUMBER_OF_CONNECTED_gNB_MAX][NB_ANTENNAS_RX]; - ///Subband PMI for each RX antenna - int subband_pmi_re[NUMBER_OF_CONNECTED_gNB_MAX][NUMBER_OF_SUBBANDS_MAX][NB_ANTENNAS_RX]; - ///Subband PMI for each RX antenna - int subband_pmi_im[NUMBER_OF_CONNECTED_gNB_MAX][NUMBER_OF_SUBBANDS_MAX][NB_ANTENNAS_RX]; - /// chosen RX antennas (1=Rx antenna 1, 2=Rx antenna 2, 3=both Rx antennas) - unsigned char selected_rx_antennas[NUMBER_OF_CONNECTED_gNB_MAX][NUMBER_OF_SUBBANDS_MAX]; - /// Wideband Rank indication - unsigned char rank[NUMBER_OF_CONNECTED_gNB_MAX]; /// Number of RX Antennas unsigned char nb_antennas_rx; - /// DLSCH error counter - // short dlsch_errors; + /// Info about neighboring cells to perform the measurements neighboring_cell_info_t neighboring_cell_info[NUMBER_OF_NEIGHBORING_CELLS_MAX]; bool meas_request_pending; @@ -263,17 +220,6 @@ typedef struct { #define MAX_NR_DCI_DECODED_SLOT 10 // This value is not specified -typedef enum { - _format_0_0_found = 0, - _format_0_1_found = 1, - _format_1_0_found = 2, - _format_1_1_found = 3, - _format_2_0_found = 4, - _format_2_1_found = 5, - _format_2_2_found = 6, - _format_2_3_found = 7 -} format_found_t; - #endif typedef struct { int nb_search_space; @@ -282,18 +228,6 @@ typedef struct { #define NR_PSBCH_DMRS_LENGTH 297 // in mod symbols #define NR_PSBCH_DMRS_LENGTH_DWORD 20 // ceil(2(QPSK)*NR_PBCH_DMRS_LENGTH/32) - -/* NR Sidelink PSBCH payload fields - TODO: This will be removed in the future and - filled in by the upper layers once developed. */ -typedef struct { - uint32_t coverageIndicator : 1; - uint32_t tddConfig : 12; - uint32_t DFN : 10; - uint32_t slotIndex : 7; - uint32_t reserved : 2; -} PSBCH_payload; - #define PBCH_A 24 typedef struct { @@ -426,15 +360,11 @@ typedef struct PHY_VARS_NR_UE_s { fapi_nr_config_request_t nrUE_config; nr_synch_request_t synch_request; - NR_UE_PRACH *prach_vars[NUMBER_OF_CONNECTED_gNB_MAX]; - NR_UE_PRS *prs_vars[NR_MAX_PRS_COMB_SIZE]; - uint8_t prs_active_gNBs; + NR_UE_PRACH *prach_vars[NUMBER_OF_CONNECTED_gNB_MAX]; + NR_UE_PRS *prs_vars[NR_MAX_PRS_COMB_SIZE]; + uint8_t prs_active_gNBs; NR_DL_UE_HARQ_t dl_harq_processes[2][NR_MAX_DLSCH_HARQ_PROCESSES]; NR_UL_UE_HARQ_t ul_harq_processes[NR_MAX_ULSCH_HARQ_PROCESSES]; - //Paging parameters - uint32_t IMSImod1024; - uint32_t PF; - uint32_t PO; // Scrambling IDs used in PUSCH DMRS c16_t X_u[64][839]; @@ -463,21 +393,6 @@ typedef struct PHY_VARS_NR_UE_s { int dlsch_received[NUMBER_OF_CONNECTED_gNB_MAX]; int dlsch_received_last[NUMBER_OF_CONNECTED_gNB_MAX]; int dlsch_fer[NUMBER_OF_CONNECTED_gNB_MAX]; - int dlsch_SI_received[NUMBER_OF_CONNECTED_gNB_MAX]; - int dlsch_SI_errors[NUMBER_OF_CONNECTED_gNB_MAX]; - int dlsch_ra_received[NUMBER_OF_CONNECTED_gNB_MAX]; - int dlsch_ra_errors[NUMBER_OF_CONNECTED_gNB_MAX]; - int dlsch_p_received[NUMBER_OF_CONNECTED_gNB_MAX]; - int dlsch_p_errors[NUMBER_OF_CONNECTED_gNB_MAX]; - int dlsch_mch_received[NUMBER_OF_CONNECTED_gNB_MAX]; - int current_dlsch_cqi[NUMBER_OF_CONNECTED_gNB_MAX]; - int dlsch_mch_received_sf[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX]; - int dlsch_mcch_received[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX]; - int dlsch_mtch_received[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX]; - int dlsch_mcch_errors[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX]; - int dlsch_mtch_errors[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX]; - int dlsch_mcch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX]; - int dlsch_mtch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_gNB_MAX]; uint8_t init_sync_frame; /// temporary offset during cell search prior to MIB decoding int ssb_offset; diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index 199877d738..20fc744f57 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -156,9 +156,7 @@ typedef struct { } prach_list_t; void init_prach_list(prach_list_t *); -typedef struct NR_DL_FRAME_PARMS NR_DL_FRAME_PARMS; - -struct NR_DL_FRAME_PARMS { +typedef struct NR_DL_FRAME_PARMS_s { /// frequency range frequency_range_t freq_range; // /// Placeholder to replace overlapping fields below @@ -269,7 +267,7 @@ struct NR_DL_FRAME_PARMS { uint16_t tdd_slot_config; uint8_t tdd_period; bool print_ue_help_cmdline_log; -}; +} NR_DL_FRAME_PARMS; // PRS config structures typedef struct { @@ -305,6 +303,29 @@ typedef struct { int32_t reserved; } prs_meas_t; +// Configuration parameters required for 5G Positioning +// TRP Cartesian Coordinate information +typedef struct trp_s { + // TRP id + uint32_t id; + // TRP x-axis value + uint32_t x_axis; + // TRP y-axis value + uint32_t y_axis; + // TRP z-axis value + uint32_t z_axis; + // 0 = mm, 1 = cm, 2 = dm + uint8_t unit; +} trp_t; + +#define MAX_NUM_TRPs 8 +typedef struct { + trp_t trps[MAX_NUM_TRPs]; + uint8_t num_trp; + // Serving gNB indicator + bool is_serving_gNB; +} positioning_config_t; + // rel16 prs k_prime table as per ts138.211 sec.7.4.1.7.2 #define K_PRIME_TABLE_ROW_SIZE 4 #define K_PRIME_TABLE_COL_SIZE 12 diff --git a/openair1/PHY/impl_defs_top_NB_IoT.h b/openair1/PHY/impl_defs_top_NB_IoT.h index 8d05e9a05e..4179a865b8 100644 --- a/openair1/PHY/impl_defs_top_NB_IoT.h +++ b/openair1/PHY/impl_defs_top_NB_IoT.h @@ -55,15 +55,15 @@ typedef struct { //! estimated noise power (linear) unsigned int n0_power[NB_ANTENNAS_RX]; //! estimated noise power (dB) - unsigned short n0_power_dB[NB_ANTENNAS_RX]; + short n0_power_dB[NB_ANTENNAS_RX]; //! total estimated noise power (linear) unsigned int n0_power_tot; //! total estimated noise power (dB) - unsigned short n0_power_tot_dB; + short n0_power_tot_dB; //! average estimated noise power (linear) unsigned int n0_power_avg; //! average estimated noise power (dB) - unsigned short n0_power_avg_dB; + short n0_power_avg_dB; //! total estimated noise power (dBm) short n0_power_tot_dBm; @@ -71,24 +71,24 @@ typedef struct { //! estimated received spatial signal power (linear) int rx_spatial_power[NUMBER_OF_CONNECTED_eNB_MAX][2][2]; //! estimated received spatial signal power (dB) - unsigned short rx_spatial_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][2][2]; + short rx_spatial_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][2][2]; /// estimated received signal power (sum over all TX antennas) //int wideband_cqi[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; int rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; /// estimated received signal power (sum over all TX antennas) //int wideband_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; - unsigned short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; /// estimated received signal power (sum over all TX/RX antennas) int rx_power_tot[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW /// estimated received signal power (sum over all TX/RX antennas) - unsigned short rx_power_tot_dB[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW + short rx_power_tot_dB[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW //! estimated received signal power (sum of all TX/RX antennas, time average) int rx_power_avg[NUMBER_OF_CONNECTED_eNB_MAX]; //! estimated received signal power (sum of all TX/RX antennas, time average, in dB) - unsigned short rx_power_avg_dB[NUMBER_OF_CONNECTED_eNB_MAX]; + short rx_power_avg_dB[NUMBER_OF_CONNECTED_eNB_MAX]; /// SINR (sum of all TX/RX antennas, in dB) int wideband_cqi_tot[NUMBER_OF_CONNECTED_eNB_MAX]; @@ -141,17 +141,17 @@ typedef struct { //! estimated noise power (linear) unsigned int n0_power[NB_ANTENNAS_RX]; //! estimated noise power (dB) - unsigned short n0_power_dB[NB_ANTENNAS_RX]; + short n0_power_dB[NB_ANTENNAS_RX]; //! total estimated noise power (linear) unsigned int n0_power_tot; //! estimated avg noise power (dB) - unsigned short n0_power_tot_dB; + short n0_power_tot_dB; //! estimated avg noise power (dB) short n0_power_tot_dBm; //! estimated avg noise power per RB per RX ant (lin) unsigned short n0_subband_power[NB_ANTENNAS_RX][100]; //! estimated avg noise power per RB per RX ant (dB) - unsigned short n0_subband_power_dB[NB_ANTENNAS_RX][100]; + short n0_subband_power_dB[NB_ANTENNAS_RX][100]; //! estimated avg noise power per RB (dB) short n0_subband_power_tot_dB[100]; //! estimated avg noise power per RB (dBm) @@ -160,7 +160,7 @@ typedef struct { //! estimated received spatial signal power (linear) unsigned int rx_spatial_power[NUMBER_OF_UE_MAX][2][2]; //! estimated received spatial signal power (dB) - unsigned short rx_spatial_power_dB[NUMBER_OF_UE_MAX][2][2]; + short rx_spatial_power_dB[NUMBER_OF_UE_MAX][2][2]; //! estimated rssi (dBm) short rx_rssi_dBm[NUMBER_OF_UE_MAX]; //! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation) @@ -173,7 +173,7 @@ typedef struct { /// Wideband CQI in dB (= SINR dB) int wideband_cqi_dB[NUMBER_OF_UE_MAX][NB_ANTENNAS_RX]; /// Wideband CQI (sum of all RX antennas, in dB) - char wideband_cqi_tot[NUMBER_OF_UE_MAX]; + int wideband_cqi_tot[NUMBER_OF_UE_MAX]; /// Subband CQI per RX antenna and RB (= SINR) int subband_cqi[NUMBER_OF_UE_MAX][NB_ANTENNAS_RX][100]; /// Total Subband CQI and RB (= SINR) diff --git a/openair1/PHY/nr_phy_common/inc/nr_phy_common.h b/openair1/PHY/nr_phy_common/inc/nr_phy_common.h index b4c0e1239c..67bed6eef4 100644 --- a/openair1/PHY/nr_phy_common/inc/nr_phy_common.h +++ b/openair1/PHY/nr_phy_common/inc/nr_phy_common.h @@ -389,4 +389,9 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms, const uint8_t cdm_type, c16_t **dataF); +int nr_get_ssb_start_sc(int scs, + int ssb_offset_point_a, + int ssb_sco, + frequency_range_t freq_range); + #endif diff --git a/openair1/PHY/nr_phy_common/src/nr_phy_common.c b/openair1/PHY/nr_phy_common/src/nr_phy_common.c index a723780f94..c29a3a4936 100644 --- a/openair1/PHY/nr_phy_common/src/nr_phy_common.c +++ b/openair1/PHY/nr_phy_common/src/nr_phy_common.c @@ -481,3 +481,26 @@ void nr_fo_compensation(double fo_Hz, int samples_per_ms, int sample_offset, con mult_complex_vectors(rxdata_in, rot, rxdata_out, size, 14); #endif } + +/*! +* Setting the first subcarrier +* 3GPP TS 38.211 sections 7.4.3.1 and 4.4.4.2 +* for FR1 offsetToPointA and k_SSB are expressed in terms of 15 kHz SCS +* for FR2 offsetToPointA is expressed in terms of 60 kHz SCS and k_SSB expressed in terms of the SCS provided +* by the higher-layer parameter subCarrierSpacingCommon +*/ +int nr_get_ssb_start_sc(int scs, int ssb_offset_point_a, int ssb_sco, frequency_range_t freq_range) +{ + const int prb_offset = + (freq_range == FR1) ? ssb_offset_point_a >> scs : ssb_offset_point_a >> (scs - 2); + const int sc_offset = + (freq_range == FR1) ? ssb_sco >> scs : ssb_sco; + + int ssb_start_subcarrier = (12 * prb_offset + sc_offset); + + LOG_D(NR_PHY, "prb_offset:%d, ssb_subcarrier_offset:%d,scs :%d, Fr:%d, ssb_start_subcarrier:%d\n", + prb_offset, ssb_sco, scs, freq_range, ssb_start_subcarrier); + + return ssb_start_subcarrier; + +} diff --git a/openair1/SCHED/nfapi_lte_dummy.c b/openair1/SCHED/nfapi_lte_dummy.c index 5ddf2d3485..82a8a77309 100644 --- a/openair1/SCHED/nfapi_lte_dummy.c +++ b/openair1/SCHED/nfapi_lte_dummy.c @@ -4,11 +4,8 @@ #include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h" #include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h" #include "openair1/PHY/LTE_TRANSPORT/transport_common.h" -typedef struct pnf_t pnf_t; -typedef struct pnf_p7_t pnf_p7_t; -typedef struct vnf_t vnf_t; -typedef struct vnf_p7_t vnf_p7_t; - +#include "nfapi/open-nFAPI/vnf/inc/vnf.h" +#include "nfapi/open-nFAPI/pnf/inc/pnf.h" int l1_north_init_gNB(void){return 0;} int slot_ahead = 6; diff --git a/openair1/SCHED/prach_procedures.c b/openair1/SCHED/prach_procedures.c index 968a94eeb0..3c8dbe8d6e 100644 --- a/openair1/SCHED/prach_procedures.c +++ b/openair1/SCHED/prach_procedures.c @@ -47,11 +47,12 @@ extern int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind); -void prach_procedures(PHY_VARS_eNB *eNB, - int br_flag ) { - uint16_t max_preamble[4]={0},max_preamble_energy[4]={0},max_preamble_delay[4]={0},avg_preamble_energy[4]={0}; +void prach_procedures(PHY_VARS_eNB *eNB, int br_flag) +{ + uint16_t max_preamble[4] = {0}, max_preamble_energy[4] = {0}, max_preamble_delay[4] = {0}; + int16_t avg_preamble_energy[4] = {0}; uint16_t i; - int frame,subframe; + int frame, subframe; if (br_flag==1) { subframe = eNB->proc.subframe_prach_br; diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index eb2c83c10a..ca712bbaf9 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -35,7 +35,7 @@ #include "sched_nr.h" #include "PHY/MODULATION/modulation_common.h" #include "PHY/MODULATION/nr_modulation.h" - +#include "openair1/PHY/defs_nr_common.h" #include "common/utils/LOG/log.h" #include "common/utils/system.h" diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index e304fe3dc9..4e69f8fa69 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -118,9 +118,10 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, const n // by the higher-layer parameter subCarrierSpacingCommon nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; const int scs = cfg->ssb_config.scs_common.value; - const int prb_offset = (fp->freq_range == FR1) ? pdu->ssbOffsetPointA >> scs : pdu->ssbOffsetPointA >> (scs - 2); - const int sc_offset = (fp->freq_range == FR1) ? pdu->SsbSubcarrierOffset >> scs : pdu->SsbSubcarrierOffset; - fp->ssb_start_subcarrier = (12 * prb_offset + sc_offset); + fp->ssb_start_subcarrier = nr_get_ssb_start_sc(scs, + pdu->ssbOffsetPointA, + pdu->SsbSubcarrierOffset, + fp->freq_range); if (fp->print_ue_help_cmdline_log && IS_SA_MODE(get_softmodem_params())) { fp->print_ue_help_cmdline_log = false; @@ -142,15 +143,6 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, const n fp->ssb_start_subcarrier, fp->threequarter_fs ? "-E" : ""); } - LOG_D(PHY, - "ssbOffsetPointA %d SSB SsbSubcarrierOffset %d prb_offset %d sc_offset %d scs %d ssb_start_subcarrier %d\n", - pdu->ssbOffsetPointA, - pdu->SsbSubcarrierOffset, - prb_offset, - sc_offset, - scs, - fp->ssb_start_subcarrier); - LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n", frame, slot, ssb_start_symbol); const nfapi_nr_tx_precoding_and_beamforming_t *pb = &pdu->precoding_and_beamforming; c16_t ***txdataF = gNB->common_vars.txdataF; @@ -209,10 +201,7 @@ void clear_slot_beamid(PHY_VARS_gNB *gNB, int slot) } } -static void nr_generate_csi_rs_gNB(PHY_VARS_gNB *gNB, - int slot, - const nfapi_nr_config_request_scf_t *cfg, - const nfapi_nr_dl_tti_csi_rs_pdu *csi_rs_pdu) +static void nr_generate_csi_rs_gNB(PHY_VARS_gNB *gNB, int slot, const nfapi_nr_dl_tti_csi_rs_pdu *csi_rs_pdu) { const nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params = &csi_rs_pdu->csi_rs_pdu_rel15; if (csi_params->csi_type == 2) // ZP-CSI @@ -253,8 +242,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, const nfapi_nr_tx_data_request_t *TX_req, const nfapi_nr_ul_dci_request_t *UL_dci_req, int frame, - int slot, - int do_meas) + int slot) { const NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; @@ -280,7 +268,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, { int slot_prs = (slot - i * prs_config->PRSResourceTimeGap + fp->slots_per_frame) % fp->slots_per_frame; LOG_D(PHY,"gNB_TX: frame %d, slot %d, slot_prs %d, PRS Resource ID %d\n",frame, slot, slot_prs, rsc_id); - nr_generate_prs(slot_prs, &gNB->common_vars.txdataF[0][0][txdataF_offset], AMP, prs_config, cfg, fp); + nr_generate_prs(slot_prs, &gNB->common_vars.txdataF[0][0][txdataF_offset], AMP, prs_config, fp); } } } @@ -299,7 +287,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, nr_generate_dci(gNB, &dl_tti_pdu->pdcch_pdu.pdcch_pdu_rel15, txdataF_offset, &gNB->frame_parms, slot); break; case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE: - nr_generate_csi_rs_gNB(gNB, slot, cfg, &dl_tti_pdu->csi_rs_pdu); + nr_generate_csi_rs_gNB(gNB, slot, &dl_tti_pdu->csi_rs_pdu); break; case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE: { int tx_data_idx = dl_tti_pdu->pdsch_pdu.pdsch_pdu_rel15.pduIndex; @@ -721,7 +709,6 @@ static void fill_ul_rb_mask(PHY_VARS_gNB *gNB, static int fill_srs_reported_symbol(nfapi_nr_srs_reported_symbol_t *reported_symbol, const nfapi_nr_srs_pdu_t *srs_pdu, - const int N_RB_UL, const int16_t *snr_per_rb, const int srs_est) { @@ -890,7 +877,7 @@ void nr_srs_rx_procedures(PHY_VARS_gNB *gNB, stop_meas(&gNB->generate_srs_stats); c16_t **rxdataF = gNB->common_vars.rxdataF[srs->beam_nb]; start_meas(&gNB->get_srs_signal_stats); - *srs_est = nr_get_srs_signal(gNB, rxdataF, frame_rx, slot_rx, srs_pdu, nr_srs_info, srs_received_signal, srs_received_noise); + *srs_est = nr_get_srs_signal(gNB, rxdataF, slot_rx, srs_pdu, nr_srs_info, srs_received_signal, srs_received_noise); stop_meas(&gNB->get_srs_signal_stats); uint32_t signal_power_avg = 0; @@ -1275,7 +1262,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, N AssertFatal(nr_srs_bf_report.num_reported_symbols == 1, "nr_srs_bf_report.num_reported_symbols %i not handled yet!\n", nr_srs_bf_report.num_reported_symbols); - fill_srs_reported_symbol(&nr_srs_bf_report.reported_symbol_list[0], srs_pdu, frame_parms->N_RB_UL, snr_per_rb, srs_est); + fill_srs_reported_symbol(&nr_srs_bf_report.reported_symbol_list[0], srs_pdu, snr_per_rb, srs_est); #ifdef SRS_IND_DEBUG LOG_I(NR_PHY, "nr_srs_bf_report.prg_size = %i\n", nr_srs_bf_report.prg_size); diff --git a/openair1/SCHED_NR/sched_nr.h b/openair1/SCHED_NR/sched_nr.h index 84691e9584..fbfb665ed1 100644 --- a/openair1/SCHED_NR/sched_nr.h +++ b/openair1/SCHED_NR/sched_nr.h @@ -38,8 +38,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, const nfapi_nr_tx_data_request_t *TX_req, const nfapi_nr_ul_dci_request_t *UL_dci_req, int frame, - int slot, - int do_meas); + int slot); void nr_save_ul_tti_req(PHY_VARS_gNB *gNB, nfapi_nr_ul_tti_request_t *UL_tti_req); int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, NR_UL_IND_t *UL_INFO); void L1_nr_prach_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_rach_indication_t *rach_ind); diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h index 5fe6e0c1bb..394b5592f5 100644 --- a/openair1/SCHED_NR_UE/defs.h +++ b/openair1/SCHED_NR_UE/defs.h @@ -172,7 +172,6 @@ void nr_fill_sl_rx_indication(sl_nr_rx_indication_t *rx_ind, uint8_t pdu_type, PHY_VARS_NR_UE *ue, uint16_t n_pdus, - const UE_nr_rxtx_proc_t *proc, void *typeSpecific, uint16_t rx_slss_id); diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 2da33ce205..cc6a2ee23b 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -1066,7 +1066,6 @@ int pbch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_da 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; int sampleShift = INT_MAX; nr_ue_dlsch_init(phy_data->dlsch, NR_MAX_NB_LAYERS>4 ? 2:1, ue->max_ldpc_iterations); @@ -1152,7 +1151,7 @@ int pbch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_da if (ue->no_timing_correction == 0 && pbchSuccess == 0) { LOG_D(PHY,"start adjust sync slot = %d no timing %d\n", nr_slot_rx, ue->no_timing_correction); sampleShift = - nr_adjust_synch_ue(fp, ue, gNB_id, fp->ofdm_symbol_size, dl_ch_estimates_time, frame_rx, nr_slot_rx, 16384); + nr_adjust_synch_ue(fp, ue, fp->ofdm_symbol_size, dl_ch_estimates_time, frame_rx, nr_slot_rx, 16384); } if (get_nrUE_params()->cont_fo_comp && pbchSuccess == 0) { diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c index 1e2151d1d3..9b17546f61 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c @@ -66,7 +66,6 @@ void nr_fill_sl_rx_indication(sl_nr_rx_indication_t *rx_ind, uint8_t pdu_type, PHY_VARS_NR_UE *ue, uint16_t n_pdus, - const UE_nr_rxtx_proc_t *proc, void *typeSpecific, uint16_t rx_slss_id) { @@ -157,7 +156,7 @@ static int nr_ue_psbch_procedures(PHY_VARS_NR_UE *ue, } nr_fill_sl_indication(&sl_indication, &rx_ind, NULL, proc, ue, phy_data); - nr_fill_sl_rx_indication(&rx_ind, SL_NR_RX_PDU_TYPE_SSB, ue, number_pdus, proc, (void *)result, rx_slss_id); + nr_fill_sl_rx_indication(&rx_ind, SL_NR_RX_PDU_TYPE_SSB, ue, number_pdus, (void *)result, rx_slss_id); if (ue->if_inst && ue->if_inst->sl_indication) ue->if_inst->sl_indication(&sl_indication); @@ -232,7 +231,7 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr if (ue->no_timing_correction == 0 && psbchSuccess == 0) { LOG_D(NR_PHY, "start adjust sync slot = %d no timing %d\n", nr_slot_rx, ue->no_timing_correction); sampleShift = - nr_adjust_synch_ue(fp, ue, proc->gNB_id, fp->ofdm_symbol_size, dl_ch_estimates_time, frame_rx, nr_slot_rx, 16384); + nr_adjust_synch_ue(fp, ue, fp->ofdm_symbol_size, dl_ch_estimates_time, frame_rx, nr_slot_rx, 16384); } LOG_D(NR_PHY, "Doing N0 measurements in %s\n", __FUNCTION__); diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c index 03c14af9b9..be1187f574 100644 --- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c +++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c @@ -176,17 +176,17 @@ void pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, switch(pucch_pdu->format_type) { case 0: - nr_generate_pucch0(ue, txdataF, &ue->frame_parms, tx_amp, nr_slot_tx, pucch_pdu); + nr_generate_pucch0(txdataF, &ue->frame_parms, tx_amp, nr_slot_tx, pucch_pdu); break; case 1: - nr_generate_pucch1(ue, txdataF, &ue->frame_parms, tx_amp, nr_slot_tx, pucch_pdu); + nr_generate_pucch1(txdataF, &ue->frame_parms, tx_amp, nr_slot_tx, pucch_pdu); break; case 2: - nr_generate_pucch2(ue, txdataF, &ue->frame_parms, tx_amp, nr_slot_tx, pucch_pdu); + nr_generate_pucch2(txdataF, &ue->frame_parms, tx_amp, nr_slot_tx, pucch_pdu); break; case 3: case 4: - nr_generate_pucch3_4(ue, txdataF, &ue->frame_parms, tx_amp, nr_slot_tx, pucch_pdu); + nr_generate_pucch3_4(txdataF, &ue->frame_parms, tx_amp, nr_slot_tx, pucch_pdu); break; } } diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index a09b3558cb..9e334cb154 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -520,7 +520,8 @@ int main(int argc, char **argv) { DCI_ALLOC_t da; DCI_ALLOC_t *dci_alloc = &da; unsigned int coded_bits_per_codeword=0,nsymb; //,tbs=0; - unsigned int tx_lev=0,tx_lev_dB=0,trials; + unsigned int tx_lev = 0, trials; + int tx_lev_dB = 0; unsigned int errs[4],errs2[4],round_trials[4],dci_errors[4];//,num_layers; memset(errs,0,4*sizeof(unsigned int)); memset(errs2,0,4*sizeof(unsigned int)); @@ -1494,7 +1495,7 @@ int main(int argc, char **argv) { eNB->frame_parms.samples_per_tti); } - tx_lev_dB = (unsigned int) dB_fixed(tx_lev); + tx_lev_dB = dB_fixed(tx_lev); if (n_frames==1) { printf("tx_lev = %u (%u dB)\n",tx_lev,tx_lev_dB); diff --git a/openair1/SIMULATION/LTE_PHY/prachsim.c b/openair1/SIMULATION/LTE_PHY/prachsim.c index 1b7f9e80e4..c1128f76a1 100644 --- a/openair1/SIMULATION/LTE_PHY/prachsim.c +++ b/openair1/SIMULATION/LTE_PHY/prachsim.c @@ -393,7 +393,7 @@ int main(int argc, char **argv) { subframe, 0); //Nf /* tx_lev_dB not used later, no need to set */ - //tx_lev_dB = (unsigned int) dB_fixed(tx_lev); + //tx_lev_dB = dB_fixed(tx_lev); LOG_M("txsig0_new.m","txs0", &txdata[0][subframe*frame_parms->samples_per_tti],frame_parms->samples_per_tti,1,1); //LOG_M("txsig1.m","txs1", txdata[1],FRAME_LENGTH_COMPLEX_SAMPLES,1,1); // multipath channel diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index 92b9d58f48..c85e07c99c 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -343,7 +343,8 @@ int main(int argc, char **argv) { unsigned short input_buffer_length; unsigned int ret; unsigned int coded_bits_per_codeword,nsymb; - unsigned int tx_lev = 0, tx_lev_dB = 0, trials, errs[6] = {0}, round_trials[4] = {0}; + unsigned int tx_lev = 0, trials, errs[6] = {0}, round_trials[4] = {0}; + int tx_lev_dB = 0; FILE *bler_fd=NULL; char bler_fname[512]; FILE *time_meas_fd=NULL; @@ -894,7 +895,7 @@ int main(int argc, char **argv) { // LOG_M("txsig1.m","txs1", txdata[1],FRAME_LENGTH_COMPLEX_SAMPLES,1,1); tx_lev = signal_energy(&txdata[0][0], OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES); - tx_lev_dB = (unsigned int) dB_fixed(tx_lev); + tx_lev_dB = dB_fixed(tx_lev); } iter_trials=0; diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index 076f05db48..6f4282f130 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -506,7 +506,7 @@ int main(int argc, char **argv) unsigned char output[nb_rb * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * NR_MAX_NB_LAYERS] __attribute__((aligned(64))); bzero(output, sizeof(output)); if (input_fd == NULL) { - nr_dlsch_encoding(gNB, 1, dlsch, frame, slot, frame_parms, output, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + nr_dlsch_encoding(gNB, 1, dlsch, frame, slot, output, NULL, NULL, NULL, NULL, NULL, NULL, NULL); } for (SNR = snr0; SNR < snr1 && !stop; SNR += snr_step) { @@ -620,7 +620,7 @@ int main(int argc, char **argv) free(RC.gNB); free_nr_ue_dl_harq(UE->dl_harq_processes, 8, nb_rb); - term_nr_ue_signal(UE, 1); + term_nr_ue_signal(UE); free(UE); for (i = 0; i < 2; i++) { diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index bcce053231..b068936739 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -1120,7 +1120,7 @@ int main(int argc, char **argv) } start_meas(&gNB->phy_proc_tx); - phy_procedures_gNB_TX(gNB, &Sched_INFO->DL_req, &Sched_INFO->TX_req, &Sched_INFO->UL_dci_req, frame, slot, 1); + phy_procedures_gNB_TX(gNB, &Sched_INFO->DL_req, &Sched_INFO->TX_req, &Sched_INFO->UL_dci_req, frame, slot); stop_meas(&gNB->phy_proc_tx); int txdataF_offset = slot * frame_parms->samples_per_slot_wCP; diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index 087b17ab06..5702be2cf9 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -654,7 +654,7 @@ int main(int argc, char **argv) nr_gscn_info_t gscnInfo[MAX_GSCN_BAND] = {0}; const int numGscn = 1; gscnInfo[0].ssbFirstSC = frame_parms->ssb_start_subcarrier; - nr_initial_sync_t ret = nr_initial_sync(&proc, UE, 1, 0, gscnInfo, numGscn); + nr_initial_sync_t ret = nr_initial_sync(&proc, UE, 1, gscnInfo, numGscn); printf("nr_initial_sync1 returns %s\n", ret.cell_detected ? "cell detected" : "cell not detected"); if (!ret.cell_detected) n_errors++; @@ -761,7 +761,7 @@ int main(int argc, char **argv) free(RC.gNB[0]); free(RC.gNB); - term_nr_ue_signal(UE, 1); + term_nr_ue_signal(UE); free(UE); for (i=0; i<2; i++) { diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 4da1accfe8..7966c74375 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -667,7 +667,7 @@ int main(int argc, char **argv){ generate_nr_prach(UE, 0, frame, slot, tx); /* tx_lev_dB not used later, no need to set */ - //tx_lev_dB = (unsigned int) dB_fixed(tx_lev); + //tx_lev_dB = dB_fixed(tx_lev); #ifdef NR_PRACH_DEBUG LOG_M("txsig0.m", "txs0", &txdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1); @@ -844,7 +844,7 @@ int main(int argc, char **argv){ free(RC.gNB[0]); free(RC.gNB); - term_nr_ue_signal(UE, 1); + term_nr_ue_signal(UE); free(UE->nrUE_config.prach_config.num_prach_fd_occasions_list); free(UE); free(PHY_vars_UE_g[0]); diff --git a/openair1/SIMULATION/NR_PHY/psbchsim.c b/openair1/SIMULATION/NR_PHY/psbchsim.c index 49d07616c4..cb78915cbb 100644 --- a/openair1/SIMULATION/NR_PHY/psbchsim.c +++ b/openair1/SIMULATION/NR_PHY/psbchsim.c @@ -673,8 +673,8 @@ int main(int argc, char **argv) free(r_re); free(r_im); - term_nr_ue_signal(UE_TX, 1); - term_nr_ue_signal(UE_RX, 1); + term_nr_ue_signal(UE_TX); + term_nr_ue_signal(UE_RX); free(UE_TX); free(UE_RX); diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c index 980beac6b3..bfa294a55f 100644 --- a/openair1/SIMULATION/NR_PHY/pucchsim.c +++ b/openair1/SIMULATION/NR_PHY/pucchsim.c @@ -551,11 +551,11 @@ int main(int argc, char **argv) for (int aatx=0;aatx<1;aatx++) bzero(txdataF[aatx],frame_parms->ofdm_symbol_size*sizeof(int)); if(format==0 && do_DTX==0){ - nr_generate_pucch0(UE, txdataF, frame_parms, amp, nr_slot_tx, &pucch_tx_pdu); + nr_generate_pucch0(txdataF, frame_parms, amp, nr_slot_tx, &pucch_tx_pdu); } else if (format == 1 && do_DTX==0){ - nr_generate_pucch1(UE, txdataF, frame_parms, amp, nr_slot_tx, &pucch_tx_pdu); + nr_generate_pucch1(txdataF, frame_parms, amp, nr_slot_tx, &pucch_tx_pdu); } else if (do_DTX == 0){ - nr_generate_pucch2(UE, txdataF, frame_parms, amp, nr_slot_tx, &pucch_tx_pdu); + nr_generate_pucch2(txdataF, frame_parms, amp, nr_slot_tx, &pucch_tx_pdu); } // SNR Computation @@ -784,7 +784,7 @@ int main(int argc, char **argv) free(RC.gNB[0]); free(RC.gNB); - term_nr_ue_signal(UE, 1); + term_nr_ue_signal(UE); free(UE); for (int aatx=0; aatxgNB_config.tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list); free(gNB->gNB_config.tdd_table.max_tdd_periodicity_list); - term_nr_ue_signal(UE, 1); + term_nr_ue_signal(UE); free(UE); abortTpool(&gNB->threadPool); diff --git a/openair2/COMMON/e1ap_messages_types.h b/openair2/COMMON/e1ap_messages_types.h index 48cfef98f3..4d1c9bbe9d 100644 --- a/openair2/COMMON/e1ap_messages_types.h +++ b/openair2/COMMON/e1ap_messages_types.h @@ -199,7 +199,7 @@ typedef struct { typedef nssai_t e1ap_nssai_t; -typedef struct e1ap_net_config_t { +typedef struct { net_ip_address_t CUUP_e1_ip_address; net_ip_address_t CUCP_e1_ip_address; uint16_t remotePortF1U; @@ -230,7 +230,7 @@ typedef struct e1ap_cucp_setup_req_s { uint64_t transac_id; } e1ap_cucp_setup_req_t; -typedef struct e1ap_register_req_t { +typedef struct { e1ap_setup_req_t setup_req; e1ap_net_config_t net_config; uint32_t gnb_id; // unused in CU-UP, but might be necessary for some functionality, e.g., E2 agent @@ -658,7 +658,7 @@ typedef struct e1ap_bearer_modif_resp_s { } e1ap_bearer_modif_resp_t; /* E1AP Connection Loss indication */ -typedef struct e1ap_lost_connection_t { +typedef struct { int dummy; } e1ap_lost_connection_t; diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index 5f430d0e39..3354388596 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -84,7 +84,7 @@ /* 9.3.1.42 of 3GPP TS 38.473 - gNB-CU System Information */ #define F1AP_MAX_NO_SIB_TYPES 32 -typedef struct f1ap_net_config_t { +typedef struct f1ap_net_config_s { char *CU_f1_ip_address; char *DU_f1c_ip_address; char *DU_f1u_ip_address; @@ -97,31 +97,31 @@ typedef struct f1ap_cp_tnl_s { uint16_t port; } f1ap_cp_tnl_t; -typedef enum f1ap_mode_t { F1AP_MODE_TDD = 0, F1AP_MODE_FDD = 1 } f1ap_mode_t; +typedef enum f1ap_mode_e { F1AP_MODE_TDD = 0, F1AP_MODE_FDD = 1 } f1ap_mode_t; -typedef struct f1ap_nr_frequency_info_t { +typedef struct f1ap_nr_frequency_info_s { uint32_t arfcn; int band; } f1ap_nr_frequency_info_t; -typedef struct f1ap_transmission_bandwidth_t { +typedef struct f1ap_transmission_bandwidth_s { uint8_t scs; uint16_t nrb; } f1ap_transmission_bandwidth_t; -typedef struct f1ap_fdd_info_t { +typedef struct f1ap_fdd_info_s { f1ap_nr_frequency_info_t ul_freqinfo; f1ap_nr_frequency_info_t dl_freqinfo; f1ap_transmission_bandwidth_t ul_tbw; f1ap_transmission_bandwidth_t dl_tbw; } f1ap_fdd_info_t; -typedef struct f1ap_tdd_info_t { +typedef struct f1ap_tdd_info_s { f1ap_nr_frequency_info_t freqinfo; f1ap_transmission_bandwidth_t tbw; } f1ap_tdd_info_t; -typedef struct f1ap_served_cell_info_t { +typedef struct f1ap_served_cell_info_s { // NR CGI (Mandatory) plmn_id_t plmn; uint64_t nr_cellid; // NR Global Cell Id @@ -143,7 +143,7 @@ typedef struct f1ap_served_cell_info_t { int measurement_timing_config_len; } f1ap_served_cell_info_t; -typedef struct f1ap_gnb_du_system_info_t { +typedef struct f1ap_gnb_du_system_info_s { // MIB message (Mandatory) uint8_t *mib; int mib_length; @@ -171,12 +171,12 @@ typedef struct f1ap_setup_req_s { } *cell; } f1ap_setup_req_t; -typedef struct f1ap_du_register_req_t { +typedef struct f1ap_du_register_req_s { f1ap_setup_req_t setup_req; f1ap_net_config_t net_config; } f1ap_du_register_req_t; -typedef struct f1ap_sib_msg_t { +typedef struct f1ap_sib_msg_s { /// RRC container with system information owned by gNB-CU uint8_t *SI_container; int SI_container_length; @@ -260,7 +260,7 @@ typedef struct f1ap_gnb_cu_configuration_update_failure_s { uint16_t criticality_diagnostics; } f1ap_gnb_cu_configuration_update_failure_t; -typedef struct f1ap_cell_status_t { +typedef struct f1ap_cell_status_s { // NR CGI plmn_id_t plmn; uint64_t nr_cellid; // NR Global Cell Id @@ -372,7 +372,7 @@ typedef enum preemption_vulnerability_e { PREEMPTABLE, } preemption_vulnerability_t; -typedef enum f1ap_rlc_mode_t { F1AP_RLC_MODE_AM, F1AP_RLC_MODE_UM_BIDIR, F1AP_RLC_UM_UNI_UL, F1AP_RLC_UM_UNI_DL } f1ap_rlc_mode_t; +typedef enum f1ap_rlc_mode_e { F1AP_RLC_MODE_AM, F1AP_RLC_MODE_UM_BIDIR, F1AP_RLC_UM_UNI_UL, F1AP_RLC_UM_UNI_DL } f1ap_rlc_mode_t; typedef struct f1ap_cu_to_du_rrc_info_s { byte_array_t *cg_configinfo; @@ -382,7 +382,7 @@ typedef struct f1ap_cu_to_du_rrc_info_s { byte_array_t *ho_prep_info; } f1ap_cu_to_du_rrc_info_t; -typedef struct f1ap_du_to_cu_rrc_info_t { +typedef struct f1ap_du_to_cu_rrc_info_s { byte_array_t cell_group_config; byte_array_t *meas_gap_config; } f1ap_du_to_cu_rrc_info_t; @@ -412,28 +412,28 @@ typedef enum lower_layer_status_e { LOWER_LAYERS_RESUME, } lower_layer_status_t; -typedef struct f1ap_srb_to_setup_t { +typedef struct f1ap_srb_to_setup_s { int id; } f1ap_srb_to_setup_t; -typedef struct f1ap_srb_setup_t { +typedef struct f1ap_srb_setup_s { int id; int lcid; } f1ap_srb_setup_t; /// 9.3.1.52 Packet Error Rate -typedef struct f1ap_per_t { +typedef struct f1ap_per_s { uint8_t scalar; uint8_t exponent; } f1ap_per_t; // 9.3.1.49 Non-Dynamic 5QI Descriptor -typedef struct f1ap_nondynamic_5qi_t { +typedef struct f1ap_nondynamic_5qi_s { int fiveQI; } f1ap_nondynamic_5qi_t; // 9.3.1.47 Dynamic 5QI Descriptor -typedef struct f1ap_dynamic_5qi_t { +typedef struct f1ap_dynamic_5qi_s { int prio; /// QoS Priority Level int pdb; /// Packet Delay Budget f1ap_per_t per; /// Packet Error Rate @@ -441,14 +441,14 @@ typedef struct f1ap_dynamic_5qi_t { int *avg_win; /// Averaging Window } f1ap_dynamic_5qi_t; -typedef struct f1ap_arp_t { +typedef struct f1ap_arp_s { uint16_t prio; preemption_capability_t preempt_cap; preemption_vulnerability_t preempt_vuln; } f1ap_arp_t; // 9.3.1.45 QoS Flow Level QoS Parameters -typedef struct f1ap_qos_flow_param_t { +typedef struct f1ap_qos_flow_param_s { fiveQI_t qos_type; union { f1ap_nondynamic_5qi_t nondyn; @@ -458,13 +458,13 @@ typedef struct f1ap_qos_flow_param_t { } f1ap_qos_flow_param_t; // in 9.2.2.1 Flows Mapped to DRB Item -typedef struct f1ap_drb_flows_mapped_t { +typedef struct f1ap_drb_flows_mapped_s { int qfi; f1ap_qos_flow_param_t param; } f1ap_drb_flows_mapped_t; /// in 9.2.2.1 DRB Info in UE Context Setup Request -typedef struct f1ap_drb_info_nr_t { +typedef struct f1ap_drb_info_nr_s { f1ap_qos_flow_param_t drb_qos; nssai_t nssai; int flows_len; @@ -473,7 +473,7 @@ typedef struct f1ap_drb_info_nr_t { typedef enum { F1AP_PDCP_SN_12B, F1AP_PDCP_SN_18B } f1ap_pdcp_sn_len_t; /// in 9.2.2.1 DRB to Be Setup Item IEs -typedef struct f1ap_drb_to_setup_t { +typedef struct f1ap_drb_to_setup_s { int id; enum { F1AP_QOS_CHOICE_EUTRAN, F1AP_QOS_CHOICE_NR } qos_choice; union { @@ -487,14 +487,14 @@ typedef struct f1ap_drb_to_setup_t { f1ap_pdcp_sn_len_t *ul_pdcp_sn_len; } f1ap_drb_to_setup_t; -typedef struct f1ap_drb_setup_t { +typedef struct f1ap_drb_setup_s { int id; int *lcid; int up_dl_tnl_len; f1ap_up_tnl_t up_dl_tnl[2]; } f1ap_drb_setup_t; -typedef struct f1ap_drb_to_release_t { +typedef struct f1ap_drb_to_release_s { int id; } f1ap_drb_to_release_t; @@ -534,7 +534,7 @@ typedef struct f1ap_ue_context_setup_resp_s { f1ap_srb_setup_t *srbs; } f1ap_ue_context_setup_resp_t; -typedef struct f1ap_ue_context_mod_req_t { +typedef struct f1ap_ue_context_mod_req_s { uint32_t gNB_CU_ue_id; uint32_t gNB_DU_ue_id; @@ -565,7 +565,7 @@ typedef struct f1ap_ue_context_mod_req_t { lower_layer_status_t *status; } f1ap_ue_context_mod_req_t; -typedef struct f1ap_ue_context_mod_resp { +typedef struct f1ap_ue_context_mod_resp_s { uint32_t gNB_CU_ue_id; uint32_t gNB_DU_ue_id; @@ -586,7 +586,7 @@ typedef enum F1ap_Cause_e { F1AP_CAUSE_MISC, } f1ap_Cause_t; -typedef struct f1ap_ue_context_modif_required_t { +typedef struct f1ap_ue_context_modif_required_s { uint32_t gNB_CU_ue_id; uint32_t gNB_DU_ue_id; du_to_cu_rrc_information_t *du_to_cu_rrc_information; @@ -594,28 +594,28 @@ typedef struct f1ap_ue_context_modif_required_t { long cause_value; } f1ap_ue_context_modif_required_t; -typedef struct f1ap_ue_context_modif_confirm_t { +typedef struct f1ap_ue_context_modif_confirm_s { uint32_t gNB_CU_ue_id; uint32_t gNB_DU_ue_id; uint8_t *rrc_container; int rrc_container_length; } f1ap_ue_context_modif_confirm_t; -typedef struct f1ap_ue_context_modif_refuse_t { +typedef struct f1ap_ue_context_modif_refuse_s { uint32_t gNB_CU_ue_id; uint32_t gNB_DU_ue_id; f1ap_Cause_t cause; long cause_value; } f1ap_ue_context_modif_refuse_t; -typedef struct f1ap_ue_context_rel_req_t { +typedef struct f1ap_ue_context_rel_req_s { uint32_t gNB_CU_ue_id; uint32_t gNB_DU_ue_id; f1ap_Cause_t cause; long cause_value; } f1ap_ue_context_rel_req_t; -typedef struct f1ap_ue_context_rel_cmd_t { +typedef struct f1ap_ue_context_rel_cmd_s { uint32_t gNB_CU_ue_id; uint32_t gNB_DU_ue_id; f1ap_Cause_t cause; @@ -627,7 +627,7 @@ typedef struct f1ap_ue_context_rel_cmd_t { uint32_t *old_gNB_DU_ue_id; // if after reestablishment request } f1ap_ue_context_rel_cmd_t; -typedef struct f1ap_ue_context_rel_cplt_t { +typedef struct f1ap_ue_context_rel_cplt_s { uint32_t gNB_CU_ue_id; uint32_t gNB_DU_ue_id; } f1ap_ue_context_rel_cplt_t; @@ -694,7 +694,7 @@ typedef struct { f1ap_paging_cell_item_t *cells; } f1ap_paging_t; -typedef struct f1ap_lost_connection_t { +typedef struct f1ap_lost_connection_s { int dummy; } f1ap_lost_connection_t; @@ -703,12 +703,12 @@ typedef enum F1AP_ResetType_e { F1AP_RESET_PART_OF_F1_INTERFACE } f1ap_ResetType_t; -typedef struct f1ap_ue_to_reset_t { +typedef struct f1ap_ue_to_reset_s { uint32_t *gNB_CU_ue_id; uint32_t *gNB_DU_ue_id; } f1ap_ue_to_reset_t; -typedef struct f1ap_reset_t { +typedef struct f1ap_reset_s { uint64_t transaction_id; f1ap_Cause_t cause; long cause_value; @@ -717,7 +717,7 @@ typedef struct f1ap_reset_t { f1ap_ue_to_reset_t *ue_to_reset; // array of num_ue_to_reset elements } f1ap_reset_t; -typedef struct f1ap_reset_ack_t { +typedef struct f1ap_reset_ack_s { uint64_t transaction_id; int num_ue_to_reset; f1ap_ue_to_reset_t *ue_to_reset; // array of num_ue_to_reset elements diff --git a/openair2/COMMON/ngap_messages_def.h b/openair2/COMMON/ngap_messages_def.h index 09e893f874..b1ffe77bc1 100644 --- a/openair2/COMMON/ngap_messages_def.h +++ b/openair2/COMMON/ngap_messages_def.h @@ -73,6 +73,7 @@ MESSAGE_DEF(NGAP_HANDOVER_NOTIFY, MESSAGE_PRIORITY_MED, ngap_handover_notify_t, MESSAGE_DEF(NGAP_HANDOVER_CANCEL, MESSAGE_PRIORITY_MED, ngap_handover_cancel_t, ngap_handover_cancel) MESSAGE_DEF(NGAP_UL_RAN_STATUS_TRANSFER, MESSAGE_PRIORITY_MED, ngap_ran_status_transfer_t, ngap_ul_ran_status_transfer) MESSAGE_DEF(NGAP_DL_RAN_STATUS_TRANSFER, MESSAGE_PRIORITY_MED, ngap_ran_status_transfer_t, ngap_dl_ran_status_transfer) +MESSAGE_DEF(NGAP_RECONNECT_TIMER, MESSAGE_PRIORITY_MED, IttiMsgText, ngap_gNB_amf_data) /* NGAP -> RRC messages */ MESSAGE_DEF(NGAP_DOWNLINK_NAS , MESSAGE_PRIORITY_MED, ngap_downlink_nas_t , ngap_downlink_nas ) @@ -88,3 +89,18 @@ MESSAGE_DEF(NGAP_HANDOVER_CANCEL_ACK, MESSAGE_PRIORITY_MED, ngap_handover_cancel /* NGAP <-> RRC messages (can be initiated either by MME or gNB) */ MESSAGE_DEF(NGAP_UE_CONTEXT_RELEASE_REQ , MESSAGE_PRIORITY_MED, ngap_ue_release_req_t , ngap_ue_release_req) + +/* NGAP -> NRPPA messages*/ +MESSAGE_DEF(NGAP_DOWNLINKUEASSOCIATEDNRPPA, + MESSAGE_PRIORITY_MED, + ngap_downlink_ue_associated_nrppa_t, + ngap_downlink_ue_associated_nrppa) +MESSAGE_DEF(NGAP_DOWNLINKNONUEASSOCIATEDNRPPA, + MESSAGE_PRIORITY_MED, + ngap_downlink_non_ue_associated_nrppa_t, + ngap_downlink_non_ue_associated_nrppa) +MESSAGE_DEF(NGAP_UPLINKUEASSOCIATEDNRPPA, MESSAGE_PRIORITY_MED, ngap_uplink_ue_associated_nrppa_t, ngap_uplink_ue_associated_nrppa) +MESSAGE_DEF(NGAP_UPLINKNONUEASSOCIATEDNRPPA, + MESSAGE_PRIORITY_MED, + ngap_uplink_non_ue_associated_nrppa_t, + ngap_uplink_non_ue_associated_nrppa) diff --git a/openair2/COMMON/ngap_messages_types.h b/openair2/COMMON/ngap_messages_types.h index 02069d056e..85d61bba39 100644 --- a/openair2/COMMON/ngap_messages_types.h +++ b/openair2/COMMON/ngap_messages_types.h @@ -79,6 +79,11 @@ #define NGAP_UL_RAN_STATUS_TRANSFER(mSGpTR) (mSGpTR)->ittiMsg.ngap_ul_ran_status_transfer #define NGAP_DL_RAN_STATUS_TRANSFER(mSGpTR) (mSGpTR)->ittiMsg.ngap_dl_ran_status_transfer +#define NGAP_DOWNLINKUEASSOCIATEDNRPPA(mSGpTR) (mSGpTR)->ittiMsg.ngap_downlink_ue_associated_nrppa +#define NGAP_DOWNLINKNONUEASSOCIATEDNRPPA(mSGpTR) (mSGpTR)->ittiMsg.ngap_downlink_non_ue_associated_nrppa + +#define NGAP_UPLINKUEASSOCIATEDNRPPA(mSGpTR) (mSGpTR)->ittiMsg.ngap_uplink_ue_associated_nrppa +#define NGAP_UPLINKNONUEASSOCIATEDNRPPA(mSGpTR) (mSGpTR)->ittiMsg.ngap_uplink_non_ue_associated_nrppa //-------------------------------------------------------------------------------------------// /* Length of the transport layer address string @@ -1007,4 +1012,44 @@ typedef struct { ngap_ran_status_container_t ran_status; } ngap_ran_status_transfer_t; +// Uplink UE Associated NRPPA Transport message (9.2.9.2 3GPP 38.413 v16.0.0) +typedef struct { + // AMF UE NGAP ID (Mandatory) + uint64_t amf_ue_ngap_id; + // RAN UE NGAP ID (Mandatory) + uint32_t gNB_ue_ngap_id; + // Routing ID (Mandatory) + byte_array_t routing_id; + // NRPPa pdu (Mandatory) + byte_array_t nrppa_pdu; +} ngap_uplink_ue_associated_nrppa_t; + +// Uplink NON UE Associated NRPPA Transport message (9.2.9.4 3GPP 38.413 v16.0.0) +typedef struct { + // Routing ID (Mandatory) + byte_array_t routing_id; + // NRPPa pdu (Mandatory) + byte_array_t nrppa_pdu; +} ngap_uplink_non_ue_associated_nrppa_t; + +// Downlink UE Associated NRPPA Transport message (9.2.9.1 3GPP 38.413 v16.0.0) +typedef struct { + // AMF UE NGAP ID (Mandatory) + uint64_t amf_ue_ngap_id; + // RAN UE NGAP ID (Mandatory) + uint32_t gNB_ue_ngap_id; + // Routing ID (Mandatory) + byte_array_t routing_id; + // NRPPa pdu (Mandatory) + byte_array_t nrppa_pdu; +} ngap_downlink_ue_associated_nrppa_t; + +// Downlink NON UE Associated NRPPA Transport message (9.2.9.3 3GPP 38.413 v16.0.0) +typedef struct { + // Routing ID (Mandatory) + byte_array_t routing_id; + // NRPPa pdu (Mandatory) + byte_array_t nrppa_pdu; +} ngap_downlink_non_ue_associated_nrppa_t; + #endif /* NGAP_MESSAGES_TYPES_H_ */ diff --git a/openair2/COMMON/nrppa_messages_def.h b/openair2/COMMON/nrppa_messages_def.h new file mode 100644 index 0000000000..aa40adce44 --- /dev/null +++ b/openair2/COMMON/nrppa_messages_def.h @@ -0,0 +1,44 @@ +/* + * 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 "openair2/COMMON/nrppa_messages_types.h" + +// LMF -> CU +MESSAGE_DEF(NRPPA_TRP_INFORMATION_REQ, MESSAGE_PRIORITY_MED, nrppa_trp_information_req_t, nrppa_trp_information_req) +MESSAGE_DEF(NRPPA_TRP_INFORMATION_RESP, MESSAGE_PRIORITY_MED, nrppa_trp_information_resp_t, nrppa_trp_information_resp) +MESSAGE_DEF(NRPPA_POSITIONING_INFORMATION_REQ, + MESSAGE_PRIORITY_MED, + nrppa_positioning_information_req_t, + nrppa_positioning_information_req) +MESSAGE_DEF(NRPPA_POSITIONING_INFORMATION_RESP, + MESSAGE_PRIORITY_MED, + nrppa_positioning_information_resp_t, + nrppa_positioning_information_resp) +MESSAGE_DEF(NRPPA_POSITIONING_ACTIVATION_REQ, + MESSAGE_PRIORITY_MED, + nrppa_positioning_activation_req_t, + nrppa_positioning_activation_req) +MESSAGE_DEF(NRPPA_POSITIONING_ACTIVATION_RESP, + MESSAGE_PRIORITY_MED, + nrppa_positioning_activation_resp_t, + nrppa_positioning_activation_resp) +MESSAGE_DEF(NRPPA_MEASUREMENT_REQ, MESSAGE_PRIORITY_MED, nrppa_measurement_req_t, nrppa_measurement_req) +MESSAGE_DEF(NRPPA_MEASUREMENT_RESP, MESSAGE_PRIORITY_MED, nrppa_measurement_resp_t, nrppa_measurement_resp) diff --git a/openair2/COMMON/nrppa_messages_types.h b/openair2/COMMON/nrppa_messages_types.h new file mode 100644 index 0000000000..881362231d --- /dev/null +++ b/openair2/COMMON/nrppa_messages_types.h @@ -0,0 +1,824 @@ +/* + * 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 NRPPA_MESSAGES_TYPES_H_ +#define NRPPA_MESSAGES_TYPES_H_ + +// Defines to access message fields. + +#define NRPPA_TRP_INFORMATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nrppa_trp_information_req +#define NRPPA_TRP_INFORMATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.nrppa_trp_information_resp +#define NRPPA_POSITIONING_INFORMATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nrppa_positioning_information_req +#define NRPPA_POSITIONING_INFORMATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.nrppa_positioning_information_resp +#define NRPPA_POSITIONING_ACTIVATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nrppa_positioning_activation_req +#define NRPPA_POSITIONING_ACTIVATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.nrppa_positioning_activation_resp +#define NRPPA_MEASUREMENT_REQ(mSGpTR) (mSGpTR)->ittiMsg.nrppa_measurement_req +#define NRPPA_MEASUREMENT_RESP(mSGpTR) (mSGpTR)->ittiMsg.nrppa_measurement_resp + +/* Structure of Positioning related NRPPA messages */ +/* IE structures for Positioning related messages as per TS 38.455 V16.7.1*/ + +typedef enum nrppa_trp_information_type_item_e { + NRPPA_TRP_INFORMATION_TYPE_ITEM_NR_PCI, + NRPPA_TRP_INFORMATION_TYPE_ITEM_NG_RAN_CGI, + NRPPA_TRP_INFORMATION_TYPE_ITEM_NR_ARFCN, + NRPPA_TRP_INFORMATION_TYPE_ITEM_PRS_CONFIG, + NRPPA_TRP_INFORMATION_TYPE_ITEM_SSB_CONFIG, + NRPPA_TRP_INFORMATION_TYPE_ITEM_SFN_INIT_TIME, + NRPPA_TRP_INFORMATION_TYPE_ITEM_SPATIAL_DIRECTION_INFO, + NRPPA_TRP_INFORMATION_TYPE_ITEM_GEO_COORDINATES +} nrppa_trp_information_type_item_pr; + +typedef struct nrppa_trp_information_type_list_s { + nrppa_trp_information_type_item_pr *trp_information_type_item; + uint8_t trp_information_type_list_length; +} nrppa_trp_information_type_list_t; + +typedef struct nrppa_trp_list_item_s { + uint32_t trp_id; +} nrppa_trp_list_item_t; + +typedef struct nrppa_trp_list_s { + nrppa_trp_list_item_t *trp_list_item; + uint32_t trp_list_length; +} nrppa_trp_list_t; + +typedef struct nrppa_access_point_position_s { + long latitude_sign; + long latitude; + long longitude; + long direction_of_altitude; + long altitude; + long uncertainty_semi_major; + long uncertainty_semi_minor; + long orientation_of_major_axis; + long uncertainty_altitude; + long confidence; +} nrppa_access_point_position_t; + +typedef struct nrppa_ngran_high_accuracy_access_point_position_s { + long latitude; + long longitude; + long altitude; + long uncertainty_semi_major; + long uncertainty_semi_minor; + long orientation_of_major_axis; + long horizontal_confidence; + long uncertainty_altitude; + long vertical_confidence; +} nrppa_ngran_high_accuracy_access_point_position_t; + +typedef union nrppa_trp_position_direct_accuracy_c { + nrppa_access_point_position_t trp_position; + nrppa_ngran_high_accuracy_access_point_position_t trp_HAposition; +} nrppa_trp_position_direct_accuracy_u; + +typedef enum nrppa_trp_position_direct_accuracy_e { + NRPPA_TRP_POSITION_DIRECT_ACCURACY_PR_NOTHING, + NRPPA_TRP_POSITION_DIRECT_ACCURACY_PR_TRPPOSITION, + NRPPA_TRP_POSITION_DIRECT_ACCURACY_PR_TRPHAPOSITION +} nrppa_trp_position_direct_accuracy_pr; + +typedef struct nrppa_trp_position_direct_accuracy_s { + nrppa_trp_position_direct_accuracy_pr present; + nrppa_trp_position_direct_accuracy_u choice; +} nrppa_trp_position_direct_accuracy_t; + +typedef struct nrppa_trp_position_direct_s { + nrppa_trp_position_direct_accuracy_t accuracy; +} nrppa_trp_position_direct_t; + +typedef enum nrppa_reference_point_e { + NRPPA_REFERENCE_POINT_PR_NOTHING, + NRPPA_REFERENCE_POINT_PR_COORDINATEID, + NRPPA_REFERENCE_POINT_PR_REFERENCEPOINTCOORDINATE, + NRPPA_REFERENCE_POINT_PR_REFERENCEPOINTCOORDINATEHA +} nrppa_reference_point_pr; + +typedef union nrppa_reference_point_c { + long coordinate_id; + nrppa_access_point_position_t reference_point_coordinate; + nrppa_ngran_high_accuracy_access_point_position_t reference_point_coordinateHA; +} nrppa_reference_point_u; + +typedef struct nrppa_reference_point_s { + nrppa_reference_point_pr present; + nrppa_reference_point_u choice; +} nrppa_reference_point_t; + +typedef struct nrppa_location_uncertainty_s { + long horizontal_uncertainty; + long horizontal_confidence; + long vertical_uncertainty; + long vertical_confidence; +} nrppa_location_uncertainty_t; + +typedef struct nrppa_relative_geodetic_location_s { + long milli_arc_second_units; + long height_units; + long delta_latitude; + long delta_longitude; + long delta_height; + nrppa_location_uncertainty_t location_uncertainty; +} nrppa_relative_geodetic_location_t; + +typedef struct nrppa_relative_cartesian_location_s { + long xyz_unit; + long xvalue; + long yvalue; + long zvalue; + nrppa_location_uncertainty_t location_uncertainty; +} nrppa_relative_cartesian_location_t; + +typedef union nrppa_trp_reference_point_type_c { + nrppa_relative_geodetic_location_t trp_position_relative_geodetic; + nrppa_relative_cartesian_location_t trp_position_relative_cartesian; +} nrppa_trp_reference_point_type_u; + +typedef enum nrppa_trp_reference_point_type_e { + NRPPA_TRP_REFERENCE_POINT_TYPE_PR_NOTHING, + NRPPA_TRP_REFERENCE_POINT_TYPE_PR_TRPPOSITION_RELATIVE_GEODETIC, + NRPPA_TRP_REFERENCE_POINT_TYPE_PR_TRPPOSITION_RELATIVE_CARTESIAN +} nrppa_trp_reference_point_type_pr; + +typedef struct nrppa_trp_reference_point_type_t { + nrppa_trp_reference_point_type_pr present; + nrppa_trp_reference_point_type_u choice; +} nrppa_trp_reference_point_type_t; + +typedef struct nrppa_trp_position_referenced_t { + nrppa_reference_point_t reference_point; + nrppa_trp_reference_point_type_t reference_point_type; +} nrppa_trp_position_referenced_t; + +typedef union nrppa_trp_position_definition_type_c { + nrppa_trp_position_direct_t direct; + nrppa_trp_position_referenced_t referenced; +} nrppa_trp_position_definition_type_u; + +typedef enum nrppa_trp_position_definition_type_e { + NRPPA_TRP_POSITION_DEFINITION_TYPE_PR_NOTHING, + NRPPA_TRP_POSITION_DEFINITION_TYPE_PR_DIRECT, + NRPPA_TRP_POSITION_DEFINITION_TYPE_PR_REFERENCED +} nrppa_trp_position_definition_type_pr; + +typedef struct nrppa_trp_position_definition_type_s { + nrppa_trp_position_definition_type_u choice; + nrppa_trp_position_definition_type_pr present; +} nrppa_trp_position_definition_type_t; + +typedef struct nrppa_geographical_coordinates_s { + nrppa_trp_position_definition_type_t trp_position_definition_type; +} nrppa_geographical_coordinates_t; + +typedef struct nrppa_ng_ran_cgi_s { + plmn_id_t plmn; + uint64_t nr_cellid; +} nrppa_ng_ran_cgi_t; + +typedef union nrppa_trp_information_type_response_item_c { + uint16_t pci_nr; + nrppa_ng_ran_cgi_t ng_ran_cgi; + uint32_t nr_arfcn; + nrppa_geographical_coordinates_t geographical_coordinates; +} nrppa_trp_information_type_response_item_u; + +typedef enum nrppa_trp_information_type_response_item_e { + NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NOTHING, + NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_PCI_NR, + NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NG_RAN_CGI, + NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NRARFCN, + NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_PRSCONFIGURATION, + NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SSBINFORMATION, + NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SFNINITIALISATIONTIME, + NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SPATIALDIRECTIONINFORMATION, + NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_GEOGRAPHICALCOORDINATES +} nrppa_trp_information_type_response_item_pr; + +typedef struct nrppa_trp_information_type_response_item_s { + nrppa_trp_information_type_response_item_pr present; + nrppa_trp_information_type_response_item_u choice; +} nrppa_trp_information_type_response_item_t; + +typedef struct nrppa_trp_information_type_response_list_s { + nrppa_trp_information_type_response_item_t *trp_information_type_response_item; + uint8_t trp_information_type_response_item_length; +} nrppa_trp_information_type_response_list_t; + +typedef struct nrppa_trp_information_s { + uint32_t trp_id; + nrppa_trp_information_type_response_list_t trp_information_type_response_list; +} nrppa_trp_information_t; + +typedef enum nrppa_subcarrier_spacing_e { + NRPPA_SUBCARRIER_SPACING_15KHZ, + NRPPA_SUBCARRIER_SPACING_30KHZ, + NRPPA_SUBCARRIER_SPACING_60KHZ, + NRPPA_SUBCARRIER_SPACING_120KHZ +} nrppa_subcarrier_spacing_pr; + +typedef struct nrppa_scs_specific_carrier_s { + uint32_t offset_to_carrier; + nrppa_subcarrier_spacing_pr subcarrier_spacing; + uint16_t carrier_bandwidth; +} nrppa_scs_specific_carrier_t; + +typedef struct nrppa_uplink_channel_bw_per_scs_list_s { + nrppa_scs_specific_carrier_t *scs_specific_carrier; + uint32_t scs_specific_carrier_list_length; +} nrppa_uplink_channel_bw_per_scs_list_t; + +typedef enum nrppa_transmission_comb_e { + NRPPA_TRANSMISSION_COMB_PR_NOTHING, + NRPPA_TRANSMISSION_COMB_PR_N2, + NRPPA_TRANSMISSION_COMB_PR_N4 +} nrppa_transmission_comb_pr; + +typedef struct nrppa_transmission_comb_n2_s { + uint8_t comb_offset_n2; + uint8_t cyclic_shift_n2; +} nrppa_transmission_comb_n2_t, nrppa_transmission_comb_pos_n2_t; + +typedef struct nrppa_transmission_comb_n4_s { + uint8_t comb_offset_n4; + uint8_t cyclic_shift_n4; +} nrppa_transmission_comb_n4_t, nrppa_transmission_comb_pos_n4_t; + +typedef union nrppa_transmission_comb_c { + nrppa_transmission_comb_n2_t n2; + nrppa_transmission_comb_n4_t n4; +} nrppa_transmission_comb_u; + +typedef struct nrppa_transmission_comb_s { + nrppa_transmission_comb_pr present; + nrppa_transmission_comb_u choice; +} nrppa_transmission_comb_t; + +typedef enum nrppa_srs_resource_type_periodicity_e { + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT1 = 0, + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT2, + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT4, + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT5, + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT8, + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT10, + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT16, + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT20, + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT32, + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT40, + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT64, + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT80, + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT160, + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT320, + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT640, + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT1280, + NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT2560 +} nrppa_srs_resource_type_periodicity_pr; + +typedef struct nrppa_resource_type_periodic_s { + nrppa_srs_resource_type_periodicity_pr periodicity; + uint16_t offset; +} nrppa_resource_type_periodic_t, nrppa_resource_type_semi_persistent_t; + +typedef union nrppa_resource_type_c { + nrppa_resource_type_periodic_t periodic; + nrppa_resource_type_semi_persistent_t semi_persistent; + bool aperiodic; +} nrppa_resource_type_u; + +typedef enum nrppa_resource_type_e { + NRPPA_RESOURCE_TYPE_PR_NOTHING, + NRPPA_RESOURCE_TYPE_PR_PERIODIC, + NRPPA_RESOURCE_TYPE_PR_SEMI_PERSISTENT, + NRPPA_RESOURCE_TYPE_PR_APERIODIC +} nrppa_resource_type_pr; + +typedef struct nrppa_resource_type_s { + nrppa_resource_type_pr present; + nrppa_resource_type_u choice; +} nrppa_resource_type_t; + +typedef struct nrppa_transmission_comb_n8_s { + uint8_t comb_offset_n8; + uint8_t cyclic_shift_n8; +} nrppa_transmission_comb_pos_n8_t; + +typedef union nrppa_transmission_comb_pos_c { + nrppa_transmission_comb_pos_n2_t n2; + nrppa_transmission_comb_pos_n4_t n4; + nrppa_transmission_comb_pos_n8_t n8; +} nrppa_transmission_comb_pos_u; + +typedef enum nrppa_transmission_comb_pos_e { + NRPPA_TRANSMISSION_COMB_POS_PR_NOTHING, + NRPPA_TRANSMISSION_COMB_POS_PR_N2, + NRPPA_TRANSMISSION_COMB_POS_PR_N4, + NRPPA_TRANSMISSION_COMB_POS_PR_N8 +} nrppa_transmission_comb_pos_pr; + +typedef struct nrppa_transmission_comb_pos_s { + nrppa_transmission_comb_pos_pr present; + nrppa_transmission_comb_pos_u choice; +} nrppa_transmission_comb_pos_t; + +typedef enum nrppa_srs_resource_type_pos_periodicity_e { + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT1 = 0, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT2, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT4, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT5, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT8, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT10, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT16, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT20, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT32, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT40, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT64, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT80, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT160, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT320, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT640, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT1280, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT2560, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT5120, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT10240, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT20480, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT40960, + NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT81920 +} nrppa_srs_resource_type_pos_periodicity_pr; + +typedef struct nrppa_resource_type_periodic_pos_s { + nrppa_srs_resource_type_pos_periodicity_pr periodicity; + uint16_t offset; +} nrppa_resource_type_periodic_pos_t, nrppa_resource_type_semi_persistent_pos_t; + +typedef struct nrppa_resource_type_aperiodic_pos_s { + uint8_t slot_offset; +} nrppa_resource_type_aperiodic_pos_t; + +typedef union nrppa_resource_type_pos_c { + nrppa_resource_type_periodic_pos_t periodic; + nrppa_resource_type_semi_persistent_pos_t semi_persistent; + nrppa_resource_type_aperiodic_pos_t aperiodic; +} nrppa_resource_type_pos_u; + +typedef enum nrppa_resource_type_pos_e { + NRPPA_RESOURCE_TYPE_POS_PR_NOTHING, + NRPPA_RESOURCE_TYPE_POS_PR_PERIODIC, + NRPPA_RESOURCE_TYPE_POS_PR_SEMI_PERSISTENT, + NRPPA_RESOURCE_TYPE_POS_PR_APERIODIC +} nrppa_resource_type_pos_pr; + +typedef struct nrppa_resource_type_pos_s { + nrppa_resource_type_pos_pr present; + nrppa_resource_type_pos_u choice; +} nrppa_resource_type_pos_t; + +typedef struct nrppa_srs_resource_id_list_s { + long *srs_resource_id; + uint8_t srs_resource_id_list_length; +} nrppa_srs_resource_id_list_t; + +typedef struct nrppa_resource_set_type_aperiodic_s { + uint8_t srs_resource_trigger; + long slot_offset; +} nrppa_resource_set_type_aperiodic_t; + +typedef union nrppa_resource_set_type_c { + bool periodic; + bool semi_persistent; + nrppa_resource_set_type_aperiodic_t aperiodic; +} nrppa_resource_set_type_u; + +typedef enum nrppa_resource_set_type_e { + NRPPA_RESOURCE_SET_TYPE_PR_NOTHING, + NRPPA_RESOURCE_SET_TYPE_PR_PERIODIC, + NRPPA_RESOURCE_SET_TYPE_PR_SEMI_PERSISTENT, + NRPPA_RESOURCE_SET_TYPE_PR_APERIODIC +} nrppa_resource_set_type_pr; + +typedef struct nrppa_resource_set_type_s { + nrppa_resource_set_type_pr present; + nrppa_resource_set_type_u choice; +} nrppa_resource_set_type_t; + +typedef struct nrppa_pos_srs_resource_id_list_s { + long *srs_pos_resource_id; + uint32_t pos_srs_resource_id_list_length; +} nrppa_pos_srs_resource_id_list_t; + +typedef union nrppa_pos_resource_set_type_c { + bool periodic; + bool semi_persistent; + uint8_t srs_resource; +} nrppa_pos_resource_set_type_u; + +typedef enum nrppa_pos_resource_set_type_e { + NRPPA_POS_RESOURCE_SET_TYPE_PR_NOTHING, + NRPPA_POS_RESOURCE_SET_TYPE_PR_PERIODIC, + NRPPA_POS_RESOURCE_SET_TYPE_PR_SEMI_PERSISTENT, + NRPPA_POS_RESOURCE_SET_TYPE_PR_APERIODIC +} nrppa_pos_resource_set_type_pr; + +typedef struct nrppa_pos_resource_set_type_s { + nrppa_pos_resource_set_type_pr present; + nrppa_pos_resource_set_type_u choice; +} nrppa_pos_resource_set_type_t; + +typedef enum nrppa_srs_resource_number_of_ports_e { + NRPPA_SRS_NUMBER_OF_PORTS_N1, + NRPPA_SRS_NUMBER_OF_PORTS_N2, + NRPPA_SRS_NUMBER_OF_PORTS_N4 +} nrppa_srs_resource_number_of_ports_pr; + +typedef enum nrppa_srs_resource_number_of_symbols_e { + NRPPA_SRS_NUMBER_OF_SYMBOLS_N1, + NRPPA_SRS_NUMBER_OF_SYMBOLS_N2, + NRPPA_SRS_NUMBER_OF_SYMBOLS_N4 +} nrppa_srs_resource_number_of_symbols_pr; + +typedef enum nrppa_srs_repetition_factor_e { + NRPPA_SRS_REPETITION_FACTOR_RF1, + NRPPA_SRS_REPETITION_FACTOR_RF2, + NRPPA_SRS_REPETITION_FACTOR_RF4 +} nrppa_srs_repetition_factor_pr; + +typedef enum nrppa_srs_group_or_sequencehopping_e { + NRPPA_GROUPORSEQUENCEHOPPING_NOTHING, + NRPPA_GROUPORSEQUENCEHOPPING_GROUPHOPPING, + NRPPA_GROUPORSEQUENCEHOPPING_SEQUENCEHOPPING +} nrppa_srs_group_or_sequencehopping_pr; + +typedef struct nrppa_srs_resource_s { + uint32_t srs_resource_id; + nrppa_srs_resource_number_of_ports_pr nr_of_srs_ports; + nrppa_transmission_comb_t transmission_comb; + uint8_t start_position; + nrppa_srs_resource_number_of_symbols_pr nr_of_symbols; + nrppa_srs_repetition_factor_pr repetition_factor; + uint8_t freq_domain_position; + uint16_t freq_domain_shift; + uint8_t c_srs; + uint8_t b_srs; + uint8_t b_hop; + nrppa_srs_group_or_sequencehopping_pr group_or_sequence_hopping; + nrppa_resource_type_t resource_type; + uint16_t sequence_id; +} nrppa_srs_resource_t; + +typedef enum nrppa_srs_resource_item_number_of_symbols_e { + NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N1, + NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N2, + NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N4, + NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N8, + NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N12 +} nrppa_srs_resource_item_number_of_symbols_pr; + +typedef struct nrppa_pos_srs_resource_item_s { + uint32_t srs_pos_resource_id; + nrppa_transmission_comb_pos_t transmission_comb_pos; + uint8_t start_position; + nrppa_srs_resource_item_number_of_symbols_pr nr_of_symbols; + uint16_t freq_domain_shift; + uint8_t c_srs; + nrppa_srs_group_or_sequencehopping_pr group_or_sequence_hopping; + nrppa_resource_type_pos_t resource_type_pos; + uint32_t sequence_id; +} nrppa_pos_srs_resource_item_t; + +typedef struct nrppa_srs_resource_set_s { + uint8_t srs_resource_set_id; + nrppa_srs_resource_id_list_t srs_resource_id_list; + nrppa_resource_set_type_t resource_set_type; +} nrppa_srs_resource_set_t; + +typedef struct nrppa_pos_srs_resource_set_item_s { + uint8_t pos_srs_resource_set_id; + nrppa_pos_srs_resource_id_list_t pos_srs_resource_id_list; + nrppa_pos_resource_set_type_t pos_resource_set_type; +} nrppa_pos_srs_resource_set_item_t; + +typedef struct nrppa_srs_resource_list_s { + nrppa_srs_resource_t *srs_resource; + uint32_t srs_resource_list_length; +} nrppa_srs_resource_list_t; + +typedef struct nrppa_pos_srs_resource_list_s { + nrppa_pos_srs_resource_item_t *pos_srs_resource_item; + uint32_t pos_srs_resource_list_length; +} nrppa_pos_srs_resource_list_t; + +typedef struct nrppa_srs_resource_set_list_s { + nrppa_srs_resource_set_t *srs_resource_set; + uint32_t srs_resource_set_list_length; +} nrppa_srs_resource_set_list_t; + +typedef struct nrppa_pos_srs_resource_set_list_s { + nrppa_pos_srs_resource_set_item_t *pos_srs_resource_set_item; + uint32_t pos_srs_resource_set_list_length; +} nrppa_pos_srs_resource_set_list_t; + +typedef struct nrppa_srs_config_s { + nrppa_srs_resource_list_t *srs_resource_list; + nrppa_pos_srs_resource_list_t *pos_srs_resource_list; + nrppa_srs_resource_set_list_t *srs_resource_set_list; + nrppa_pos_srs_resource_set_list_t *pos_srs_resource_set_list; +} nrppa_srs_config_t; + +typedef enum nrppa_cp_type_e { NRPPA_CP_TYPE_NORMAL, NRPPA_CP_TYPE_EXTENDED } nrppa_cp_type_pr; + +typedef struct nrppa_active_ul_bwp_s { + uint32_t location_and_bandwidth; + nrppa_subcarrier_spacing_pr subcarrier_spacing; + nrppa_cp_type_pr cyclic_prefix; + uint32_t tx_direct_current_location; + uint8_t shift_7_dot_5kHz; + nrppa_srs_config_t srs_config; +} nrppa_active_ul_bwp_t; + +typedef struct nrppa_srs_carrier_list_item_s { + uint32_t pointA; + nrppa_uplink_channel_bw_per_scs_list_t uplink_channel_bw_per_scs_list; + nrppa_active_ul_bwp_t active_ul_bwp; + uint16_t pci; +} nrppa_srs_carrier_list_item_t; + +typedef struct nrppa_srs_carrier_list_s { + nrppa_srs_carrier_list_item_t *srs_carrier_list_item; + uint32_t srs_carrier_list_length; +} nrppa_srs_carrier_list_t; + +typedef struct nrppa_srs_configuration_s { + nrppa_srs_carrier_list_t srs_carrier_list; +} nrppa_srs_configuration_t; + +// IE 9.3.1.176 (TS 38.473 V16.21.0) +typedef struct nrppa_trp_information_list_s { + nrppa_trp_information_t *trp_information_item; + uint32_t trp_information_item_length; +} nrppa_trp_information_list_t; + +typedef union nrppa_srs_type_c { + uint8_t *srs_resource_set_id; + bool *aperiodic; +} nrppa_srs_type_u; + +typedef enum nrppa_srs_type_e { + NRPPA_SRS_TYPE_PR_NOTHING, + NRPPA_SRS_TYPE_PR_SEMIPERSISTENTSRS, + NRPPA_SRS_TYPE_PR_APERIODICSRS +} nrppa_srs_type_pr; + +typedef struct nrppa_srs_type_s { + nrppa_srs_type_pr present; + nrppa_srs_type_u choice; +} nrppa_srs_type_t; + +typedef struct nrppa_trp_measurement_request_item_s { + uint32_t trp_id; +} nrppa_trp_measurement_request_item_t; + +typedef struct nrppa_trp_measurement_request_list_s { + nrppa_trp_measurement_request_item_t *trp_measurement_request_item; + uint32_t trp_measurement_request_list_length; +} nrppa_trp_measurement_request_list_t; + +typedef enum nrppa_pos_report_characteristics_e { + NRPPA_POSREPORTCHARACTERISTICS_ONDEMAND = 0, + NRPPA_POSREPORTCHARACTERISTICS_PERIODIC = 1 +} nrppa_report_characteristics_pr; + +typedef enum nrppa_pos_measurement_periodicity_e { + NRPPA_POSMEASUREMENTPERIODICITY_MS120 = 0, + NRPPA_POSMEASUREMENTPERIODICITY_MS240 = 1, + NRPPA_POSMEASUREMENTPERIODICITY_MS480 = 2, + NRPPA_POSMEASUREMENTPERIODICITY_MS640 = 3, + NRPPA_POSMEASUREMENTPERIODICITY_MS1024 = 4, + NRPPA_POSMEASUREMENTPERIODICITY_MS2048 = 5, + NRPPA_POSMEASUREMENTPERIODICITY_MS5120 = 6, + NRPPA_POSMEASUREMENTPERIODICITY_MS10240 = 7, + NRPPA_POSMEASUREMENTPERIODICITY_MIN1 = 8, + NRPPA_POSMEASUREMENTPERIODICITY_MIN6 = 9, + NRPPA_POSMEASUREMENTPERIODICITY_MIN12 = 10, + NRPPA_POSMEASUREMENTPERIODICITY_MIN30 = 11, + NRPPA_POSMEASUREMENTPERIODICITY_MIN60 = 12 +} nrppa_measurement_periodicity_pr; + +typedef enum nrppa_pos_measurement_type_e { + NRPPA_POSMEASUREMENTTYPE_GNB_RX_TX = 0, + NRPPA_POSMEASUREMENTTYPE_UL_SRS_RSRP = 1, + NRPPA_POSMEASUREMENTTYPE_UL_AOA = 2, + NRPPA_POSMEASUREMENTTYPE_UL_RTOA = 3 +} nrppa_measurement_type_pr; + +typedef struct nrppa_pos_measurement_quantities_item_s { + nrppa_measurement_type_pr measurement_type; +} nrppa_measurement_quantities_item_t; + +typedef struct nrppa_pos_measurement_quantities_s { + nrppa_measurement_quantities_item_t *measurement_quantities_item; + uint32_t measurement_quantities_length; +} nrppa_measurement_quantities_t; + +typedef struct nrppa_lcs_to_gcs_translationaoa_c { + uint16_t alpha; + uint16_t beta; + uint16_t gamma; +} nrppa_lcs_to_gcs_translationaoa_t; + +typedef struct nrppa_ul_aoa_s { + uint16_t azimuth_aoa; + uint16_t *zenith_aoa; + nrppa_lcs_to_gcs_translationaoa_t *lcs_to_gcs_translation_aoa; +} nrppa_ul_aoa_t; + +typedef union nrppa_relative_path_delay_c { + uint32_t k0; + uint32_t k1; + uint32_t k2; + uint32_t k3; + uint32_t k4; + uint32_t k5; +} nrppa_relative_path_delay_u, nrppa_ul_rtoa_measurement_u, nrppa_gnb_rx_tx_time_diff_u; + +typedef enum nrppa_gnb_rx_tx_time_diff_meas_e { + NRPPA_GNBRXTXTIMEDIFFMEAS_PR_NOTHING, + NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K0, + NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K1, + NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K2, + NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K3, + NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K4, + NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K5 +} nrppa_gnb_rx_tx_time_diff_pr; + +typedef struct nrppa_gnb_rx_tx_time_diff_s { + nrppa_gnb_rx_tx_time_diff_pr present; + nrppa_gnb_rx_tx_time_diff_u choice; +} nrppa_gnb_rx_tx_time_diff_t; + +typedef enum nrppa_ul_rtoa_measurement_e { + NRPPA_ULRTOAMEAS_PR_NOTHING, + NRPPA_ULRTOAMEAS_PR_K0, + NRPPA_ULRTOAMEAS_PR_K1, + NRPPA_ULRTOAMEAS_PR_K2, + NRPPA_ULRTOAMEAS_PR_K3, + NRPPA_ULRTOAMEAS_PR_K4, + NRPPA_ULRTOAMEAS_PR_K5 +} nrppa_ul_rtoa_measurement_pr; + +typedef struct nrppa_ul_rtoa_measurement_s { + nrppa_ul_rtoa_measurement_pr present; + nrppa_ul_rtoa_measurement_u choice; +} nrppa_ul_rtoa_measurement_t; + +typedef union nrppa_measured_results_value_c { + nrppa_ul_aoa_t ul_angle_of_arrival; + uint8_t ul_srs_rsrp; + nrppa_ul_rtoa_measurement_t ul_rtoa; + nrppa_gnb_rx_tx_time_diff_t gnb_rx_tx_time_diff; +} nrppa_measured_results_value_u; + +typedef enum nrppa_measured_results_value_e { + NRPPA_MEASURED_RESULTS_VALUE_PR_NOTHING, + NRPPA_MEASURED_RESULTS_VALUE_PR_UL_ANGLEOFARRIVAL, + NRPPA_MEASURED_RESULTS_VALUE_PR_UL_SRS_RSRP, + NRPPA_MEASURED_RESULTS_VALUE_PR_UL_RTOA, + NRPPA_MEASURED_RESULTS_VALUE_PR_GNB_RXTXTIMEDIFF +} nrppa_measured_results_value_pr; + +typedef struct nrppa_measured_results_value_s { + nrppa_measured_results_value_pr present; + nrppa_measured_results_value_u choice; +} nrppa_measured_results_value_t; + +typedef union nrppa_time_stamp_slot_index_c { + uint8_t scs_15; + uint8_t scs_30; + uint8_t scs_60; + uint8_t scs_120; +} nrppa_time_stamp_slot_index_u; + +typedef enum nrppa_time_stamp_slot_index_e { + NRPPA_TIME_STAMP_SLOT_INDEX_PR_NOTHING, + NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_15, + NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_30, + NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_60, + NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_120 +} nrppa_time_stamp_slot_index_pr; + +typedef struct nrppa_time_stamp_slot_index_s { + nrppa_time_stamp_slot_index_pr present; + nrppa_time_stamp_slot_index_u choice; +} nrppa_time_stamp_slot_index_t; + +typedef struct nrppa_time_stamp_s { + uint16_t system_frame_number; + nrppa_time_stamp_slot_index_t slot_index; +} nrppa_time_stamp_t; + +typedef struct nrppa_measurement_result_item_s { + nrppa_measured_results_value_t measured_results_value; + nrppa_time_stamp_t time_stamp; +} nrppa_measurement_result_item_t; + +typedef struct nrppa_measurement_result_s { + nrppa_measurement_result_item_t *measurement_result_item; + uint32_t measurement_result_item_length; +} nrppa_measurement_result_t; + +typedef struct nrppa_measurement_response_item_s { + nrppa_measurement_result_t measurement_result; + uint32_t trp_id; +} nrppa_measurement_response_item_t; + +typedef struct nrppa_measurement_response_list_s { + nrppa_measurement_response_item_t *measurement_response_item; + uint32_t measurement_response_list_length; +} nrppa_measurement_response_list_t; + +typedef struct nrppa_trp_information_req_s { + // IE 9.2.4 (mandatory) + uint16_t transaction_id; + bool has_trp_list; + // mandatory + nrppa_trp_list_t trp_list; + // mandatory + nrppa_trp_information_type_list_t trp_information_type_list; +} nrppa_trp_information_req_t; + +typedef struct nrppa_trp_information_resp_s { + // IE 9.2.4 (mandatory) + uint16_t transaction_id; + // mandatory + nrppa_trp_information_list_t trp_information_list; +} nrppa_trp_information_resp_t; + +typedef struct nrppa_positioning_information_req_s { + // IE 9.2.4 (mandatory) + uint16_t transaction_id; +} nrppa_positioning_information_req_t; + +typedef struct nrppa_positioning_information_resp_s { + // IE 9.2.4 (mandatory) + uint16_t transaction_id; + // IE 9.2.28 (optional) + nrppa_srs_configuration_t *srs_configuration; +} nrppa_positioning_information_resp_t; + +typedef struct nrppa_positioning_activation_req_s { + // IE 9.2.4 (mandatory) + uint16_t transaction_id; + // (mandatory) + nrppa_srs_type_t srs_type; +} nrppa_positioning_activation_req_t; + +typedef struct nrppa_positioning_activation_resp_s { + // IE 9.2.4 (mandatory) + uint16_t transaction_id; +} nrppa_positioning_activation_resp_t; + +typedef struct nrppa_measurement_req_s { + // IE 9.2.4 (mandatory) + uint16_t transaction_id; + // (mandatory) + uint32_t lmf_measurement_id; + // (mandatory) + nrppa_trp_measurement_request_list_t trp_measurement_request_list; + // (mandatory) ondemand = 0, periodic = 1 + nrppa_report_characteristics_pr report_characteristics; + // if report characteristics periodic + nrppa_measurement_periodicity_pr measurement_periodicity; + // (mandatory) + nrppa_measurement_quantities_t measurement_quantities; + // IE 9.2.28 (optional) + nrppa_srs_configuration_t *srs_configuration; +} nrppa_measurement_req_t; + +typedef struct nrppa_measurement_resp_s { + // IE 9.2.4 (mandatory) + uint16_t transaction_id; + // (mandatory) + uint32_t lmf_measurement_id; + // (mandatory) + uint32_t ran_measurement_id; + // (optional) + nrppa_measurement_response_list_t *measurement_response_list; +} nrppa_measurement_resp_t; + +#endif // NRPPA_MESSAGES_TYPES_H_ diff --git a/openair2/COMMON/positioning_nr_paramdef.h b/openair2/COMMON/positioning_nr_paramdef.h new file mode 100644 index 0000000000..6861db6778 --- /dev/null +++ b/openair2/COMMON/positioning_nr_paramdef.h @@ -0,0 +1,62 @@ +/* + * 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 __POSITIONING_NR_PARAMDEF__H__ +#define __POSITIONING_NR_PARAMDEF__H__ + +/* Positioning configuration section names */ +#define CONFIG_STRING_POSITIONING_CONFIG "positioning_config" + +/* Global parameters */ + +/* TRP configuration parameters names */ +#define CONFIG_STRING_POSITIONING_NUM_TRPS "NumTRPs" +#define CONFIG_STRING_POSITIONING_TRP_IDS_LIST "TRPIDs" +#define CONFIG_STRING_POSITIONING_TRP_X_AXIS_LIST "TRPxAxis" +#define CONFIG_STRING_POSITIONING_TRP_Y_AXIS_LIST "TRPyAxis" +#define CONFIG_STRING_POSITIONING_TRP_Z_AXIS_LIST "TRPzAxis" +#define CONFIG_STRING_POSITIONING_TRP_UNIT_LIST "Units" + +/* Help string for Positioning parameters */ +#define HELP_STRING_POSITIONING_NUM_TRPS "Number of TRPs connected with gNB(max 4)\n" +#define HELP_STRING_POSITIONING_TRP_IDS_LIST "User defined IDs for each TRP \n" +#define HELP_STRING_POSITIONING_TRP_X_AXIS_LIST "x-axis value of each TRP \n" +#define HELP_STRING_POSITIONING_TRP_Y_AXIS_LIST "y-axis value of each TRP \n" +#define HELP_STRING_POSITIONING_TRP_Z_AXIS_LIST "z-axis value of each TRP \n" +#define HELP_STRING_POSITIONING_TRP_UNIT_LIST "XYZ unit value of each TRP \n" + +/*----------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* TRP configuration parameters */ +/* optname helpstr paramflags XXXptr defXXXval type + * numelt */ +/*----------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +// clang-format off +#define POSITIONING_PARAMS_DESC { \ + {CONFIG_STRING_POSITIONING_NUM_TRPS, HELP_STRING_POSITIONING_NUM_TRPS, 0, .uptr=NULL, .defuintval=0, TYPE_UINT, 0}, \ + {CONFIG_STRING_POSITIONING_TRP_IDS_LIST, HELP_STRING_POSITIONING_TRP_IDS_LIST, 0, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \ + {CONFIG_STRING_POSITIONING_TRP_X_AXIS_LIST, HELP_STRING_POSITIONING_TRP_X_AXIS_LIST, 0, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \ + {CONFIG_STRING_POSITIONING_TRP_Y_AXIS_LIST, HELP_STRING_POSITIONING_TRP_Y_AXIS_LIST, 0, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \ + {CONFIG_STRING_POSITIONING_TRP_Z_AXIS_LIST, HELP_STRING_POSITIONING_TRP_Z_AXIS_LIST, 0, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \ + {CONFIG_STRING_POSITIONING_TRP_UNIT_LIST, HELP_STRING_POSITIONING_TRP_UNIT_LIST, 0, .uptr=NULL, .defintarrayval=0, TYPE_UINTARRAY, 0}, \ +} +// clang-format on + +#endif diff --git a/openair2/F1AP/f1ap_du_task.h b/openair2/F1AP/f1ap_du_task.h index 8ce8aacab6..8546ca6cb3 100644 --- a/openair2/F1AP/f1ap_du_task.h +++ b/openair2/F1AP/f1ap_du_task.h @@ -21,9 +21,9 @@ #ifndef F1AP_DU_TASK_H_ #define F1AP_DU_TASK_H_ +#include "openair2/COMMON/f1ap_messages_types.h" -struct f1ap_net_config_t; -void du_task_send_sctp_association_req(instance_t instance, struct f1ap_net_config_t *du_inst); +void du_task_send_sctp_association_req(instance_t instance, f1ap_net_config_t *du_inst); void du_task_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp); void du_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind); void *F1AP_DU_task(void *arg); diff --git a/openair2/F1AP/lib/f1ap_lib_common.h b/openair2/F1AP/lib/f1ap_lib_common.h index 94e0ee22c3..419ee278b1 100644 --- a/openair2/F1AP/lib/f1ap_lib_common.h +++ b/openair2/F1AP/lib/f1ap_lib_common.h @@ -83,14 +83,10 @@ } while (0) bool eq_f1ap_plmn(const plmn_id_t *a, const plmn_id_t *b); -struct f1ap_served_cell_info_t; -bool eq_f1ap_cell_info(const struct f1ap_served_cell_info_t *a, const struct f1ap_served_cell_info_t *b); -struct f1ap_gnb_du_system_info_t; -bool eq_f1ap_sys_info(const struct f1ap_gnb_du_system_info_t *a, const struct f1ap_gnb_du_system_info_t *b); -struct f1ap_nr_frequency_info_t; -bool eq_f1ap_freq_info(const struct f1ap_nr_frequency_info_t *a, const struct f1ap_nr_frequency_info_t *b); -struct f1ap_transmission_bandwidth_t; -bool eq_f1ap_tx_bandwidth(const struct f1ap_transmission_bandwidth_t *a, const struct f1ap_transmission_bandwidth_t *b); +bool eq_f1ap_cell_info(const f1ap_served_cell_info_t *a, const f1ap_served_cell_info_t *b); +bool eq_f1ap_sys_info(const f1ap_gnb_du_system_info_t *a, const f1ap_gnb_du_system_info_t *b); +bool eq_f1ap_freq_info(const f1ap_nr_frequency_info_t *a, const f1ap_nr_frequency_info_t *b); +bool eq_f1ap_tx_bandwidth(const f1ap_transmission_bandwidth_t *a, const f1ap_transmission_bandwidth_t *b); struct OCTET_STRING; uint8_t *cp_octet_string(const struct OCTET_STRING *os, int *len); diff --git a/openair2/GNB_APP/gnb_app.c b/openair2/GNB_APP/gnb_app.c index 98546413a0..9597f61430 100644 --- a/openair2/GNB_APP/gnb_app.c +++ b/openair2/GNB_APP/gnb_app.c @@ -53,6 +53,7 @@ #include "openair2/E1AP/e1ap.h" #include "gnb_config.h" #include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h" +#include "openair2/GNB_APP/gnb_config_ng.h" extern RAN_CONTEXT_t RC; /*------------------------------------------------------------------------------*/ diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 667ab25093..d3618bdaaf 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -79,7 +79,8 @@ #include "uper_encoder.h" #include "utils.h" #include "x2ap_messages_types.h" - +#include "gnb_config_common.h" +#include "positioning_nr_paramdef.h" static int DEFBANDS[] = {7}; static int DEFENBS[] = {0}; @@ -96,45 +97,6 @@ static int DEFRUTPCORES[] = {-1,-1,-1,-1}; (element)->choice.setup = CALLOC(1, sizeof(*((element)->choice.setup))); \ } while (0) -static uint16_t set_snssai_config(nssai_t *nssai, const int max_num_ssi, uint8_t k, uint8_t l) -{ - char snssaistr[MAX_OPTNAME_SIZE * 2 + 8]; - snprintf(snssaistr, sizeof(snssaistr), "%s.[%i].%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, k, GNB_CONFIG_STRING_PLMN_LIST, l); - GET_PARAMS_LIST(SNSSAIParamList, - SNSSAIParams, - GNBSNSSAIPARAMS_DESC, - GNB_CONFIG_STRING_SNSSAI_LIST, - snssaistr, - SNSSAIPARAMS_CHECK); - uint16_t num_ssi = SNSSAIParamList.numelt; - AssertFatal(num_ssi < max_num_ssi, "S-NSSAI size %d exceeds the max array size %d", num_ssi, max_num_ssi); - for (int s = 0; s < num_ssi; ++s) { - nssai[s].sst = *SNSSAIParamList.paramarray[s][GNB_SLICE_SERVICE_TYPE_IDX].uptr; - // SD is optional - // 0xffffff is "no SD", see 23.003 Sec 28.4.2 - nssai[s].sd = *SNSSAIParamList.paramarray[s][GNB_SLICE_DIFFERENTIATOR_IDX].uptr; - AssertFatal(nssai[s].sd <= 0xffffff, "SD cannot be bigger than 0xffffff, but is %d\n", nssai[s].sd); - } - return num_ssi; -} - -static uint8_t set_plmn_config(plmn_id_t *p, uint8_t idx) -{ - char gnbpath[MAX_OPTNAME_SIZE * 2 + 8]; - snprintf(gnbpath, sizeof(gnbpath), "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, idx); - GET_PARAMS_LIST(PLMNParamList, PLMNParams, GNBPLMNPARAMS_DESC, GNB_CONFIG_STRING_PLMN_LIST, gnbpath, PLMNPARAMS_CHECK); - uint8_t num_plmn = PLMNParamList.numelt; - AssertFatal(num_plmn >= 1 && num_plmn <= 6, "The number of PLMN IDs must be in [1,6], but is %d\n", num_plmn); - for (int l = 0; l < num_plmn; ++l) { - plmn_id_t *plmn = &p[l]; - plmn->mcc = *PLMNParamList.paramarray[l][GNB_MOBILE_COUNTRY_CODE_IDX].uptr; - plmn->mnc = *PLMNParamList.paramarray[l][GNB_MOBILE_NETWORK_CODE_IDX].uptr; - plmn->mnc_digit_length = *PLMNParamList.paramarray[l][GNB_MNC_DIGIT_LENGTH].u8ptr; - AssertFatal((plmn->mnc_digit_length == 2) || (plmn->mnc_digit_length == 3), "BAD MNC DIGIT LENGTH %d", plmn->mnc_digit_length); - } - return num_plmn; -} - /** * Allocate memory and initialize ServingCellConfigCommon struct members */ @@ -816,7 +778,7 @@ void RCconfig_nr_prs(void) /** * @brief Get number or blacklisted UL PRBs and their mapping from gNB config */ -static int get_prb_blacklist(uint8_t instance, uint16_t *prbbl) +static int get_prb_blacklist(uint16_t *prbbl) { paramdef_t GNBSParams[] = GNBSPARAMS_DESC; paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST, NULL, 0}; @@ -870,7 +832,7 @@ void RCconfig_NR_L1(void) // PRB Blacklist uint16_t prbbl[MAX_BWP_SIZE] = {0}; - int num_ulprbbl = get_prb_blacklist(j, prbbl); + int num_ulprbbl = get_prb_blacklist(prbbl); if (num_ulprbbl != -1) { RC.gNB[j]->num_ulprbbl = num_ulprbbl; LOG_D(NR_PHY, "Copying %d blacklisted PRB to L1 context\n", RC.gNB[j]->num_ulprbbl); @@ -943,7 +905,7 @@ bool is_pattern2_config(paramdef_t *param) return true; } -static NR_ServingCellConfigCommon_t *get_scc_config(configmodule_interface_t *cfg, int minRXTXTIME, int do_SRS) +static NR_ServingCellConfigCommon_t *get_scc_config(int minRXTXTIME, int do_SRS) { NR_ServingCellConfigCommon_t *scc = calloc_or_fail(1, sizeof(*scc)); uint64_t ssb_bitmap=0xff; @@ -1039,8 +1001,7 @@ static NR_ServingCellConfigCommon_t *get_scc_config(configmodule_interface_t *cf return scc; } -static int read_du_cell_info(configmodule_interface_t *cfg, - bool separate_du, +static int read_du_cell_info(bool separate_du, uint32_t *gnb_id, uint64_t *gnb_du_id, char **name, @@ -1211,7 +1172,7 @@ static f1ap_setup_req_t *RC_read_F1Setup(uint64_t id, return req; } -static nr_ptrs_config_t *get_ptrs_config(int gnb_idx) +static nr_ptrs_config_t *get_ptrs_config() { char aprefix[MAX_OPTNAME_SIZE * 2 + 8]; snprintf(aprefix, sizeof(aprefix), "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0); @@ -1471,7 +1432,7 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg) AssertFatal(config.maxMIMO_layers != 0 && config.maxMIMO_layers <= tot_ant, "Invalid maxMIMO_layers %d\n", config.maxMIMO_layers); config.redcap = get_redcap_config(0); - config.ptrs = get_ptrs_config(0); + config.ptrs = get_ptrs_config(); char aprefix[MAX_OPTNAME_SIZE * 2 + 8]; snprintf(aprefix, sizeof(aprefix), "%s.[%d].%s", GNB_CONFIG_STRING_GNB_LIST, 0, GNB_CONFIG_STRING_TIMERS_CONFIG); @@ -1523,7 +1484,7 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg) config.num_agg_level_candidates[PDCCH_AGG_LEVEL8], config.num_agg_level_candidates[PDCCH_AGG_LEVEL16]); - NR_ServingCellConfigCommon_t *scc = get_scc_config(cfg, config.minRXTXTIME, config.do_SRS); + NR_ServingCellConfigCommon_t *scc = get_scc_config(config.minRXTXTIME, config.do_SRS); // BWP get_bwp_config(&config, scc); AssertFatal(config.num_additional_bwps <= 4, "Impossible to configure more than 4 additional BWPs\n"); @@ -1622,7 +1583,7 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg) RC.nrmac[j]->identity_pm = *(MacRLC_ParamList.paramarray[j][MACRLC_IDENTITY_PM_IDX].u8ptr); // PRB Blacklist uint16_t prbbl[MAX_BWP_SIZE] = {0}; - int num_ulprbbl = get_prb_blacklist(j, prbbl); + int num_ulprbbl = get_prb_blacklist(prbbl); if (num_ulprbbl != -1) { LOG_I(NR_PHY, "Copying %d blacklisted PRB to L1 context\n", num_ulprbbl); memcpy(RC.nrmac[j]->ulprbbl, prbbl, MAX_BWP_SIZE * sizeof(prbbl[0])); @@ -1667,7 +1628,7 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg) uint32_t gnb_id = 0; char *name = NULL; f1ap_served_cell_info_t info; - read_du_cell_info(cfg, NODE_IS_DU(node_type), &gnb_id, &gnb_du_id, &name, &info, 1); + read_du_cell_info(NODE_IS_DU(node_type), &gnb_id, &gnb_du_id, &name, &info, 1); NR_COMMON_channels_t *cc = &RC.nrmac[0]->common_channels[0]; cc->du_SIBs = fill_du_sibs(GNBParamList.paramarray[0]); @@ -2131,130 +2092,6 @@ gNB_RRC_INST *RCconfig_NRRRC() return rrc; } -int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i) -{ - int j,k = 0; - int gnb_id; - - char* gnb_ipv4_address_for_NGU = NULL; - uint32_t gnb_port_for_NGU = 0; - char* gnb_ipv4_address_for_S1U = NULL; - uint32_t gnb_port_for_S1U = 0; - - GET_PARAMS(GNBSParams, GNBSPARAMS_DESC, NULL); - AssertFatal (i0) { - // Output a list of all gNBs. - GET_PARAMS_LIST(GNBParamList, GNBParams, GNBPARAMS_DESC, GNB_CONFIG_STRING_GNB_LIST, NULL); - if (GNBParamList.numelt > 0) { - for (k = 0; k < GNBParamList.numelt; k++) { - if (GNBParamList.paramarray[k][GNB_GNB_ID_IDX].uptr == NULL) { - // Calculate a default gNB ID - if (IS_SA_MODE(get_softmodem_params())) { - uint32_t hash; - - hash = ngap_generate_gNB_id (); - gnb_id = k + (hash & 0xFFFFFF8); - } else { - gnb_id = k; - } - } else { - gnb_id = *(GNBParamList.paramarray[k][GNB_GNB_ID_IDX].uptr); - } - - - // search if in active list - for (j=0; j < GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt; j++) { - if (strcmp(GNBSParams[GNB_ACTIVE_GNBS_IDX].strlistptr[j], *(GNBParamList.paramarray[k][GNB_GNB_NAME_IDX].strptr)) == 0) { - - char aprefix[MAX_OPTNAME_SIZE*2 + 8]; - NGAP_REGISTER_GNB_REQ (msg_p).gNB_id = gnb_id; - - if (strcmp(*(GNBParamList.paramarray[k][GNB_CELL_TYPE_IDX].strptr), "CELL_MACRO_GNB") == 0) { - NGAP_REGISTER_GNB_REQ (msg_p).cell_type = CELL_MACRO_GNB; - } else if (strcmp(*(GNBParamList.paramarray[k][GNB_CELL_TYPE_IDX].strptr), "CELL_HOME_GNB") == 0) { - NGAP_REGISTER_GNB_REQ (msg_p).cell_type = CELL_HOME_ENB; - } else { - AssertFatal (0, - "Failed to parse gNB configuration file %s, gnb %u unknown value \"%s\" for cell_type choice: CELL_MACRO_GNB or CELL_HOME_GNB !\n", - RC.config_file_name, i, *(GNBParamList.paramarray[k][GNB_CELL_TYPE_IDX].strptr)); - } - - NGAP_REGISTER_GNB_REQ (msg_p).gNB_name = strdup(*(GNBParamList.paramarray[k][GNB_GNB_NAME_IDX].strptr)); - NGAP_REGISTER_GNB_REQ (msg_p).tac = *GNBParamList.paramarray[k][GNB_TRACKING_AREA_CODE_IDX].uptr; - AssertFatal(!GNBParamList.paramarray[k][GNB_MOBILE_COUNTRY_CODE_IDX_OLD].strptr - && !GNBParamList.paramarray[k][GNB_MOBILE_NETWORK_CODE_IDX_OLD].strptr, - "It seems that you use an old configuration file. Please change the existing\n" - " tracking_area_code = \"1\";\n" - " mobile_country_code = \"208\";\n" - " mobile_network_code = \"93\";\n" - "to\n" - " tracking_area_code = 1; // no string!!\n" - " plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } )\n"); - // PLMN - plmn_id_t p[PLMN_LIST_MAX_SIZE] = {0}; - NGAP_REGISTER_GNB_REQ(msg_p).num_plmn = set_plmn_config(p, 0); - for (int l = 0; l < NGAP_REGISTER_GNB_REQ(msg_p).num_plmn; ++l) { - NGAP_REGISTER_GNB_REQ(msg_p).plmn[l].plmn = p[l]; - // SNSSAI - NGAP_REGISTER_GNB_REQ(msg_p).plmn[l].num_nssai = set_snssai_config(NGAP_REGISTER_GNB_REQ(msg_p).plmn[l].s_nssai, 8, k, l); - } - NGAP_REGISTER_GNB_REQ(msg_p).default_drx = 0; - // NG - snprintf(aprefix, sizeof(aprefix), "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, k); - GET_PARAMS_LIST(NGParamList, NGParams, GNBNGPARAMS_DESC, GNB_CONFIG_STRING_AMF_IP_ADDRESS, aprefix); - NGAP_REGISTER_GNB_REQ (msg_p).nb_amf = 0; - - for (int l = 0; l < NGParamList.numelt; l++) { - NGAP_REGISTER_GNB_REQ (msg_p).nb_amf += 1; - strcpy(NGAP_REGISTER_GNB_REQ (msg_p).amf_ip_address[l].ipv4_address,*(NGParamList.paramarray[l][GNB_AMF_IPV4_ADDRESS_IDX].strptr)); - NGAP_REGISTER_GNB_REQ (msg_p).amf_ip_address[j].ipv4 = 1; - NGAP_REGISTER_GNB_REQ (msg_p).amf_ip_address[j].ipv6 = 0; - /* if no broadcasst_plmn array is defined, fill default values */ - if (NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_num[l] == 0) { - NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_num[l] = NGAP_REGISTER_GNB_REQ(msg_p).num_plmn; - for (int el = 0; el < NGAP_REGISTER_GNB_REQ(msg_p).num_plmn; ++el) - NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_index[l][el] = el; - } - } - - // SCTP SETTING - NGAP_REGISTER_GNB_REQ (msg_p).sctp_out_streams = SCTP_OUT_STREAMS; - NGAP_REGISTER_GNB_REQ (msg_p).sctp_in_streams = SCTP_IN_STREAMS; - if (IS_SA_MODE(get_softmodem_params())) { - snprintf(aprefix, sizeof(aprefix), "%s.[%d].%s", GNB_CONFIG_STRING_GNB_LIST, k, GNB_CONFIG_STRING_SCTP_CONFIG); - GET_PARAMS(SCTPParams, GNBSCTPPARAMS_DESC, aprefix); - NGAP_REGISTER_GNB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[GNB_SCTP_INSTREAMS_IDX].uptr); - NGAP_REGISTER_GNB_REQ (msg_p).sctp_out_streams = (uint16_t)*(SCTPParams[GNB_SCTP_OUTSTREAMS_IDX].uptr); - } - - // NETWORK_INTERFACES - snprintf(aprefix, sizeof(aprefix), "%s.[%d].%s", GNB_CONFIG_STRING_GNB_LIST, k, GNB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); - GET_PARAMS(NETParams, GNBNETPARAMS_DESC, aprefix); - if (NETParams[GNB_IPV4_ADDRESS_FOR_NG_AMF_IDX].strptr != NULL) { - char *cidr = *(NETParams[GNB_IPV4_ADDRESS_FOR_NG_AMF_IDX].strptr); - char *save = NULL; - char *address = strtok_r(cidr, "/", &save); - strcpy(NGAP_REGISTER_GNB_REQ (msg_p).gnb_ip_address.ipv4_address, address); - LOG_I(GNB_APP, "Parsed IPv4 address for NG AMF: %s\n", address); - } - - NGAP_REGISTER_GNB_REQ (msg_p).gnb_ip_address.ipv6 = 0; - NGAP_REGISTER_GNB_REQ (msg_p).gnb_ip_address.ipv4 = 1; - - break; - } - } - } - } - } - return 0; -} - static pthread_mutex_t rc_mutex = PTHREAD_MUTEX_INITIALIZER; static bool rc_done = false; diff --git a/openair2/GNB_APP/gnb_config.h b/openair2/GNB_APP/gnb_config.h index c33c6964dc..1f48358e67 100644 --- a/openair2/GNB_APP/gnb_config.h +++ b/openair2/GNB_APP/gnb_config.h @@ -44,7 +44,6 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg); void NRRCConfig(void); gNB_RRC_INST *RCconfig_NRRRC(); -int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i); int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i); void wait_f1_setup_response(void); f1ap_tdd_info_t read_tdd_config(const NR_ServingCellConfigCommon_t *scc); diff --git a/openair2/GNB_APP/gnb_config_common.c b/openair2/GNB_APP/gnb_config_common.c new file mode 100644 index 0000000000..ac5e840851 --- /dev/null +++ b/openair2/GNB_APP/gnb_config_common.c @@ -0,0 +1,66 @@ +/* + * 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 "openair2/GNB_APP/gnb_config_common.h" +#include "common/config/config_paramdesc.h" +#include "common/config/config_userapi.h" +#include "RRC_nr_paramsvalues.h" +#include "gnb_paramdef.h" +#include "sctp_default_values.h" + +uint16_t set_snssai_config(nssai_t *nssai, const int max_num_ssi, uint8_t k, uint8_t l) +{ + char snssaistr[MAX_OPTNAME_SIZE * 2 + 8]; + snprintf(snssaistr, sizeof(snssaistr), "%s.[%i].%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, k, GNB_CONFIG_STRING_PLMN_LIST, l); + GET_PARAMS_LIST(SNSSAIParamList, + SNSSAIParams, + GNBSNSSAIPARAMS_DESC, + GNB_CONFIG_STRING_SNSSAI_LIST, + snssaistr, + SNSSAIPARAMS_CHECK); + uint16_t num_ssi = SNSSAIParamList.numelt; + AssertFatal(num_ssi < max_num_ssi, "S-NSSAI size %d exceeds the max array size %d", num_ssi, max_num_ssi); + for (int s = 0; s < num_ssi; ++s) { + nssai[s].sst = *SNSSAIParamList.paramarray[s][GNB_SLICE_SERVICE_TYPE_IDX].uptr; + // SD is optional + // 0xffffff is "no SD", see 23.003 Sec 28.4.2 + nssai[s].sd = *SNSSAIParamList.paramarray[s][GNB_SLICE_DIFFERENTIATOR_IDX].uptr; + AssertFatal(nssai[s].sd <= 0xffffff, "SD cannot be bigger than 0xffffff, but is %d\n", nssai[s].sd); + } + return num_ssi; +} + +uint8_t set_plmn_config(plmn_id_t *p, uint8_t idx) +{ + char gnbpath[MAX_OPTNAME_SIZE * 2 + 8]; + snprintf(gnbpath, sizeof(gnbpath), "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, idx); + GET_PARAMS_LIST(PLMNParamList, PLMNParams, GNBPLMNPARAMS_DESC, GNB_CONFIG_STRING_PLMN_LIST, gnbpath, PLMNPARAMS_CHECK); + uint8_t num_plmn = PLMNParamList.numelt; + AssertFatal(num_plmn >= 1 && num_plmn <= 6, "The number of PLMN IDs must be in [1,6], but is %d\n", num_plmn); + for (int l = 0; l < num_plmn; ++l) { + plmn_id_t *plmn = &p[l]; + plmn->mcc = *PLMNParamList.paramarray[l][GNB_MOBILE_COUNTRY_CODE_IDX].uptr; + plmn->mnc = *PLMNParamList.paramarray[l][GNB_MOBILE_NETWORK_CODE_IDX].uptr; + plmn->mnc_digit_length = *PLMNParamList.paramarray[l][GNB_MNC_DIGIT_LENGTH].u8ptr; + AssertFatal((plmn->mnc_digit_length == 2) || (plmn->mnc_digit_length == 3), "BAD MNC DIGIT LENGTH %d", plmn->mnc_digit_length); + } + return num_plmn; +} diff --git a/openair2/GNB_APP/gnb_config_common.h b/openair2/GNB_APP/gnb_config_common.h new file mode 100644 index 0000000000..8317709a78 --- /dev/null +++ b/openair2/GNB_APP/gnb_config_common.h @@ -0,0 +1,26 @@ +/* + * 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/5g_platform_types.h" + +uint16_t set_snssai_config(nssai_t *nssai, const int max_num_ssi, uint8_t k, uint8_t l); +uint8_t set_plmn_config(plmn_id_t *p, uint8_t idx); diff --git a/openair2/GNB_APP/gnb_config_ng.c b/openair2/GNB_APP/gnb_config_ng.c new file mode 100644 index 0000000000..632c670def --- /dev/null +++ b/openair2/GNB_APP/gnb_config_ng.c @@ -0,0 +1,162 @@ +/* + * 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 "gnb_config_ng.h" +#include +#include "assertions.h" +#include "common/ran_context.h" +#include "openair2/GNB_APP/gnb_config_common.h" +#include "common/config/config_paramdesc.h" +#include "sctp_default_values.h" +#include "gnb_paramdef.h" + +int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i) +{ + int j, k = 0; + int gnb_id; + + char *gnb_ipv4_address_for_NGU = NULL; + uint32_t gnb_port_for_NGU = 0; + char *gnb_ipv4_address_for_S1U = NULL; + uint32_t gnb_port_for_S1U = 0; + + GET_PARAMS(GNBSParams, GNBSPARAMS_DESC, NULL); + AssertFatal(i < GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt, + "Failed to parse config file %s, %uth attribute %s \n", + RC.config_file_name, + i, + GNB_CONFIG_STRING_ACTIVE_GNBS); + + if (GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt > 0) { + // Output a list of all gNBs. + GET_PARAMS_LIST(GNBParamList, GNBParams, GNBPARAMS_DESC, GNB_CONFIG_STRING_GNB_LIST, NULL); + if (GNBParamList.numelt > 0) { + for (k = 0; k < GNBParamList.numelt; k++) { + if (GNBParamList.paramarray[k][GNB_GNB_ID_IDX].uptr == NULL) { + // Calculate a default gNB ID + if (IS_SA_MODE(get_softmodem_params())) { + uint32_t hash; + + hash = ngap_generate_gNB_id(); + gnb_id = k + (hash & 0xFFFFFF8); + } else { + gnb_id = k; + } + } else { + gnb_id = *(GNBParamList.paramarray[k][GNB_GNB_ID_IDX].uptr); + } + + // search if in active list + for (j = 0; j < GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt; j++) { + if (strcmp(GNBSParams[GNB_ACTIVE_GNBS_IDX].strlistptr[j], *(GNBParamList.paramarray[k][GNB_GNB_NAME_IDX].strptr)) == 0) { + char aprefix[MAX_OPTNAME_SIZE * 2 + 8]; + NGAP_REGISTER_GNB_REQ(msg_p).gNB_id = gnb_id; + + if (strcmp(*(GNBParamList.paramarray[k][GNB_CELL_TYPE_IDX].strptr), "CELL_MACRO_GNB") == 0) { + NGAP_REGISTER_GNB_REQ(msg_p).cell_type = CELL_MACRO_GNB; + } else if (strcmp(*(GNBParamList.paramarray[k][GNB_CELL_TYPE_IDX].strptr), "CELL_HOME_GNB") == 0) { + NGAP_REGISTER_GNB_REQ(msg_p).cell_type = CELL_HOME_ENB; + } else { + AssertFatal(0, + "Failed to parse gNB configuration file %s, gnb %u unknown value \"%s\" for cell_type choice: " + "CELL_MACRO_GNB or CELL_HOME_GNB !\n", + RC.config_file_name, + i, + *(GNBParamList.paramarray[k][GNB_CELL_TYPE_IDX].strptr)); + } + + NGAP_REGISTER_GNB_REQ(msg_p).gNB_name = strdup(*(GNBParamList.paramarray[k][GNB_GNB_NAME_IDX].strptr)); + NGAP_REGISTER_GNB_REQ(msg_p).tac = *GNBParamList.paramarray[k][GNB_TRACKING_AREA_CODE_IDX].uptr; + AssertFatal(!GNBParamList.paramarray[k][GNB_MOBILE_COUNTRY_CODE_IDX_OLD].strptr + && !GNBParamList.paramarray[k][GNB_MOBILE_NETWORK_CODE_IDX_OLD].strptr, + "It seems that you use an old configuration file. Please change the existing\n" + " tracking_area_code = \"1\";\n" + " mobile_country_code = \"208\";\n" + " mobile_network_code = \"93\";\n" + "to\n" + " tracking_area_code = 1; // no string!!\n" + " plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } )\n"); + // PLMN + plmn_id_t p[PLMN_LIST_MAX_SIZE] = {0}; + NGAP_REGISTER_GNB_REQ(msg_p).num_plmn = set_plmn_config(p, 0); + for (int l = 0; l < NGAP_REGISTER_GNB_REQ(msg_p).num_plmn; ++l) { + NGAP_REGISTER_GNB_REQ(msg_p).plmn[l].plmn = p[l]; + // SNSSAI + NGAP_REGISTER_GNB_REQ(msg_p).plmn[l].num_nssai = + set_snssai_config(NGAP_REGISTER_GNB_REQ(msg_p).plmn[l].s_nssai, 8, k, l); + } + NGAP_REGISTER_GNB_REQ(msg_p).default_drx = 0; + // NG + snprintf(aprefix, sizeof(aprefix), "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, k); + GET_PARAMS_LIST(NGParamList, NGParams, GNBNGPARAMS_DESC, GNB_CONFIG_STRING_AMF_IP_ADDRESS, aprefix); + NGAP_REGISTER_GNB_REQ(msg_p).nb_amf = 0; + + for (int l = 0; l < NGParamList.numelt; l++) { + NGAP_REGISTER_GNB_REQ(msg_p).nb_amf += 1; + strcpy(NGAP_REGISTER_GNB_REQ(msg_p).amf_ip_address[l].ipv4_address, + *(NGParamList.paramarray[l][GNB_AMF_IPV4_ADDRESS_IDX].strptr)); + NGAP_REGISTER_GNB_REQ(msg_p).amf_ip_address[l].ipv4 = 1; + NGAP_REGISTER_GNB_REQ(msg_p).amf_ip_address[l].ipv6 = 0; + /* if no broadcasst_plmn array is defined, fill default values */ + if (NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_num[l] == 0) { + NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_num[l] = NGAP_REGISTER_GNB_REQ(msg_p).num_plmn; + for (int el = 0; el < NGAP_REGISTER_GNB_REQ(msg_p).num_plmn; ++el) + NGAP_REGISTER_GNB_REQ(msg_p).broadcast_plmn_index[l][el] = el; + } + } + + // SCTP SETTING + NGAP_REGISTER_GNB_REQ(msg_p).sctp_out_streams = SCTP_OUT_STREAMS; + NGAP_REGISTER_GNB_REQ(msg_p).sctp_in_streams = SCTP_IN_STREAMS; + if (IS_SA_MODE(get_softmodem_params())) { + snprintf(aprefix, sizeof(aprefix), "%s.[%d].%s", GNB_CONFIG_STRING_GNB_LIST, k, GNB_CONFIG_STRING_SCTP_CONFIG); + GET_PARAMS(SCTPParams, GNBSCTPPARAMS_DESC, aprefix); + NGAP_REGISTER_GNB_REQ(msg_p).sctp_in_streams = (uint16_t) * (SCTPParams[GNB_SCTP_INSTREAMS_IDX].uptr); + NGAP_REGISTER_GNB_REQ(msg_p).sctp_out_streams = (uint16_t) * (SCTPParams[GNB_SCTP_OUTSTREAMS_IDX].uptr); + } + + // NETWORK_INTERFACES + snprintf(aprefix, + sizeof(aprefix), + "%s.[%d].%s", + GNB_CONFIG_STRING_GNB_LIST, + k, + GNB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); + GET_PARAMS(NETParams, GNBNETPARAMS_DESC, aprefix); + if (NETParams[GNB_IPV4_ADDRESS_FOR_NG_AMF_IDX].strptr != NULL) { + char *cidr = *(NETParams[GNB_IPV4_ADDRESS_FOR_NG_AMF_IDX].strptr); + char *save = NULL; + char *address = strtok_r(cidr, "/", &save); + strcpy(NGAP_REGISTER_GNB_REQ(msg_p).gnb_ip_address.ipv4_address, address); + LOG_I(GNB_APP, "Parsed IPv4 address for NG AMF: %s\n", address); + } + + NGAP_REGISTER_GNB_REQ(msg_p).gnb_ip_address.ipv6 = 0; + NGAP_REGISTER_GNB_REQ(msg_p).gnb_ip_address.ipv4 = 1; + + break; + } + } + } + } + } + return 0; +} diff --git a/openair2/GNB_APP/gnb_config_ng.h b/openair2/GNB_APP/gnb_config_ng.h new file mode 100644 index 0000000000..792f55e940 --- /dev/null +++ b/openair2/GNB_APP/gnb_config_ng.h @@ -0,0 +1,29 @@ +/* + * 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 NGAP_GNB_CONFIG_H_ +#define NGAP_GNB_CONFIG_H_ +#include +#include "intertask_interface.h" + +int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i); + +#endif /* NGAP_GNB_CONFIG_H_ */ diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 2a5c8e041d..c42406149e 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -537,16 +537,15 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommon_t // SSB Table config if (frequencyInfoDL && frequencyInfoDL->absoluteFrequencySSB) { - int scs_scaling = 1 << (cfg->ssb_config.scs_common); - if (frequencyInfoDL->absoluteFrequencyPointA < 600000) - scs_scaling = scs_scaling * 3; - if (frequencyInfoDL->absoluteFrequencyPointA > 2016666) - scs_scaling = scs_scaling >> 2; - uint32_t absolute_diff = (*frequencyInfoDL->absoluteFrequencySSB - frequencyInfoDL->absoluteFrequencyPointA); - cfg->ssb_table.ssb_offset_point_a = absolute_diff / (12 * scs_scaling) - 10; + cfg->ssb_table.ssb_offset_point_a = get_ssb_offset_to_pointA(*frequencyInfoDL->absoluteFrequencySSB, + frequencyInfoDL->absoluteFrequencyPointA, + cfg->ssb_config.scs_common, + mac->frequency_range); cfg->ssb_table.ssb_period = *scc->ssb_periodicityServingCell; // NSA -> take ssb offset from SCS - cfg->ssb_table.ssb_subcarrier_offset = absolute_diff % (12 * scs_scaling); + cfg->ssb_table.ssb_subcarrier_offset = get_ssb_subcarrier_offset(*frequencyInfoDL->absoluteFrequencySSB, + frequencyInfoDL->absoluteFrequencyPointA, + cfg->ssb_config.scs_common); cfg->ssb_table.ssb_case = set_ssb_case(*scc->ssbSubcarrierSpacing, mac->nr_band); } @@ -717,9 +716,7 @@ static void update_ss(void *ue_ss_in, void *nw_ss_in) } } -static void configure_common_ss_coreset(const NR_UE_MAC_INST_t *mac, - NR_BWP_PDCCH_t *pdcch, - NR_PDCCH_ConfigCommon_t *pdcch_ConfigCommon) +static void configure_common_ss_coreset(NR_BWP_PDCCH_t *pdcch, NR_PDCCH_ConfigCommon_t *pdcch_ConfigCommon) { if (!pdcch_ConfigCommon) return; @@ -1778,7 +1775,7 @@ static void configure_common_BWP_dl(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP_Do NR_BWP_PDCCH_t *pdcch = &mac->config_BWP_PDCCH[bwp_id]; if (dl_common->pdcch_ConfigCommon) { if (dl_common->pdcch_ConfigCommon->present == NR_SetupRelease_PDCCH_ConfigCommon_PR_setup) - configure_common_ss_coreset(mac, pdcch, dl_common->pdcch_ConfigCommon->choice.setup); + configure_common_ss_coreset(pdcch, dl_common->pdcch_ConfigCommon->choice.setup); if (dl_common->pdcch_ConfigCommon->present == NR_SetupRelease_PDCCH_ConfigCommon_PR_release) release_common_ss_cset(pdcch); } @@ -2107,18 +2104,24 @@ static void handle_reconfiguration_with_sync(NR_UE_MAC_INST_t *mac, configure_common_BWP_dl(mac, bwp_id, scc->downlinkConfigCommon->initialDownlinkBWP); if (scc->uplinkConfigCommon) configure_common_BWP_ul(mac, bwp_id, scc->uplinkConfigCommon->initialUplinkBWP); + + // Update PDCCH config as MAC configuration has changed + if (IS_SA_MODE(get_softmodem_params())) + update_pdcch_config(mac); } mac->state = UE_NOT_SYNC_RECONF; ra->ra_state = nrRA_UE_IDLE; nr_ue_mac_default_configs(mac); + // PHY CONFIG request should be sent, ahead of SYNC request + // As SYNC request processes the new config + mac->if_module->phy_config_request(&mac->phy_config); + mac->phy_config.config_req.ntn_config.params_changed = false; mac->synch_request.Mod_id = mac->ue_id; mac->synch_request.CC_id = cc_idP; mac->synch_request.synch_req.target_Nid_cell = mac->physCellId; mac->if_module->synch_request(&mac->synch_request); - mac->if_module->phy_config_request(&mac->phy_config); - mac->phy_config.config_req.ntn_config.params_changed = false; } static void configure_physicalcellgroup(NR_UE_MAC_INST_t *mac, diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue_sl.c b/openair2/LAYER2/NR_MAC_UE/config_ue_sl.c index e6d872da81..809ce054f4 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue_sl.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue_sl.c @@ -394,8 +394,7 @@ int nr_rrc_mac_config_req_sl_preconfig(module_id_t module_id, //Copies the values of SSB time allocation from ASN format to MAC context -static void sl_mac_config_ssb_time_alloc(uint8_t module_id, - NR_SL_SSB_TimeAllocation_r16_t *sl_SSB_TimeAllocation_r16, +static void sl_mac_config_ssb_time_alloc(NR_SL_SSB_TimeAllocation_r16_t *sl_SSB_TimeAllocation_r16, sl_ssb_timealloc_t *ssb_time_alloc) { @@ -432,9 +431,7 @@ void nr_rrc_mac_transmit_slss_req(module_id_t module_id, sl_mac->tx_sl_bch.num_ssb = 0; sl_mac->tx_sl_bch.ssb_slot = 0; - sl_mac_config_ssb_time_alloc(module_id, - ssb_ta, - &sl_mac->tx_sl_bch.ssb_time_alloc); + sl_mac_config_ssb_time_alloc(ssb_ta, &sl_mac->tx_sl_bch.ssb_time_alloc); LOG_I(NR_MAC,"[UE%d]SL RRC->MAC: TX SLSS REQ SLSS-id:%d, SL-MIB:%x, numssb:%d, offset:%d, interval:%d\n", module_id, sl_mac->tx_sl_bch.slss_id, @@ -489,9 +486,7 @@ void nr_rrc_mac_config_req_sl_mib(module_id_t module_id, sl_mac->rx_sl_bch.num_ssb = 0; sl_mac->rx_sl_bch.ssb_slot = 0; - sl_mac_config_ssb_time_alloc(module_id, - ssb_ta, - &sl_mac->rx_sl_bch.ssb_time_alloc); + sl_mac_config_ssb_time_alloc(ssb_ta, &sl_mac->rx_sl_bch.ssb_time_alloc); LOG_I(NR_MAC,"[UE%d]SL RRC->MAC: RX SLSS REQ SLSS-id:%d, SL-MIB:%x, numssb:%d, offset:%d, interval:%d\n", module_id, sl_mac->rx_sl_bch.slss_id, diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 9ee1bfab28..91783894b3 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -166,11 +166,7 @@ typedef struct { enum { b_none, b_long, b_short, b_short_trunc, b_long_trunc } type_bsr; } type_bsr_t; -int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, - NR_UE_MAC_INST_t *mac, - NR_SINGLE_ENTRY_PHR_MAC_CE *power_headroom, - const type_bsr_t *bsr, - uint8_t *mac_ce_end); +int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, NR_SINGLE_ENTRY_PHR_MAC_CE *power_headroom, const type_bsr_t *bsr, uint8_t *mac_ce_end); void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl_config, const frame_t frame, const int slot); void set_precoding_information_parameters(nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, @@ -241,10 +237,9 @@ int get_sum_delta_pucch(NR_UE_MAC_INST_t *mac, int slot, frame_t frame); void ul_ports_config(NR_UE_MAC_INST_t *mac, int *n_front_load_symb, nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, - dci_pdu_rel15_t *dci, - nr_dci_format_t dci_format); + dci_pdu_rel15_t *dci); -bool init_RA(NR_UE_MAC_INST_t *mac, int frame); +bool init_RA(NR_UE_MAC_INST_t *mac); /* Random Access */ /* \brief This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211 tables 6.3.3.2.x @@ -262,7 +257,7 @@ void configure_csi_resource_mapping(fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_c bool is_lcid_suspended(NR_UE_MAC_INST_t *mac, int lcid); void nr_ra_contention_resolution_failed(NR_UE_MAC_INST_t *mac); -void nr_ra_succeeded(NR_UE_MAC_INST_t *mac, const uint8_t gNB_index, const frame_t frame, const int slot); +void nr_ra_succeeded(NR_UE_MAC_INST_t *mac, const frame_t frame, const int slot); void nr_ra_backoff_setting(RA_config_t *ra); void nr_get_RA_window(NR_UE_MAC_INST_t *mac); void prepare_msg4_msgb_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack); @@ -283,7 +278,7 @@ int16_t get_prach_tx_power(NR_UE_MAC_INST_t *mac); void schedule_RA_after_SR_failure(NR_UE_MAC_INST_t *mac); void nr_rar_not_successful(NR_UE_MAC_INST_t *mac); void ra_resource_selection(NR_UE_MAC_INST_t *mac); -void nr_Msg3_transmitted(NR_UE_MAC_INST_t *mac, uint8_t CC_id, frame_t frameP, slot_t slotP, uint8_t gNB_id); +void nr_Msg3_transmitted(NR_UE_MAC_INST_t *mac); void trigger_MAC_UE_RA(NR_UE_MAC_INST_t *mac, dci_pdu_rel15_t *pdcch_order); void nr_get_Msg3_MsgA_PUSCH_payload(NR_UE_MAC_INST_t *mac, uint8_t *buf, int TBS_max); void handle_time_alignment_timer_expired(NR_UE_MAC_INST_t *mac); @@ -377,4 +372,5 @@ void nr_ue_sidelink_scheduler(nr_sidelink_indication_t *sl_ind, NR_UE_MAC_INST_t NR_SearchSpace_t *get_common_search_space(const NR_UE_MAC_INST_t *mac, const NR_SearchSpaceId_t ss_id); ssb_ro_preambles_t get_ssb_ro_preambles_4step(struct NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB *config); +void update_pdcch_config(NR_UE_MAC_INST_t *mac); #endif diff --git a/openair2/LAYER2/NR_MAC_UE/mac_tables.c b/openair2/LAYER2/NR_MAC_UE/mac_tables.c index a313600609..90cdc26fe4 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_tables.c +++ b/openair2/LAYER2/NR_MAC_UE/mac_tables.c @@ -470,8 +470,7 @@ void set_antenna_port_parameters(fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_pdu, void ul_ports_config(NR_UE_MAC_INST_t *mac, int *n_front_load_symb, nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, - dci_pdu_rel15_t *dci, - nr_dci_format_t dci_format) + dci_pdu_rel15_t *dci) { uint8_t rank = pusch_config_pdu->nrOfLayers; NR_PUSCH_Config_t *pusch_Config = mac->current_UL_BWP->pusch_Config; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 47277f8a66..a93ad9f8d2 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -819,7 +819,7 @@ static void setup_ra_response_window(NR_UE_MAC_INST_t *mac, // Random Access procedure initialization as per 5.1.1 and initialization of variables specific // to Random Access type as specified in clause 5.1.1a (3GPP TS 38.321 version 16.2.1 Release 16) -bool init_RA(NR_UE_MAC_INST_t *mac, int frame) +bool init_RA(NR_UE_MAC_INST_t *mac) { RA_config_t *ra = &mac->ra; LOG_D(NR_MAC, "Initialization of RA\n"); @@ -1023,7 +1023,7 @@ bool init_RA(NR_UE_MAC_INST_t *mac, int frame) return true; } -void nr_Msg3_transmitted(NR_UE_MAC_INST_t *mac, uint8_t CC_id, frame_t frameP, slot_t slotP, uint8_t gNB_id) +void nr_Msg3_transmitted(NR_UE_MAC_INST_t *mac) { RA_config_t *ra = &mac->ra; NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = mac->current_UL_BWP->rach_ConfigCommon; @@ -1109,7 +1109,7 @@ void nr_get_Msg3_MsgA_PUSCH_payload(NR_UE_MAC_INST_t *mac, uint8_t *buf, int TBS // according to section 5 of 3GPP TS 38.321 version 16.2.1 Release 16 // todo: // - complete handling of received contention-based RA preamble -void nr_ra_succeeded(NR_UE_MAC_INST_t *mac, const uint8_t gNB_index, const frame_t frame, const int slot) +void nr_ra_succeeded(NR_UE_MAC_INST_t *mac, const frame_t frame, const int slot) { RA_config_t *ra = &mac->ra; 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 8dbce0032c..43aab362f3 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -422,6 +422,38 @@ static bool monitor_dci_for_other_SI(NR_UE_MAC_INST_t *mac, return false; } +void update_pdcch_config(NR_UE_MAC_INST_t *mac) +{ + int scs = mac->current_DL_BWP ? mac->current_DL_BWP->scs : mac->numerology; + const int slots_per_frame = get_slots_per_frame_from_scs(scs); + int ssb_sc_offset_norm; + if (mac->ssb_subcarrier_offset < 24 && mac->frequency_range == FR1) + ssb_sc_offset_norm = mac->ssb_subcarrier_offset >> scs; + else + ssb_sc_offset_norm = mac->ssb_subcarrier_offset; + uint16_t ssb_offset_point_a = (mac->ssb_start_subcarrier - ssb_sc_offset_norm) / 12; + int ssb_start_symbol = get_ssb_start_symbol(mac->nr_band, scs, mac->mib_ssb); + get_type0_PDCCH_CSS_config_parameters(&mac->type0_PDCCH_CSS_config, + mac->mib_frame, + mac->mib, + slots_per_frame, + ssb_sc_offset_norm, + ssb_start_symbol, + scs, + mac->frequency_range, + mac->nr_band, + 273, // at this point UE in principle doesn't know the grid size (we assume the largest) + mac->mib_ssb, + 1, // If the UE is not configured with a periodicity, the UE assumes a periodicity of a half frame + ssb_offset_point_a); + if (mac->search_space_zero == NULL) + mac->search_space_zero = calloc(1, sizeof(*mac->search_space_zero)); + if (mac->coreset0 == NULL) + mac->coreset0 = calloc(1, sizeof(*mac->coreset0)); + fill_coresetZero(mac->coreset0, &mac->type0_PDCCH_CSS_config); + fill_searchSpaceZero(mac->search_space_zero, slots_per_frame, &mac->type0_PDCCH_CSS_config); +} + void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl_config, const frame_t frame, const int slot) { const NR_UE_DL_BWP_t *current_DL_BWP = mac->current_DL_BWP; @@ -430,37 +462,14 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl int scs = current_DL_BWP ? current_DL_BWP->scs : mac->numerology; const int slots_per_frame = get_slots_per_frame_from_scs(scs); if (mac->get_sib1) { - int ssb_sc_offset_norm; - if (mac->ssb_subcarrier_offset < 24 && mac->frequency_range == FR1) - ssb_sc_offset_norm = mac->ssb_subcarrier_offset >> scs; - else - ssb_sc_offset_norm = mac->ssb_subcarrier_offset; - uint16_t ssb_offset_point_a = (mac->ssb_start_subcarrier - ssb_sc_offset_norm) / 12; - int ssb_start_symbol = get_ssb_start_symbol(mac->nr_band, scs, mac->mib_ssb); - get_type0_PDCCH_CSS_config_parameters(&mac->type0_PDCCH_CSS_config, - mac->mib_frame, - mac->mib, - slots_per_frame, - ssb_sc_offset_norm, - ssb_start_symbol, - scs, - mac->frequency_range, - mac->nr_band, - 273, // at this point UE in principle doesn't know the grid size (we assume the largest) - mac->mib_ssb, - 1, // If the UE is not configured with a periodicity, the UE assumes a periodicity of a half frame - ssb_offset_point_a); - if (mac->search_space_zero == NULL) - mac->search_space_zero = calloc(1, sizeof(*mac->search_space_zero)); - if (mac->coreset0 == NULL) - mac->coreset0 = calloc(1, sizeof(*mac->coreset0)); - fill_coresetZero(mac->coreset0, &mac->type0_PDCCH_CSS_config); - fill_searchSpaceZero(mac->search_space_zero, slots_per_frame, &mac->type0_PDCCH_CSS_config); - if (is_ss_monitor_occasion(frame, slot, slots_per_frame, mac->search_space_zero)) { + update_pdcch_config(mac); + bool is_occasion = is_ss_monitor_occasion(frame, slot, slots_per_frame, mac->search_space_zero); + if (is_occasion) { LOG_D(NR_MAC_DCI, "Monitoring DCI for SIB1 in frame %d slot %d\n", frame, slot); config_dci_pdu(mac, dl_config, TYPE_SI_RNTI_, slot, mac->search_space_zero); } } + for (int i = 0; i < MAX_SI_GROUPS; i++) { if (!mac->get_otherSI[i]) continue; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c index a409cbe653..668efba2f5 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c @@ -59,7 +59,7 @@ static const int nb_symbols_excluding_dmrs[11][2][2] }; // ∆MPR according to Table 6.2.2-3 38.101-1 -static float get_delta_mpr(uint16_t nr_band, frame_type_t frame_type, int scs, int channel_bandwidth, int n_prbs, int start_prb, int power_class) +static float get_delta_mpr(uint16_t nr_band, frame_type_t frame_type, int scs, int channel_bandwidth, int power_class) { if (compare_relative_ul_channel_bw(nr_band, scs, channel_bandwidth, frame_type)) { if (power_class == 3) { @@ -191,7 +191,7 @@ float nr_get_Pcmax(int p_Max, int delta_TC = 0; float MPR = get_mpr(Qm, N_RB_UL, is_transform_precoding, n_prbs, start_prb, power_class); - float delta_MPR = get_delta_mpr(nr_band, frame_type, scs, channel_bandwidth, n_prbs, start_prb, power_class); + float delta_MPR = get_delta_mpr(nr_band, frame_type, scs, channel_bandwidth, power_class); int A_MPR = 0; // TODO too complicated to implement for now (see 6.2.3 in 38.101-1) int delta_rx_SRS = 0; // TODO for SRS int P_MPR = 0; // to ensure compliance with applicable electromagnetic energy absorption requirements diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 52ed7580c6..2c3ee539fc 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -3296,7 +3296,7 @@ static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *d rar = (NR_MAC_RAR *) (dlsch_buffer + n_subheaders + (n_subPDUs - 1) * sizeof(NR_MAC_RAR)); handle_rar_reception(mac, rar, frame, slot); if (ra->cfra) - nr_ra_succeeded(mac, dl_info->gNB_index, frame, slot); + nr_ra_succeeded(mac, frame, slot); break; } if (rarh->E == 0) { @@ -3818,12 +3818,7 @@ static bool check_ra_contention_resolution(const uint8_t *pdu, const uint8_t *co return true; } -static int nr_ue_validate_successrar(uint8_t *pduP, - int32_t pdu_len, - NR_UE_MAC_INST_t *mac, - uint8_t gNB_index, - frame_t frameP, - int slot) +static int nr_ue_validate_successrar(uint8_t *pduP, int32_t pdu_len, NR_UE_MAC_INST_t *mac, frame_t frameP, int slot) { // TS 38.321 - Figure 6.1.5a-1: BI MAC subheader // TS 38.321 - Figure 6.1.5a-3: SuccessRAR MAC subheader @@ -3885,7 +3880,7 @@ static int nr_ue_validate_successrar(uint8_t *pduP, if (ra->RA_active && ra_success) { nr_timer_stop(&ra->response_window_timer); - nr_ra_succeeded(mac, gNB_index, frameP, slot); + nr_ra_succeeded(mac, frameP, slot); } else if (!ra_success) { nr_ra_backoff_setting(ra); } @@ -3943,7 +3938,6 @@ static void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_ fapi_nr_pdsch_pdu_t *pdsch_pdu = &(dl_info->rx_ind->rx_indication_body + pdu_id)->pdsch_pdu; uint8_t *pduP = pdsch_pdu->pdu; int32_t pdu_len = (int32_t)pdsch_pdu->pdu_length; - uint8_t gNB_index = dl_info->gNB_index; uint8_t CC_id = dl_info->cc_id; uint8_t done = 0; RA_config_t *ra = &mac->ra; @@ -3963,7 +3957,7 @@ static void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_ dl_info->rx_ind->number_pdus); if (ra->ra_type == RA_2_STEP && ra->ra_state == nrRA_WAIT_MSGB) { - int n = nr_ue_validate_successrar(pduP, pdu_len, mac, gNB_index, frameP, slot); + int n = nr_ue_validate_successrar(pduP, pdu_len, mac, frameP, slot); pduP += n; pdu_len -= n; } @@ -4095,7 +4089,7 @@ static void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_ bool ra_success = check_ra_contention_resolution(&pduP[1], ra->cont_res_id); if (ra->RA_active && ra_success) { - nr_ra_succeeded(mac, gNB_index, frameP, slot); + nr_ra_succeeded(mac, frameP, slot); } else if (!ra_success) { // consider this Contention Resolution not successful and discard the successfully decoded MAC PDU nr_ra_contention_resolution_failed(mac); @@ -4135,14 +4129,9 @@ static void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_ * Function: generating MAC CEs (MAC CE and subheader) for the ULSCH PDU * Parameters: * @mac_ce pointer to the MAC sub-PDUs including the MAC CEs - * @mac pointer to the MAC instance * Return: number of written bytes */ -int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, - NR_UE_MAC_INST_t *mac, - NR_SINGLE_ENTRY_PHR_MAC_CE *power_headroom, - const type_bsr_t *bsr, - uint8_t *mac_ce_end) +int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, NR_SINGLE_ENTRY_PHR_MAC_CE *power_headroom, const type_bsr_t *bsr, uint8_t *mac_ce_end) { uint8_t *pdu = mac_ce; if (power_headroom) { diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index d06c8302a6..cc933b50e4 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -324,7 +324,7 @@ fapi_nr_dl_config_request_t *get_dl_config_request(NR_UE_MAC_INST_t *mac, int sl return &mac->dl_config_request[slot]; } -void ul_layers_config(NR_UE_MAC_INST_t *mac, nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, dci_pdu_rel15_t *dci, nr_dci_format_t dci_format) +static void ul_layers_config(NR_UE_MAC_INST_t *mac, nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, dci_pdu_rel15_t *dci) { NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; NR_SRS_Config_t *srs_config = current_UL_BWP->srs_Config; @@ -583,8 +583,8 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, else pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; } else if (dci_format == NR_UL_DCI_FORMAT_0_1) { - ul_layers_config(mac, pusch_config_pdu, dci, dci_format); - ul_ports_config(mac, &dmrslength, pusch_config_pdu, dci, dci_format); + ul_layers_config(mac, pusch_config_pdu, dci); + ul_ports_config(mac, &dmrslength, pusch_config_pdu, dci); } else { LOG_E(NR_MAC, "UL grant from DCI format %d is not handled...\n", dci_format); mac->stats.bad_dci++; @@ -1459,7 +1459,7 @@ static void nr_update_sr(NR_UE_MAC_INST_t *mac, bool BSRsent) } } -static void nr_update_rlc_buffers_status(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t slotP, uint8_t gNB_index) +static void nr_update_rlc_buffers_status(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t slotP) { for (int i = 0; i < mac->lc_ordered_list.count; i++) { nr_lcordered_info_t *lc_info = mac->lc_ordered_list.array[i]; @@ -1987,10 +1987,8 @@ static uint8_t nr_locate_BsrIndexByBufferSize(int size, int value) } static void nr_ue_get_sdu_mac_ce_pre(NR_UE_MAC_INST_t *mac, - int CC_id, frame_t frame, slot_t slot, - uint8_t gNB_index, uint8_t *ulsch_buffer, uint32_t buflen, uint32_t *LCG_bytes, @@ -2172,8 +2170,7 @@ static void nr_ue_get_sdu_mac_ce_post(NR_UE_MAC_INST_t *mac, } } - int size = - nr_write_ce_ulsch_pdu(mac_ce_p->cur_ptr, mac, mac_ce_p->phr_len ? &mac_ce_p->phr : NULL, &mac_ce_p->bsr, mac_ce_p->pdu_end); + int size = nr_write_ce_ulsch_pdu(mac_ce_p->cur_ptr, mac_ce_p->phr_len ? &mac_ce_p->phr : NULL, &mac_ce_p->bsr, mac_ce_p->pdu_end); LOG_D(NR_MAC, "Added %d bytes of BSR\n", size); mac_ce_p->cur_ptr += size; } @@ -2272,7 +2269,6 @@ static uint select_logical_channels(NR_UE_MAC_INST_t *mac, nr_lcordered_info_t * static bool fill_mac_sdu(NR_UE_MAC_INST_t *mac, frame_t frame, slot_t slot, - uint8_t gNB_index, int lcid, uint count_same_priority_lcids, uint32_t buflen_ep, @@ -2406,18 +2402,14 @@ static bool fill_mac_sdu(NR_UE_MAC_INST_t *mac, to generate the complete MAC PDU with sub-headers and MAC CEs according to ULSCH MAC PDU generation (6.1.2 TS 38.321) the selected sub-header for the payload sub-PDUs is NR_MAC_SUBHEADER_LONG * @module_idP Module ID - * @CC_id Component Carrier index * @frame current UL frame * @slot current UL slot - * @gNB_index gNB index * @ulsch_buffer Pointer to ULSCH PDU * @buflen TBS */ static uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac, - int CC_id, frame_t frame, slot_t slot, - uint8_t gNB_index, uint8_t *ulsch_buffer, const uint32_t buflen, int tx_power, @@ -2436,7 +2428,7 @@ static uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac, uint32_t LCG_bytes[NR_MAX_NUM_LCGID] = {0}; nr_update_bsr(mac, LCG_bytes); - nr_ue_get_sdu_mac_ce_pre(mac, CC_id, frame, slot, gNB_index, ulsch_buffer, buflen, LCG_bytes, &mac_ce_info, tx_power, P_CMAX); + nr_ue_get_sdu_mac_ce_pre(mac, frame, slot, ulsch_buffer, buflen, LCG_bytes, &mac_ce_info, tx_power, P_CMAX); LOG_D(NR_MAC, "[UE %d] [%d.%d] process UL transport block with size TBS = %d bytes, number of existing LCids %d \n", @@ -2510,7 +2502,6 @@ static uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac, if (!fill_mac_sdu(mac, frame, slot, - gNB_index, lcid, count_same_priority_lcids, buflen_ep, @@ -2563,12 +2554,10 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info) int cc_id = ul_info->cc_id; frame_t frame_tx = ul_info->frame; slot_t slot_tx = ul_info->slot; - uint32_t gNB_index = ul_info->gNB_index; - RA_config_t *ra = &mac->ra; if (mac->state == UE_PERFORMING_RA && ra->ra_state == nrRA_UE_IDLE) { - init_RA(mac, frame_tx); + init_RA(mac); // perform the Random Access Resource selection procedure (see clause 5.1.2 and .2a) ra_resource_selection(mac); } @@ -2579,7 +2568,7 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info) bool BSRsent = false; if (mac->state == UE_CONNECTED) { nr_ue_periodic_srs_scheduling(mac, frame_tx, slot_tx); - nr_update_rlc_buffers_status(mac, frame_tx, slot_tx, gNB_index); + nr_update_rlc_buffers_status(mac, frame_tx, slot_tx); } // Schedule ULSCH only if the current frame and slot match those in ul_config_req @@ -2637,7 +2626,7 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info) pdu->rb_size, pdu->rb_start); - nr_ue_get_sdu(mac, cc_id, frame_tx, slot_tx, gNB_index, ulsch_input_buffer, TBS_bytes, tx_power, P_CMAX, &BSRsent); + nr_ue_get_sdu(mac, frame_tx, slot_tx, ulsch_input_buffer, TBS_bytes, tx_power, P_CMAX, &BSRsent); pdu->tx_request_body.fapiTxPdu = ulsch_input_buffer; pdu->tx_request_body.pdu_length = TBS_bytes; number_of_pdus++; @@ -2654,11 +2643,11 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info) LOG_I(NR_MAC, "[RAPROC][%d.%d] RA-Msg3 retransmitted\n", frame_tx, slot_tx); // 38.321 restart the ra-ContentionResolutionTimer at each HARQ retransmission in the first symbol after the end of the Msg3 // transmission - nr_Msg3_transmitted(mac, cc_id, frame_tx, slot_tx, gNB_index); + nr_Msg3_transmitted(mac); } if (ra->ra_state == nrRA_WAIT_RAR && !ra->cfra) { LOG_A(NR_MAC, "[RAPROC][%d.%d] RA-Msg3 transmitted\n", frame_tx, slot_tx); - nr_Msg3_transmitted(mac, cc_id, frame_tx, slot_tx, gNB_index); + nr_Msg3_transmitted(mac); } if (ra->ra_state == nrRA_WAIT_MSGB && !ra->cfra) { LOG_A(NR_MAC, "[RAPROC][%d.%d] RA-MsgA-PUSCH transmitted\n", frame_tx, slot_tx); diff --git a/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_ra_procedures.cpp b/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_ra_procedures.cpp index f7fc520d06..cdbb3e9e3e 100644 --- a/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_ra_procedures.cpp +++ b/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_ra_procedures.cpp @@ -101,9 +101,8 @@ TEST(test_init_ra, four_step_cbra) mac.frame_structure.frame_type = TDD; mac.frame_structure.numb_slots_frame = 20; mac.frequency_range = FR1; - int frame = 151; - init_RA(&mac, frame); + init_RA(&mac); EXPECT_EQ(mac.ra.ra_type, RA_4_STEP); EXPECT_EQ(mac.state, UE_PERFORMING_RA); @@ -135,14 +134,13 @@ TEST(test_init_ra, four_step_cfra) mac.frame_structure.frame_type = TDD; mac.frame_structure.numb_slots_frame = 20; mac.frequency_range = FR1; - int frame = 151; NR_RACH_ConfigDedicated_t rach_ConfigDedicated = {0}; NR_CFRA_t cfra; rach_ConfigDedicated.cfra = &cfra; ra->rach_ConfigDedicated = &rach_ConfigDedicated; - init_RA(&mac, frame); + init_RA(&mac); EXPECT_EQ(mac.ra.ra_type, RA_4_STEP); EXPECT_EQ(mac.state, UE_PERFORMING_RA); diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 40ed4c6a50..adbba9c772 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -184,7 +184,7 @@ typedef enum { SSB_SINR, } nr_config_report_type_t; -typedef struct nr_mac_config_t { +typedef struct nr_mac_config_s { nr_pdsch_AntennaPorts_t pdsch_AntennaPorts; int pusch_AntennaPorts; int minRXTXTIME; @@ -855,7 +855,7 @@ typedef struct gNB_MAC_INST_s gNB_MAC_INST; typedef void (*nr_pp_impl_dl)(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pp_pdsch); typedef void (*nr_pp_impl_ul)(gNB_MAC_INST *nr_mac, post_process_pusch_t *pp_pusch); -typedef struct f1_config_t { +typedef struct { f1ap_setup_req_t *setup_req; f1ap_setup_resp_t *setup_resp; uint32_t gnb_id; // associated gNB's ID, not used in DU itself diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h index edf53f24f7..dc10904425 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_radio_config.h @@ -38,13 +38,8 @@ struct NR_MeasurementTimingConfiguration; struct NR_PDSCH_TimeDomainResourceAllocationList; // forward declaration of MAC configuration parameters, definition is included in C file -struct nr_mac_config_t; -typedef struct nr_mac_config_t nr_mac_config_t; - -struct nr_mac_timers; +typedef struct nr_mac_config_s nr_mac_config_t; typedef struct nr_mac_timers nr_mac_timers_t; - -struct measgap_config; typedef struct measgap_config measgap_config_t; void nr_rrc_config_dl_tda(struct NR_PDSCH_TimeDomainResourceAllocationList *pdsch_TimeDomainAllocationList, diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c index 25081891d3..42e09308f2 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c @@ -303,7 +303,7 @@ static int nr_pdcp_entity_process_sdu(nr_pdcp_entity_t *entity, return header_size + size + integrity_size; } -static bool nr_pdcp_entity_check_integrity(struct nr_pdcp_entity_t *entity, +static bool nr_pdcp_entity_check_integrity(nr_pdcp_entity_t *entity, const uint8_t *buffer, int buffer_size, const nr_pdcp_integrity_data_t *msg_integrity) @@ -329,8 +329,7 @@ static bool nr_pdcp_entity_check_integrity(struct nr_pdcp_entity_t *entity, } /* may be called several times, take care to clean previous settings */ -static void nr_pdcp_entity_set_security(struct nr_pdcp_entity_t *entity, - const nr_pdcp_entity_security_keys_and_algos_t *parameters) +static void nr_pdcp_entity_set_security(nr_pdcp_entity_t *entity, const nr_pdcp_entity_security_keys_and_algos_t *parameters) { if (parameters->integrity_algorithm != -1) { entity->security_keys_and_algos.integrity_algorithm = parameters->integrity_algorithm; @@ -453,7 +452,7 @@ static void check_t_reordering(nr_pdcp_entity_t *entity) } } -static void nr_pdcp_entity_set_time(struct nr_pdcp_entity_t *entity, uint64_t now) +static void nr_pdcp_entity_set_time(nr_pdcp_entity_t *entity, uint64_t now) { entity->t_current = now; @@ -697,12 +696,13 @@ nr_pdcp_entity_t *new_nr_pdcp_entity( int pdusession_id, bool has_sdap_rx, bool has_sdap_tx, - void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, - char *buf, int size, + void (*deliver_sdu)(void *deliver_sdu_data, + nr_pdcp_entity_t *entity, + char *buf, + int size, const nr_pdcp_integrity_data_t *msg_integrity), void *deliver_sdu_data, - void (*deliver_pdu)(void *deliver_pdu_data, ue_id_t ue_id, int rb_id, - char *buf, int size, int sdu_id), + void (*deliver_pdu)(void *deliver_pdu_data, ue_id_t ue_id, int rb_id, char *buf, int size, int sdu_id), void *deliver_pdu_data, int sn_size, int t_reordering, diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h index 84ecce8997..338279aec9 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h @@ -92,36 +92,36 @@ typedef struct { uint8_t mode; /* 0: PDCP AM, 1: PDCP UM, 2: PDCP TM */ } nr_pdcp_statistics_t; -typedef struct nr_pdcp_entity_t { +typedef struct nr_pdcp_entity_s { nr_pdcp_entity_type_t type; /* functions provided by the PDCP module */ - void (*recv_pdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size); - int (*process_sdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size, - int sdu_id, char *pdu_buffer, int pdu_max_size); - void (*delete_entity)(struct nr_pdcp_entity_t *entity); - void (*release_entity)(struct nr_pdcp_entity_t *entity); - void (*suspend_entity)(struct nr_pdcp_entity_t *entity); - void (*reestablish_entity)(struct nr_pdcp_entity_t *entity, - const nr_pdcp_entity_security_keys_and_algos_t *parameters); - void (*get_stats)(struct nr_pdcp_entity_t *entity, nr_pdcp_statistics_t *out); + void (*recv_pdu)(struct nr_pdcp_entity_s *entity, char *buffer, int size); + int (*process_sdu)(struct nr_pdcp_entity_s *entity, char *buffer, int size, int sdu_id, char *pdu_buffer, int pdu_max_size); + void (*delete_entity)(struct nr_pdcp_entity_s *entity); + void (*release_entity)(struct nr_pdcp_entity_s *entity); + void (*suspend_entity)(struct nr_pdcp_entity_s *entity); + void (*reestablish_entity)(struct nr_pdcp_entity_s *entity, const nr_pdcp_entity_security_keys_and_algos_t *parameters); + void (*get_stats)(struct nr_pdcp_entity_s *entity, nr_pdcp_statistics_t *out); /* set_security: pass -1 to parameters->integrity_algorithm / parameters->ciphering_algorithm * to keep the corresponding current algorithm and key */ - void (*set_security)(struct nr_pdcp_entity_t *entity, - const nr_pdcp_entity_security_keys_and_algos_t *parameters); + void (*set_security)(struct nr_pdcp_entity_s *entity, const nr_pdcp_entity_security_keys_and_algos_t *parameters); /* check_integrity is used by RRC */ - bool (*check_integrity)(struct nr_pdcp_entity_t *entity, - const uint8_t *buffer, int buffer_length, + bool (*check_integrity)(struct nr_pdcp_entity_s *entity, + const uint8_t *buffer, + int buffer_length, const nr_pdcp_integrity_data_t *msg_integrity); - void (*set_time)(struct nr_pdcp_entity_t *entity, uint64_t now); + void (*set_time)(struct nr_pdcp_entity_s *entity, uint64_t now); /* callbacks provided to the PDCP module */ - void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, - char *buf, int size, + void (*deliver_sdu)(void *deliver_sdu_data, + struct nr_pdcp_entity_s *entity, + char *buf, + int size, const nr_pdcp_integrity_data_t *msg_integrity); void *deliver_sdu_data; void (*deliver_pdu)(void *deliver_pdu_data, ue_id_t ue_id, int rb_id, @@ -186,10 +186,10 @@ typedef struct nr_pdcp_entity_t { bool entity_suspended; /* PDCP Count API */ - nr_pdcp_count_t (*get_pdcp_count_dl)(struct nr_pdcp_entity_t *entity); - nr_pdcp_count_t (*get_pdcp_count_ul)(struct nr_pdcp_entity_t *entity); - void (*set_pdcp_count_dl)(struct nr_pdcp_entity_t *entity, nr_pdcp_count_t count, int sn_size); - void (*set_pdcp_count_ul)(struct nr_pdcp_entity_t *entity, nr_pdcp_count_t count, int sn_size); + nr_pdcp_count_t (*get_pdcp_count_dl)(struct nr_pdcp_entity_s *entity); + nr_pdcp_count_t (*get_pdcp_count_ul)(struct nr_pdcp_entity_s *entity); + void (*set_pdcp_count_dl)(struct nr_pdcp_entity_s *entity, nr_pdcp_count_t count, int sn_size); + void (*set_pdcp_count_ul)(struct nr_pdcp_entity_s *entity, nr_pdcp_count_t count, int sn_size); } nr_pdcp_entity_t; @@ -200,12 +200,13 @@ nr_pdcp_entity_t *new_nr_pdcp_entity( int pdusession_id, bool has_sdap_rx, bool has_sdap_tx, - void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, - char *buf, int size, + void (*deliver_sdu)(void *deliver_sdu_data, + struct nr_pdcp_entity_s *entity, + char *buf, + int size, const nr_pdcp_integrity_data_t *msg_integrity), void *deliver_sdu_data, - void (*deliver_pdu)(void *deliver_pdu_data, ue_id_t ue_id, int rb_id, - char *buf, int size, int sdu_id), + void (*deliver_pdu)(void *deliver_pdu_data, ue_id_t ue_id, int rb_id, char *buf, int size, int sdu_id), void *deliver_pdu_data, int sn_size, int t_reordering, diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity.c index e452981357..2bb407ad01 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity.c @@ -71,26 +71,23 @@ static void nr_rlc_entity_get_stats( out->txsdu_avg_time_to_tx = 0; } -nr_rlc_entity_t *new_nr_rlc_entity_am( - int rx_maxsize, - int tx_maxsize, - void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, - char *buf, int size), - void *deliver_sdu_data, - void (*sdu_successful_delivery)(void *sdu_successful_delivery_data, - struct nr_rlc_entity_t *entity, - int sdu_id), - void *sdu_successful_delivery_data, - void (*max_retx_reached)(void *max_retx_reached_data, - struct nr_rlc_entity_t *entity), - void *max_retx_reached_data, - int t_poll_retransmit, - int t_reassembly, - int t_status_prohibit, - int poll_pdu, - int poll_byte, - int max_retx_threshold, - int sn_field_length) +nr_rlc_entity_t *new_nr_rlc_entity_am(int rx_maxsize, + int tx_maxsize, + void (*deliver_sdu)(void *deliver_sdu_data, nr_rlc_entity_t *entity, char *buf, int size), + void *deliver_sdu_data, + void (*sdu_successful_delivery)(void *sdu_successful_delivery_data, + nr_rlc_entity_t *entity, + int sdu_id), + void *sdu_successful_delivery_data, + void (*max_retx_reached)(void *max_retx_reached_data, nr_rlc_entity_t *entity), + void *max_retx_reached_data, + int t_poll_retransmit, + int t_reassembly, + int t_status_prohibit, + int poll_pdu, + int poll_byte, + int max_retx_threshold, + int sn_field_length) { nr_rlc_entity_am_t *ret; @@ -150,14 +147,12 @@ nr_rlc_entity_t *new_nr_rlc_entity_am( return (nr_rlc_entity_t *)ret; } -nr_rlc_entity_t *new_nr_rlc_entity_um( - int rx_maxsize, - int tx_maxsize, - void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, - char *buf, int size), - void *deliver_sdu_data, - int t_reassembly, - int sn_field_length) +nr_rlc_entity_t *new_nr_rlc_entity_um(int rx_maxsize, + int tx_maxsize, + void (*deliver_sdu)(void *deliver_sdu_data, nr_rlc_entity_t *entity, char *buf, int size), + void *deliver_sdu_data, + int t_reassembly, + int sn_field_length) { nr_rlc_entity_um_t *ret; @@ -203,11 +198,9 @@ nr_rlc_entity_t *new_nr_rlc_entity_um( return (nr_rlc_entity_t *)ret; } -nr_rlc_entity_t *new_nr_rlc_entity_tm( - int tx_maxsize, - void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, - char *buf, int size), - void *deliver_sdu_data) +nr_rlc_entity_t *new_nr_rlc_entity_tm(int tx_maxsize, + void (*deliver_sdu)(void *deliver_sdu_data, nr_rlc_entity_t *entity, char *buf, int size), + void *deliver_sdu_data) { nr_rlc_entity_tm_t *ret; diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity.h index 459e9f59a5..a16e3b7186 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity.h @@ -97,41 +97,35 @@ typedef struct { int retx_size; } nr_rlc_entity_buffer_status_t; -typedef struct nr_rlc_entity_t { +typedef struct nr_rlc_entity_s { /* functions provided by the RLC module */ - void (*recv_pdu)(struct nr_rlc_entity_t *entity, char *buffer, int size); - nr_rlc_entity_buffer_status_t (*buffer_status)( - struct nr_rlc_entity_t *entity, int maxsize); - int (*generate_pdu)(struct nr_rlc_entity_t *entity, char *buffer, int size); + void (*recv_pdu)(struct nr_rlc_entity_s *entity, char *buffer, int size); + nr_rlc_entity_buffer_status_t (*buffer_status)(struct nr_rlc_entity_s *entity, int maxsize); + int (*generate_pdu)(struct nr_rlc_entity_s *entity, char *buffer, int size); - void (*recv_sdu)(struct nr_rlc_entity_t *entity, char *buffer, int size, - int sdu_id); + void (*recv_sdu)(struct nr_rlc_entity_s *entity, char *buffer, int size, int sdu_id); - void (*set_time)(struct nr_rlc_entity_t *entity, uint64_t now); + void (*set_time)(struct nr_rlc_entity_s *entity, uint64_t now); - void (*discard_sdu)(struct nr_rlc_entity_t *entity, int sdu_id); + void (*discard_sdu)(struct nr_rlc_entity_s *entity, int sdu_id); - void (*reestablishment)(struct nr_rlc_entity_t *entity); + void (*reestablishment)(struct nr_rlc_entity_s *entity); - void (*delete_entity)(struct nr_rlc_entity_t *entity); + void (*delete_entity)(struct nr_rlc_entity_s *entity); - int (*available_tx_space)(struct nr_rlc_entity_t *entity); - int (*tx_list_occupancy)(struct nr_rlc_entity_t *entity); + int (*available_tx_space)(struct nr_rlc_entity_s *entity); + int (*tx_list_occupancy)(struct nr_rlc_entity_s *entity); - void (*get_stats)(struct nr_rlc_entity_t *entity, nr_rlc_statistics_t *out); + void (*get_stats)(struct nr_rlc_entity_s *entity, nr_rlc_statistics_t *out); /* callbacks provided to the RLC module */ - void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, - char *buf, int size); + void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_s *entity, char *buf, int size); void *deliver_sdu_data; - void (*sdu_successful_delivery)(void *sdu_successful_delivery_data, - struct nr_rlc_entity_t *entity, - int sdu_id); + void (*sdu_successful_delivery)(void *sdu_successful_delivery_data, struct nr_rlc_entity_s *entity, int sdu_id); void *sdu_successful_delivery_data; - void (*max_retx_reached)(void *max_retx_reached_data, - struct nr_rlc_entity_t *entity); + void (*max_retx_reached)(void *max_retx_reached_data, struct nr_rlc_entity_s *entity); void *max_retx_reached_data; /* buffer status computation */ nr_rlc_entity_buffer_status_t bstatus; @@ -141,41 +135,34 @@ typedef struct nr_rlc_entity_t { int avg_time_is_on; } nr_rlc_entity_t; -nr_rlc_entity_t *new_nr_rlc_entity_am( - int rx_maxsize, - int tx_maxsize, - void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, - char *buf, int size), - void *deliver_sdu_data, - void (*sdu_successful_delivery)(void *sdu_successful_delivery_data, - struct nr_rlc_entity_t *entity, - int sdu_id), - void *sdu_successful_delivery_data, - void (*max_retx_reached)(void *max_retx_reached_data, - struct nr_rlc_entity_t *entity), - void *max_retx_reached_data, - int t_poll_retransmit, - int t_reassembly, - int t_status_prohibit, - int poll_pdu, - int poll_byte, - int max_retx_threshold, - int sn_field_length); +nr_rlc_entity_t *new_nr_rlc_entity_am(int rx_maxsize, + int tx_maxsize, + void (*deliver_sdu)(void *deliver_sdu_data, nr_rlc_entity_t *entity, char *buf, int size), + void *deliver_sdu_data, + void (*sdu_successful_delivery)(void *sdu_successful_delivery_data, + nr_rlc_entity_t *entity, + int sdu_id), + void *sdu_successful_delivery_data, + void (*max_retx_reached)(void *max_retx_reached_data, nr_rlc_entity_t *entity), + void *max_retx_reached_data, + int t_poll_retransmit, + int t_reassembly, + int t_status_prohibit, + int poll_pdu, + int poll_byte, + int max_retx_threshold, + int sn_field_length); -nr_rlc_entity_t *new_nr_rlc_entity_um( - int rx_maxsize, - int tx_maxsize, - void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, - char *buf, int size), - void *deliver_sdu_data, - int t_reassembly, - int sn_field_length); +nr_rlc_entity_t *new_nr_rlc_entity_um(int rx_maxsize, + int tx_maxsize, + void (*deliver_sdu)(void *deliver_sdu_data, nr_rlc_entity_t *entity, char *buf, int size), + void *deliver_sdu_data, + int t_reassembly, + int sn_field_length); -nr_rlc_entity_t *new_nr_rlc_entity_tm( - int tx_maxsize, - void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, - char *buf, int size), - void *deliver_sdu_data); +nr_rlc_entity_t *new_nr_rlc_entity_tm(int tx_maxsize, + void (*deliver_sdu)(void *deliver_sdu_data, nr_rlc_entity_t *entity, char *buf, int size), + void *deliver_sdu_data); void nr_rlc_entity_um_reconfigure(nr_rlc_entity_t *_entity, int t_reassembly, int *sn_field_length); diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 126f9fb51c..133aea8d15 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -875,8 +875,7 @@ struct srb0_data { void (*send_initial_ul_rrc_message)(int ue_id, const uint8_t *sdu, sdu_size_t sdu_len, void *data); }; -void deliver_sdu_srb0(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, - char *buf, int size) +void deliver_sdu_srb0(void *deliver_sdu_data, nr_rlc_entity_t *entity, char *buf, int size) { struct srb0_data *s0 = (struct srb0_data *)deliver_sdu_data; s0->send_initial_ul_rrc_message(s0->ue_id, (unsigned char *)buf, size, s0->data); diff --git a/openair2/LAYER2/nr_rlc/tests/benchmark_nr_rlc_am_entity.cpp b/openair2/LAYER2/nr_rlc/tests/benchmark_nr_rlc_am_entity.cpp index ac36b79211..fe51273e61 100644 --- a/openair2/LAYER2/nr_rlc/tests/benchmark_nr_rlc_am_entity.cpp +++ b/openair2/LAYER2/nr_rlc/tests/benchmark_nr_rlc_am_entity.cpp @@ -28,13 +28,13 @@ extern configmodule_interface_t *uniqCfg; } #include -void deliver_sdu(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, char *buf, int size) +void deliver_sdu(void *deliver_sdu_data, nr_rlc_entity_t *entity, char *buf, int size) { } -void sdu_successful_delivery(void *sdu_successful_delivery_data, struct nr_rlc_entity_t *entity, int sdu_id) +void sdu_successful_delivery(void *sdu_successful_delivery_data, nr_rlc_entity_t *entity, int sdu_id) { } -void max_retx_reached(void *max_retx_reached_data, struct nr_rlc_entity_t *entity) +void max_retx_reached(void *max_retx_reached_data, nr_rlc_entity_t *entity) { } diff --git a/openair2/LAYER2/nr_rlc/tests/test.c b/openair2/LAYER2/nr_rlc/tests/test.c index 04e49c460a..6af48b474b 100644 --- a/openair2/LAYER2/nr_rlc/tests/test.c +++ b/openair2/LAYER2/nr_rlc/tests/test.c @@ -107,9 +107,7 @@ int test[] = { #include TEST }; -void deliver_sdu_gnb_am(void *deliver_sdu_data, - struct nr_rlc_entity_t *_entity, - char *buf, int size) +void deliver_sdu_gnb_am(void *deliver_sdu_data, nr_rlc_entity_t *_entity, char *buf, int size) { nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; printf("TEST: GNB: %"PRIu64": deliver SDU size %d [", @@ -118,9 +116,7 @@ void deliver_sdu_gnb_am(void *deliver_sdu_data, printf("]\n"); } -void deliver_sdu_gnb_um(void *deliver_sdu_data, - struct nr_rlc_entity_t *_entity, - char *buf, int size) +void deliver_sdu_gnb_um(void *deliver_sdu_data, nr_rlc_entity_t *_entity, char *buf, int size) { nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity; printf("TEST: GNB: %"PRIu64": deliver SDU size %d [", @@ -129,9 +125,7 @@ void deliver_sdu_gnb_um(void *deliver_sdu_data, printf("]\n"); } -void deliver_sdu_gnb_tm(void *deliver_sdu_data, - struct nr_rlc_entity_t *_entity, - char *buf, int size) +void deliver_sdu_gnb_tm(void *deliver_sdu_data, nr_rlc_entity_t *_entity, char *buf, int size) { nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity; printf("TEST: GNB: %"PRIu64": deliver SDU size %d [", @@ -157,9 +151,7 @@ void max_retx_reached_gnb(void *max_retx_reached_data, exit(1); } -void deliver_sdu_ue_am(void *deliver_sdu_data, - struct nr_rlc_entity_t *_entity, - char *buf, int size) +void deliver_sdu_ue_am(void *deliver_sdu_data, nr_rlc_entity_t *_entity, char *buf, int size) { nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; printf("TEST: UE: %"PRIu64": deliver SDU size %d [", @@ -168,9 +160,7 @@ void deliver_sdu_ue_am(void *deliver_sdu_data, printf("]\n"); } -void deliver_sdu_ue_um(void *deliver_sdu_data, - struct nr_rlc_entity_t *_entity, - char *buf, int size) +void deliver_sdu_ue_um(void *deliver_sdu_data, nr_rlc_entity_t *_entity, char *buf, int size) { nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity; printf("TEST: UE: %"PRIu64": deliver SDU size %d [", @@ -179,9 +169,7 @@ void deliver_sdu_ue_um(void *deliver_sdu_data, printf("]\n"); } -void deliver_sdu_ue_tm(void *deliver_sdu_data, - struct nr_rlc_entity_t *_entity, - char *buf, int size) +void deliver_sdu_ue_tm(void *deliver_sdu_data, nr_rlc_entity_t *_entity, char *buf, int size) { nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity; printf("TEST: UE: %"PRIu64": deliver SDU size %d [", diff --git a/openair2/LAYER2/nr_rlc/tests/test_nr_rlc_am_entity.cpp b/openair2/LAYER2/nr_rlc/tests/test_nr_rlc_am_entity.cpp index 5407f7b2ae..5f07b9243e 100644 --- a/openair2/LAYER2/nr_rlc/tests/test_nr_rlc_am_entity.cpp +++ b/openair2/LAYER2/nr_rlc/tests/test_nr_rlc_am_entity.cpp @@ -31,7 +31,7 @@ extern configmodule_interface_t *uniqCfg; int sdu_delivered_count = 0; int sdu_acked_count = 0; -void deliver_sdu(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, char *buf, int size) +void deliver_sdu(void *deliver_sdu_data, nr_rlc_entity_t *entity, char *buf, int size) { sdu_delivered_count++; char payload[300]; @@ -40,13 +40,13 @@ void deliver_sdu(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, char *b std::cout << "Delivered sdu: " << payload << std::endl; } -void sdu_successful_delivery(void *sdu_successful_delivery_data, struct nr_rlc_entity_t *entity, int sdu_id) +void sdu_successful_delivery(void *sdu_successful_delivery_data, nr_rlc_entity_t *entity, int sdu_id) { sdu_acked_count++; std::cout << "SDU " << sdu_id << " acked" << std::endl; } -void max_retx_reached(void *max_retx_reached_data, struct nr_rlc_entity_t *entity) +void max_retx_reached(void *max_retx_reached_data, nr_rlc_entity_t *entity) { } diff --git a/openair2/LAYER2/rlc_v2/rlc_entity.c b/openair2/LAYER2/rlc_v2/rlc_entity.c index d774e2b7e1..26af68e58b 100644 --- a/openair2/LAYER2/rlc_v2/rlc_entity.c +++ b/openair2/LAYER2/rlc_v2/rlc_entity.c @@ -28,25 +28,22 @@ #include "LOG/log.h" -rlc_entity_t *new_rlc_entity_am( - int rx_maxsize, - int tx_maxsize, - void (*deliver_sdu)(void *deliver_sdu_data, struct rlc_entity_t *entity, - char *buf, int size), - void *deliver_sdu_data, - void (*sdu_successful_delivery)(void *sdu_successful_delivery_data, - struct rlc_entity_t *entity, - int sdu_id), - void *sdu_successful_delivery_data, - void (*max_retx_reached)(void *max_retx_reached_data, - struct rlc_entity_t *entity), - void *max_retx_reached_data, - int t_reordering, - int t_status_prohibit, - int t_poll_retransmit, - int poll_pdu, - int poll_byte, - int max_retx_threshold) +rlc_entity_t *new_rlc_entity_am(int rx_maxsize, + int tx_maxsize, + void (*deliver_sdu)(void *deliver_sdu_data, rlc_entity_t *entity, char *buf, int size), + void *deliver_sdu_data, + void (*sdu_successful_delivery)(void *sdu_successful_delivery_data, + rlc_entity_t *entity, + int sdu_id), + void *sdu_successful_delivery_data, + void (*max_retx_reached)(void *max_retx_reached_data, rlc_entity_t *entity), + void *max_retx_reached_data, + int t_reordering, + int t_status_prohibit, + int t_poll_retransmit, + int poll_pdu, + int poll_byte, + int max_retx_threshold) { rlc_entity_am_t *ret; @@ -91,14 +88,12 @@ rlc_entity_t *new_rlc_entity_am( return (rlc_entity_t *)ret; } -rlc_entity_t *new_rlc_entity_um( - int rx_maxsize, - int tx_maxsize, - void (*deliver_sdu)(void *deliver_sdu_data, struct rlc_entity_t *entity, - char *buf, int size), - void *deliver_sdu_data, - int t_reordering, - int sn_field_length) +rlc_entity_t *new_rlc_entity_um(int rx_maxsize, + int tx_maxsize, + void (*deliver_sdu)(void *deliver_sdu_data, rlc_entity_t *entity, char *buf, int size), + void *deliver_sdu_data, + int t_reordering, + int sn_field_length) { rlc_entity_um_t *ret; diff --git a/openair2/LAYER2/rlc_v2/rlc_entity.h b/openair2/LAYER2/rlc_v2/rlc_entity.h index c9b35204f0..d0be4d87e7 100644 --- a/openair2/LAYER2/rlc_v2/rlc_entity.h +++ b/openair2/LAYER2/rlc_v2/rlc_entity.h @@ -32,66 +32,55 @@ typedef struct { int retx_size; } rlc_entity_buffer_status_t; -typedef struct rlc_entity_t { +typedef struct rlc_entity_s { /* functions provided by the RLC module */ - void (*recv_pdu)(struct rlc_entity_t *entity, char *buffer, int size); - rlc_entity_buffer_status_t (*buffer_status)( - struct rlc_entity_t *entity, int maxsize); - int (*generate_pdu)(struct rlc_entity_t *entity, char *buffer, int size); + void (*recv_pdu)(struct rlc_entity_s *entity, char *buffer, int size); + rlc_entity_buffer_status_t (*buffer_status)(struct rlc_entity_s *entity, int maxsize); + int (*generate_pdu)(struct rlc_entity_s *entity, char *buffer, int size); - void (*recv_sdu)(struct rlc_entity_t *entity, char *buffer, int size, - int sdu_id); + void (*recv_sdu)(struct rlc_entity_s *entity, char *buffer, int size, int sdu_id); - void (*set_time)(struct rlc_entity_t *entity, uint64_t now); + void (*set_time)(struct rlc_entity_s *entity, uint64_t now); - void (*discard_sdu)(struct rlc_entity_t *entity, int sdu_id); + void (*discard_sdu)(struct rlc_entity_s *entity, int sdu_id); - void (*reestablishment)(struct rlc_entity_t *entity); + void (*reestablishment)(struct rlc_entity_s *entity); - void (*delete)(struct rlc_entity_t *entity); + void (*delete)(struct rlc_entity_s *entity); /* callbacks provided to the RLC module */ - void (*deliver_sdu)(void *deliver_sdu_data, struct rlc_entity_t *entity, - char *buf, int size); + void (*deliver_sdu)(void *deliver_sdu_data, struct rlc_entity_s *entity, char *buf, int size); void *deliver_sdu_data; - void (*sdu_successful_delivery)(void *sdu_successful_delivery_data, - struct rlc_entity_t *entity, - int sdu_id); + void (*sdu_successful_delivery)(void *sdu_successful_delivery_data, struct rlc_entity_s *entity, int sdu_id); void *sdu_successful_delivery_data; - void (*max_retx_reached)(void *max_retx_reached_data, - struct rlc_entity_t *entity); + void (*max_retx_reached)(void *max_retx_reached_data, struct rlc_entity_s *entity); void *max_retx_reached_data; } rlc_entity_t; -rlc_entity_t *new_rlc_entity_am( - int rx_maxsize, - int tx_maxsize, - void (*deliver_sdu)(void *deliver_sdu_data, struct rlc_entity_t *entity, - char *buf, int size), - void *deliver_sdu_data, - void (*sdu_successful_delivery)(void *sdu_successful_delivery_data, - struct rlc_entity_t *entity, - int sdu_id), - void *sdu_successful_delivery_data, - void (*max_retx_reached)(void *max_retx_reached_data, - struct rlc_entity_t *entity), - void *max_retx_reached_data, - int t_reordering, - int t_status_prohibit, - int t_poll_retransmit, - int poll_pdu, - int poll_byte, - int max_retx_threshold); +rlc_entity_t *new_rlc_entity_am(int rx_maxsize, + int tx_maxsize, + void (*deliver_sdu)(void *deliver_sdu_data, rlc_entity_t *entity, char *buf, int size), + void *deliver_sdu_data, + void (*sdu_successful_delivery)(void *sdu_successful_delivery_data, + rlc_entity_t *entity, + int sdu_id), + void *sdu_successful_delivery_data, + void (*max_retx_reached)(void *max_retx_reached_data, rlc_entity_t *entity), + void *max_retx_reached_data, + int t_reordering, + int t_status_prohibit, + int t_poll_retransmit, + int poll_pdu, + int poll_byte, + int max_retx_threshold); -rlc_entity_t *new_rlc_entity_um( - int rx_maxsize, - int tx_maxsize, - void (*deliver_sdu)(void *deliver_sdu_data, struct rlc_entity_t *entity, - char *buf, int size), - void *deliver_sdu_data, - int t_reordering, - int sn_field_length); +rlc_entity_t *new_rlc_entity_um(int rx_maxsize, + int tx_maxsize, + void (*deliver_sdu)(void *deliver_sdu_data, rlc_entity_t *entity, char *buf, int size), + void *deliver_sdu_data, + int t_reordering, + int sn_field_length); #endif /* _RLC_ENTITY_H_ */ diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 73845551af..5fb8ad78dd 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -106,7 +106,6 @@ void print_ue_mac_stats(const module_id_t mod, const int frame_rx, const int slo static int handle_bcch_bch(NR_UE_MAC_INST_t *mac, int cc_id, unsigned int gNB_index, - void *phy_data, uint8_t *pduP, unsigned int additional_bits, uint32_t ssb_index_mod8, @@ -149,17 +148,13 @@ static int handle_bcch_dlsch(NR_UE_MAC_INST_t *mac, } // L2 Abstraction Layer -static nr_dci_format_t handle_dci(NR_UE_MAC_INST_t *mac, - unsigned int gNB_index, - frame_t frame, - int slot, - fapi_nr_dci_indication_pdu_t *dci) +static nr_dci_format_t handle_dci(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci) { // if notification of a reception of a PDCCH transmission of the SpCell is received from lower layers // if the C-RNTI MAC CE was included in Msg3 // consider this Contention Resolution successful if (mac->msg3_C_RNTI && mac->ra.ra_state == nrRA_WAIT_CONTENTION_RESOLUTION) - nr_ra_succeeded(mac, gNB_index, frame, slot); + nr_ra_succeeded(mac, frame, slot); // suspend RAR response window timer // (in RFsim running multiple slot in parallel it might expire while decoding MSG2) @@ -245,11 +240,7 @@ static uint32_t nr_ue_dl_processing(NR_UE_MAC_INST_t *mac, nr_downlink_indicatio LOG_T(MAC, "[L2][IF MODULE][DL INDICATION][DCI_IND]\n"); for (int i = 0; i < dl_info->dci_ind->number_of_dcis; i++) { LOG_T(MAC, ">>>NR_IF_Module i=%d, dl_info->dci_ind->number_of_dcis=%d\n", i, dl_info->dci_ind->number_of_dcis); - nr_dci_format_t dci_format = handle_dci(mac, - dl_info->gNB_index, - dl_info->frame, - dl_info->slot, - dl_info->dci_ind->dci_list + i); + nr_dci_format_t dci_format = handle_dci(mac, dl_info->frame, dl_info->slot, dl_info->dci_ind->dci_list + i); /* The check below filters out UL_DCIs which are being processed as DL_DCIs. */ if (dci_format != NR_DL_DCI_FORMAT_1_0 && dci_format != NR_DL_DCI_FORMAT_1_1) { @@ -291,7 +282,6 @@ static uint32_t nr_ue_dl_processing(NR_UE_MAC_INST_t *mac, nr_downlink_indicatio ret_mask |= (handle_bcch_bch(mac, dl_info->cc_id, dl_info->gNB_index, - dl_info->phy_data, rx_indication_body.ssb_pdu.pdu, rx_indication_body.ssb_pdu.additional_bits, rx_indication_body.ssb_pdu.ssb_index, diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.c b/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.c index 97c5a4e130..439371c013 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.c @@ -25,7 +25,7 @@ nr_bler_struct nr_bler_data[NR_NUM_MCS]; -slot_rnti_mcs_s slot_rnti_mcs[NUM_NFAPI_SLOT]; +slot_rnti_mcs_t slot_rnti_mcs[NUM_NFAPI_SLOT]; void read_channel_param(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t * pdu, int slot, int index) { if (pdu == NULL) diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.h b/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.h index dcc5710724..4db7f64a4f 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.h +++ b/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.h @@ -44,13 +44,6 @@ typedef struct { uint8_t area_code; } nr_channel_status; -typedef struct nr_phy_channel_params_t { - uint16_t sfn_slot; - uint16_t message_id; - uint16_t nb_of_csi; - nr_channel_status csi[NR_NUM_LAYER]; -} nr_phy_channel_params_t; - typedef struct { uint8_t slot; uint16_t rnti[MAX_NR_CHAN_PARAMS]; @@ -61,7 +54,7 @@ typedef struct { bool drop_flag[MAX_NR_CHAN_PARAMS]; bool latest; uint8_t area_code; -} slot_rnti_mcs_s; +} slot_rnti_mcs_t; typedef struct { uint16_t length; diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c index 6b327d92bc..87481ec316 100644 --- a/openair2/RRC/LTE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -130,9 +130,8 @@ static int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_ static int decode_SIB1_MBMS( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, const uint8_t rsrq, const uint8_t rsrp ); -typedef struct rrc_dcch_data_copy_t -{ - LTE_DL_DCCH_Message_t *dl_dcch_msg; +typedef struct { + LTE_DL_DCCH_Message_t *dl_dcch_msg; } rrc_dcch_data_copy_t; static void rrc_ue_process_ueCapabilityEnquiry(const protocol_ctxt_t *const ctxt_pP, diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 936f333124..7fea00e5dc 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -207,7 +207,7 @@ static bool rrc_delay_transaction(instance_t instance, MessageDef *msg_p) return false; /* not delayed */ } -typedef struct deliver_ue_ctxt_release_data_t { +typedef struct { gNB_RRC_INST *rrc; f1ap_ue_context_rel_cmd_t *release_cmd; sctp_assoc_t assoc_id; diff --git a/openair2/RRC/NR/rrc_gNB_du.c b/openair2/RRC/NR/rrc_gNB_du.c index 76f1ab1741..70fec34a83 100644 --- a/openair2/RRC/NR/rrc_gNB_du.c +++ b/openair2/RRC/NR/rrc_gNB_du.c @@ -53,12 +53,12 @@ #include "utils.h" #include "xer_encoder.h" -static int get_dl_band(const struct f1ap_served_cell_info_t *cell_info) +static int get_dl_band(const f1ap_served_cell_info_t *cell_info) { return cell_info->mode == F1AP_MODE_TDD ? cell_info->tdd.freqinfo.band : cell_info->fdd.dl_freqinfo.band; } -static int get_ssb_scs(const struct f1ap_served_cell_info_t *cell_info) +static int get_ssb_scs(const f1ap_served_cell_info_t *cell_info) { return cell_info->mode == F1AP_MODE_TDD ? cell_info->tdd.tbw.scs : cell_info->fdd.dl_tbw.scs; } diff --git a/openair2/RRC/NR/rrc_gNB_du.h b/openair2/RRC/NR/rrc_gNB_du.h index 343ab5d189..e746b9af96 100644 --- a/openair2/RRC/NR/rrc_gNB_du.h +++ b/openair2/RRC/NR/rrc_gNB_du.h @@ -37,8 +37,8 @@ struct f1ap_served_cell_info_t; #include "f1ap_messages_types.h" #include "ngap_messages_types.h" -void rrc_gNB_process_f1_setup_req(struct f1ap_setup_req_s *req, sctp_assoc_t assoc_id); -void rrc_CU_process_f1_lost_connection(struct gNB_RRC_INST_s *rrc, struct f1ap_lost_connection_t *lc, sctp_assoc_t assoc_id); +void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id); +void rrc_CU_process_f1_lost_connection(struct gNB_RRC_INST_s *rrc, f1ap_lost_connection_t *lc, sctp_assoc_t assoc_id); void rrc_gNB_process_f1_du_configuration_update(struct f1ap_gnb_du_configuration_update_s *conf_up, sctp_assoc_t assoc_id); struct nr_rrc_du_container_t *get_du_for_ue(struct gNB_RRC_INST_s *rrc, uint32_t ue_id); diff --git a/openair2/RRC/NR/rrc_gNB_mobility.c b/openair2/RRC/NR/rrc_gNB_mobility.c index 4d2785d9a0..3c59cdfc16 100644 --- a/openair2/RRC/NR/rrc_gNB_mobility.c +++ b/openair2/RRC/NR/rrc_gNB_mobility.c @@ -163,7 +163,7 @@ static void nr_initiate_handover(const gNB_RRC_INST *rrc, rrc_f1_ue_context_setup_for_target_du(rrc, ue, target_cell, ho_prep_info); } -typedef struct deliver_ue_ctxt_modification_data_t { +typedef struct { gNB_RRC_INST *rrc; f1ap_ue_context_mod_req_t *modification_req; sctp_assoc_t assoc_id; diff --git a/openair2/RRC/NR/rrc_gNB_mobility.h b/openair2/RRC/NR/rrc_gNB_mobility.h index d4a51efeb9..6eb65b51e5 100644 --- a/openair2/RRC/NR/rrc_gNB_mobility.h +++ b/openair2/RRC/NR/rrc_gNB_mobility.h @@ -28,7 +28,6 @@ /* forward declarations */ typedef struct gNB_RRC_INST_s gNB_RRC_INST; typedef struct gNB_RRC_UE_s gNB_RRC_UE_t; -typedef struct nr_rrc_cell_container_t nr_rrc_cell_container_t; typedef struct NR_CellGroupConfig NR_CellGroupConfig_t; diff --git a/openair3/NGAP/ngap_gNB.c b/openair3/NGAP/ngap_gNB.c index 257ca25f1a..995de828bb 100644 --- a/openair3/NGAP/ngap_gNB.c +++ b/openair3/NGAP/ngap_gNB.c @@ -58,6 +58,7 @@ #include "ngap_gNB_mobility_management.h" #include "ngap_gNB_ue_context.h" #include "ngap_gNB_pdu_session_management.h" +#include "ngap_gNB_NRPPa_transport_procedures.h" #include "oai_asn1.h" #include "openair3/SECU/kdf.h" #include "queue.h" @@ -93,6 +94,38 @@ uint32_t ngap_generate_gNB_id(void) return gNB_id; } +static void ngap_gNB_redial_amf(ngap_gNB_amf_data_t *amf_desc_p) +{ + NGAP_INFO("AMF cnx_id = %u\n", amf_desc_p->cnx_id); + NGAP_INFO("AMF state = %d\n", amf_desc_p->state); + /*reconnect with the amf */ + MessageDef *message_p = itti_alloc_new_message(TASK_NGAP, 0, SCTP_NEW_ASSOCIATION_REQ); + sctp_new_association_req_t *req = &message_p->ittiMsg.sctp_new_association_req; + + /*amf descriptor */ + req->port = NGAP_PORT_NUMBER; + req->ppid = NGAP_SCTP_PPID; + req->in_streams = amf_desc_p->in_streams; + req->out_streams = amf_desc_p->out_streams; + req->ulp_cnx_id = amf_desc_p->cnx_id; + + ngap_gNB_instance_t *inst = amf_desc_p->ngap_gNB_instance; + + memcpy(&req->remote_address, &amf_desc_p->amf_s1_ip, sizeof(req->remote_address)); + memcpy(&req->local_address, &inst->gNB_ng_ip, sizeof(req->local_address)); + + NGAP_INFO("[gNB %ld] Re-dial AMF cnx_id=%u (streams in=%u out=%u)\n", + inst->instance, + amf_desc_p->cnx_id, + req->in_streams, + req->out_streams); + + inst->ngap_amf_nb++; + inst->ngap_amf_pending_nb++; + + itti_send_msg_to_task(TASK_SCTP, inst->instance, message_p); +} + static void ngap_gNB_register_amf(ngap_gNB_instance_t *instance_p, net_ip_address_t *amf_ip_address, net_ip_address_t *local_ip_addr, @@ -550,6 +583,15 @@ void *ngap_gNB_process_itti_msg(void *notUsed) { ngap_gNB_handle_sctp_association_resp(instance, &received_msg->ittiMsg.sctp_new_association_resp); break; + case TIMER_HAS_EXPIRED: { + timer_has_expired_t *th = &received_msg->ittiMsg.timer_has_expired; + ngap_gNB_amf_data_t *amf_desc_p = (ngap_gNB_amf_data_t *)th->arg; + if (amf_desc_p) { + ngap_gNB_redial_amf(amf_desc_p); + } + break; + } + case SCTP_DATA_IND: ngap_gNB_handle_sctp_data_ind(&received_msg->ittiMsg.sctp_data_ind); break; @@ -626,6 +668,14 @@ void *ngap_gNB_process_itti_msg(void *notUsed) { ngap_gNB_handle_ul_ran_status_transfer(instance, &NGAP_UL_RAN_STATUS_TRANSFER(received_msg)); break; + case NGAP_UPLINKUEASSOCIATEDNRPPA: + ngap_gNB_uplink_ue_associated_nrppa_transport(instance, &NGAP_UPLINKUEASSOCIATEDNRPPA(received_msg)); + break; + + case NGAP_UPLINKNONUEASSOCIATEDNRPPA: + ngap_gNB_uplink_non_ue_associated_nrppa_transport(instance, &NGAP_UPLINKNONUEASSOCIATEDNRPPA(received_msg)); + break; + default: NGAP_ERROR("Received unhandled message: %d:%s\n", ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg)); break; diff --git a/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.c b/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.c new file mode 100644 index 0000000000..37b5e3b344 --- /dev/null +++ b/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.c @@ -0,0 +1,314 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include +#include +#include + +#include "assertions.h" +#include "conversions.h" + +#include "intertask_interface.h" + +#include "ngap_common.h" +#include "ngap_gNB_defs.h" +#include "ngap_gNB_itti_messaging.h" +#include "ngap_gNB_encoder.h" +#include "ngap_gNB_nnsf.h" +#include "ngap_gNB_ue_context.h" +#include "ngap_gNB_management_procedures.h" + +#include "ngap_gNB_NRPPa_transport_procedures.h" + +// UPLINK UE ASSOCIATED NRPPA TRANSPORT (9.2.9.2 of TS 38.413 Version 16.0.0) +int ngap_gNB_uplink_ue_associated_nrppa_transport(instance_t instance, const ngap_uplink_ue_associated_nrppa_t *msg) +{ + LOG_I(NGAP, "Initiating ngap_gNB_uplink_ue_associated_nrppa_transport \n"); + DevAssert(msg != NULL); + DevAssert(msg->routing_id.buf); + DevAssert(msg->routing_id.len); + DevAssert(msg->nrppa_pdu.buf); + DevAssert(msg->nrppa_pdu.len); + struct ngap_gNB_ue_context_s *ue_context_p = NULL; + ngap_gNB_instance_t *ngap_gNB_instance_p = NULL; + + // Retrieve the NGAP gNB instance associated with Mod_id + ngap_gNB_instance_p = ngap_gNB_get_instance(instance); + DevAssert(ngap_gNB_instance_p != NULL); + + if ((ue_context_p = ngap_get_ue_context(msg->gNB_ue_ngap_id)) == NULL) { + // The context for this gNB ue ngap id doesn't exist in the map of gNB UEs + LOG_E(NGAP, "Failed to find ue context associated with gNB ue ngap id: %08x\n", msg->gNB_ue_ngap_id); + return -1; + } + /* Prepare the NGAP message to encode */ + NGAP_NGAP_PDU_t pdu = {0}; + + // IE: 9.3.1.1 Message Type UplinkUEAssociatedNRPPaTransport + pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; + asn1cCalloc(pdu.choice.initiatingMessage, head); + head->procedureCode = NGAP_ProcedureCode_id_UplinkUEAssociatedNRPPaTransport; + head->criticality = NGAP_Criticality_ignore; + head->value.present = NGAP_InitiatingMessage__value_PR_UplinkUEAssociatedNRPPaTransport; + NGAP_UplinkUEAssociatedNRPPaTransport_t *out = &head->value.choice.UplinkUEAssociatedNRPPaTransport; + + // IE: 9.3.3.1 AMF UE NGAP ID (mandatory) + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_UplinkUEAssociatedNRPPaTransportIEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UplinkUEAssociatedNRPPaTransportIEs__value_PR_AMF_UE_NGAP_ID; + asn_uint642INTEGER(&ie->value.choice.AMF_UE_NGAP_ID, msg->amf_ue_ngap_id); + } + + // IE: 9.3.3.2 RAN UE NGAP ID (mandatory) + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_UplinkUEAssociatedNRPPaTransportIEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UplinkUEAssociatedNRPPaTransportIEs__value_PR_RAN_UE_NGAP_ID; + ie->value.choice.RAN_UE_NGAP_ID = msg->gNB_ue_ngap_id; + } + + // IE: 9.3.3.13 Routing ID (mandatory) + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_UplinkUEAssociatedNRPPaTransportIEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_RoutingID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UplinkUEAssociatedNRPPaTransportIEs__value_PR_RoutingID; + ie->value.choice.RoutingID.buf = msg->routing_id.buf; + ie->value.choice.RoutingID.size = msg->routing_id.len; + } + + // IE: 9.3.3.14 NRPPa-PDU (mandatory) + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_UplinkUEAssociatedNRPPaTransportIEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_NRPPa_PDU; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UplinkUEAssociatedNRPPaTransportIEs__value_PR_NRPPa_PDU; + ie->value.choice.NRPPa_PDU.buf = msg->nrppa_pdu.buf; + ie->value.choice.NRPPa_PDU.size = msg->nrppa_pdu.len; + } + + // Encode NGAP message + uint8_t *buffer = NULL; + uint32_t length = 0; + if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { + LOG_E(NGAP, "Failed to encode Uplink UE Associated NRPPa Transport\n"); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_NGAP_PDU, &pdu); + return -1; + } + LOG_I(NGAP, "Sending ngap_gNB_uplink_ue_associated_nrppa_transport over SCTP\n"); + + // UE associated signalling -> use the allocated stream + ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance, + ue_context_p->amf_ref->assoc_id, + buffer, + length, + ue_context_p->tx_stream); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_NGAP_PDU, &pdu); + return 0; +} + +// UPLINK NON UE ASSOCIATED NRPPA TRANSPORT (9.2.9.4 of TS 38.413 Version 16.0.0) +int ngap_gNB_uplink_non_ue_associated_nrppa_transport(instance_t instance, const ngap_uplink_non_ue_associated_nrppa_t *msg) +{ + LOG_I(NGAP, "ngap_gNB_uplink_non_ue_associated_nrppa_transport\n"); + DevAssert(msg != NULL); + DevAssert(msg->routing_id.buf); + DevAssert(msg->routing_id.len); + DevAssert(msg->nrppa_pdu.buf); + DevAssert(msg->nrppa_pdu.len); + + // Retrieve the NGAP gNB instance associated with Mod_id + ngap_gNB_instance_t *ngap_gNB_instance_p = NULL; + ngap_gNB_instance_p = ngap_gNB_get_instance(instance); + DevAssert(ngap_gNB_instance_p != NULL); + + // Retrieve the NGAP gNB amf data + ngap_gNB_amf_data_t *amf_desc_p = NULL; + amf_desc_p = ngap_gNB_get_AMF_from_instance(ngap_gNB_instance_p); + DevAssert(amf_desc_p != NULL); + + // Prepare the NGAP message to encode + NGAP_NGAP_PDU_t pdu = {0}; + + // IE: 9.3.1.1 Message Type UplinkNonUEAssociatedNRPPaTransport + pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; + asn1cCalloc(pdu.choice.initiatingMessage, head); + head->procedureCode = NGAP_ProcedureCode_id_UplinkNonUEAssociatedNRPPaTransport; + head->criticality = NGAP_Criticality_ignore; + head->value.present = NGAP_InitiatingMessage__value_PR_UplinkNonUEAssociatedNRPPaTransport; + NGAP_UplinkNonUEAssociatedNRPPaTransport_t *out = &head->value.choice.UplinkNonUEAssociatedNRPPaTransport; + + // IE: 9.3.3.13 Routing ID (mandatory) + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_UplinkNonUEAssociatedNRPPaTransportIEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_RoutingID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UplinkNonUEAssociatedNRPPaTransportIEs__value_PR_RoutingID; + ie->value.choice.RoutingID.buf = msg->routing_id.buf; + ie->value.choice.RoutingID.size = msg->routing_id.len; + } + + // IE: 9.3.3.14 NRPPa-PDU (mandatory) + { + asn1cSequenceAdd(out->protocolIEs.list, NGAP_UplinkNonUEAssociatedNRPPaTransportIEs_t, ie); + ie->id = NGAP_ProtocolIE_ID_id_NRPPa_PDU; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_UplinkNonUEAssociatedNRPPaTransportIEs__value_PR_NRPPa_PDU; + ie->value.choice.NRPPa_PDU.buf = msg->nrppa_pdu.buf; + ie->value.choice.NRPPa_PDU.size = msg->nrppa_pdu.len; + } + + // Encode NGAP message + uint8_t *buffer = NULL; + uint32_t length = 0; + if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { + LOG_E(NGAP, "Failed to encode Uplink Non UE Associated NRPPa Transport\n"); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_NGAP_PDU, &pdu); + return -1; + } + + // Non UE-Associated signalling -> stream = 0 + LOG_I(NGAP, "Sending ngap_gNB_uplink_non_ue_associated_nrppa_transport over SCTP (assoc_id %d)\n", amf_desc_p->assoc_id); + ngap_gNB_itti_send_sctp_data_req(ngap_gNB_instance_p->instance, amf_desc_p->assoc_id, buffer, length, 0); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_NGAP_PDU, &pdu); + return 0; +} + +// handle DOWNLINK UE ASSOCIATED NRPPA TRANSPORT (9.2.9.1 of TS 38.413 Version 16.0.0) +int ngap_gNB_handle_downlink_ue_associated_nrppa_transport(sctp_assoc_t assoc_id, uint32_t stream, NGAP_NGAP_PDU_t *pdu) +{ + DevAssert(pdu != NULL); + ngap_gNB_amf_data_t *amf_desc_p = NULL; + + if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) { + NGAP_ERROR("[SCTP %d] Received NRPPa downlink message for non existing AMF context\n", assoc_id); + return -1; + } + + ngap_gNB_instance_t *ngap_gNB_instance = NULL; + ngap_gNB_instance = amf_desc_p->ngap_gNB_instance; + + // Prepare the NGAP message for NRPPA + NGAP_DownlinkUEAssociatedNRPPaTransport_t *container = NULL; + NGAP_DownlinkUEAssociatedNRPPaTransportIEs_t *ie = NULL; + + // IE: 9.3.1.1 Message Type + container = &pdu->choice.initiatingMessage->value.choice.DownlinkUEAssociatedNRPPaTransport; + + // IE: 9.3.3.1 AMF UE NGAP ID + uint64_t amf_ue_ngap_id; + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_DownlinkUEAssociatedNRPPaTransportIEs_t, + ie, + container, + NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID, + true); + asn_INTEGER2ulong(&(ie->value.choice.AMF_UE_NGAP_ID), &amf_ue_ngap_id); + + // IE: 9.3.3.2 RAN UE NGAP ID + NGAP_RAN_UE_NGAP_ID_t gnb_ue_ngap_id; + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_DownlinkUEAssociatedNRPPaTransportIEs_t, + ie, + container, + NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID, + true); + gnb_ue_ngap_id = ie->value.choice.RAN_UE_NGAP_ID; + + ngap_gNB_ue_context_t *ue_desc_p = NULL; + if ((ue_desc_p = ngap_get_ue_context(gnb_ue_ngap_id)) == NULL) { + NGAP_ERROR("[SCTP %d] Received NRPPa downlink message for non existing UE context gNB_UE_NGAP_ID: 0x%lx\n", + assoc_id, + gnb_ue_ngap_id); + return -1; + } + + // Is it the first outcome of the AMF for this UE ? If so store the amf UE ngap id + if (ue_desc_p->amf_ue_ngap_id == 0) { + ue_desc_p->amf_ue_ngap_id = amf_ue_ngap_id; + } else { + // We already have a amf ue ngap id check the received is the same + if (ue_desc_p->amf_ue_ngap_id != amf_ue_ngap_id) { + NGAP_ERROR("[SCTP %d] Mismatch in AMF UE NGAP ID (0x%lx != 0x%" PRIx64 "\n", + assoc_id, + amf_ue_ngap_id, + (uint64_t)ue_desc_p->amf_ue_ngap_id); + return -1; + } + } + + MessageDef *msg = itti_alloc_new_message(TASK_NGAP, 0, NGAP_DOWNLINKUEASSOCIATEDNRPPA); + ngap_downlink_ue_associated_nrppa_t *dl_ue_assoc_nrppa = &NGAP_DOWNLINKUEASSOCIATEDNRPPA(msg); + + dl_ue_assoc_nrppa->amf_ue_ngap_id = amf_ue_ngap_id; + dl_ue_assoc_nrppa->gNB_ue_ngap_id = gnb_ue_ngap_id; + + // IE: 9.3.3.13 Routing ID + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_DownlinkUEAssociatedNRPPaTransportIEs_t, ie, container, NGAP_ProtocolIE_ID_id_RoutingID, true); + dl_ue_assoc_nrppa->routing_id = create_byte_array(ie->value.choice.RoutingID.size, ie->value.choice.RoutingID.buf); + + // IE: 9.3.3.14 NRPPa-PDU + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_DownlinkUEAssociatedNRPPaTransportIEs_t, ie, container, NGAP_ProtocolIE_ID_id_NRPPa_PDU, true); + dl_ue_assoc_nrppa->nrppa_pdu = create_byte_array(ie->value.choice.NRPPa_PDU.size, ie->value.choice.NRPPa_PDU.buf); + + // Forward the NRPPA PDU to NRPPA + itti_send_msg_to_task(TASK_NRPPA, ngap_gNB_instance->instance, msg); + + return 0; +} + +// handle DOWNLINK NON UE ASSOCIATED NRPPA TRANSPORT (9.2.9.3 of TS 38.413 Version 16.0.0) +int ngap_gNB_handle_downlink_non_ue_associated_nrppa_transport(sctp_assoc_t assoc_id, uint32_t stream, NGAP_NGAP_PDU_t *pdu) +{ + DevAssert(pdu != NULL); + ngap_gNB_amf_data_t *amf_desc_p = NULL; + + if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) { + NGAP_ERROR("[SCTP %d] Received NRPPa downlink message for non existing AMF context\n", assoc_id); + return -1; + } + + ngap_gNB_instance_t *ngap_gNB_instance = NULL; + ngap_gNB_instance = amf_desc_p->ngap_gNB_instance; + + MessageDef *msg = itti_alloc_new_message(TASK_NGAP, 0, NGAP_DOWNLINKNONUEASSOCIATEDNRPPA); + ngap_downlink_non_ue_associated_nrppa_t *dl_non_ue_assoc_nrppa = &NGAP_DOWNLINKNONUEASSOCIATEDNRPPA(msg); + + // Prepare the NGAP message to forward to NRPPA + NGAP_DownlinkNonUEAssociatedNRPPaTransport_t *container; + NGAP_DownlinkNonUEAssociatedNRPPaTransportIEs_t *ie; + + // IE: 9.3.1.1 Message Type + container = &pdu->choice.initiatingMessage->value.choice.DownlinkNonUEAssociatedNRPPaTransport; + + // IE: 9.3.3.13 Routing ID + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_DownlinkNonUEAssociatedNRPPaTransportIEs_t, ie, container, NGAP_ProtocolIE_ID_id_RoutingID, true); + dl_non_ue_assoc_nrppa->routing_id = create_byte_array(ie->value.choice.RoutingID.size, ie->value.choice.RoutingID.buf); + + // IE: 9.3.3.14 NRPPa-PDU + NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_DownlinkNonUEAssociatedNRPPaTransportIEs_t, ie, container, NGAP_ProtocolIE_ID_id_NRPPa_PDU, true); + dl_non_ue_assoc_nrppa->nrppa_pdu = create_byte_array(ie->value.choice.NRPPa_PDU.size, ie->value.choice.NRPPa_PDU.buf); + + itti_send_msg_to_task(TASK_NRPPA, ngap_gNB_instance->instance, msg); + + return 0; +} diff --git a/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.h b/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.h new file mode 100644 index 0000000000..a180888029 --- /dev/null +++ b/openair3/NGAP/ngap_gNB_NRPPa_transport_procedures.h @@ -0,0 +1,37 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef NGAP_GNB_NRPPA_PROCEDURES_H_ +#define NGAP_GNB_NRPPA_PROCEDURES_H_ + +// UPLINK UE ASSOCIATED NRPPA TRANSPORT (9.2.9.2 of TS 38.413 Version 16.0.0) +int ngap_gNB_uplink_ue_associated_nrppa_transport(instance_t instance, const ngap_uplink_ue_associated_nrppa_t *msg); + +// UPLINK NON UE ASSOCIATED NRPPA TRANSPORT (9.2.9.4 of TS 38.413 Version 16.0.0) +int ngap_gNB_uplink_non_ue_associated_nrppa_transport(instance_t instance, const ngap_uplink_non_ue_associated_nrppa_t *msg); + +// DOWNLINK UE ASSOCIATED NRPPA TRANSPORT (9.2.9.1 of TS 38.413 Version 16.0.0) +int ngap_gNB_handle_downlink_ue_associated_nrppa_transport(sctp_assoc_t assoc_id, uint32_t stream, NGAP_NGAP_PDU_t *pdu); + +// DOWNLINK UE ASSOCIATED NRPPA TRANSPORT (9.2.9.3 of TS 38.413 Version 16.0.0) +int ngap_gNB_handle_downlink_non_ue_associated_nrppa_transport(sctp_assoc_t assoc_id, uint32_t stream, NGAP_NGAP_PDU_t *pdu); + +#endif /* NGAP_GNB_NRPPA_PROCEDURES_H_ */ diff --git a/openair3/NGAP/ngap_gNB_decoder.c b/openair3/NGAP/ngap_gNB_decoder.c index 43110e9037..3993f8aa72 100644 --- a/openair3/NGAP/ngap_gNB_decoder.c +++ b/openair3/NGAP/ngap_gNB_decoder.c @@ -112,6 +112,18 @@ static int ngap_gNB_decode_initiating_message(NGAP_NGAP_PDU_t *pdu) { NGAP_INFO("DL RAN Status Transfer initiating message\n"); break; + case NGAP_ProcedureCode_id_DownlinkUEAssociatedNRPPaTransport: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); + free(res.buffer); + NGAP_INFO("DL UE Associated NRPPA Transport initiating message\n"); + break; + + case NGAP_ProcedureCode_id_DownlinkNonUEAssociatedNRPPaTransport: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NGAP_NGAP_PDU, pdu); + free(res.buffer); + NGAP_INFO("DL NON UE Associated NRPPA Transport initiating message\n"); + break; + default: NGAP_ERROR("Unknown procedure ID (%d) for initiating message\n", (int)pdu->choice.initiatingMessage->procedureCode); diff --git a/openair3/NGAP/ngap_gNB_defs.h b/openair3/NGAP/ngap_gNB_defs.h index 1a1e5768ff..b7c5dc3f64 100644 --- a/openair3/NGAP/ngap_gNB_defs.h +++ b/openair3/NGAP/ngap_gNB_defs.h @@ -161,6 +161,8 @@ struct ngap_gNB_instance_s; /* This structure describes association of a gNB to a AMF */ typedef struct ngap_gNB_amf_data_s { + long t_reconnect; // ITTI timer id (or equivalent) + /* AMF descriptors tree, ordered by sctp assoc id */ RB_ENTRY(ngap_gNB_amf_data_s) entry; diff --git a/openair3/NGAP/ngap_gNB_encoder.c b/openair3/NGAP/ngap_gNB_encoder.c index ff318ed184..801ce95d42 100644 --- a/openair3/NGAP/ngap_gNB_encoder.c +++ b/openair3/NGAP/ngap_gNB_encoder.c @@ -56,7 +56,9 @@ static inline int ngap_gNB_encode_initiating(NGAP_NGAP_PDU_t *pdu, uint8_t **buf NGAP_ProcedureCode_id_UplinkRANStatusTransfer, NGAP_ProcedureCode_id_HandoverPreparation, NGAP_ProcedureCode_id_HandoverCancel, - NGAP_ProcedureCode_id_HandoverNotification}; + NGAP_ProcedureCode_id_HandoverNotification, + NGAP_ProcedureCode_id_UplinkUEAssociatedNRPPaTransport, + NGAP_ProcedureCode_id_UplinkNonUEAssociatedNRPPaTransport}; int i; for (i = 0; i < sizeofArray(tmp); i++) if (pdu->choice.initiatingMessage->procedureCode == tmp[i]) diff --git a/openair3/NGAP/ngap_gNB_handlers.c b/openair3/NGAP/ngap_gNB_handlers.c index 9113f850ca..ddd39b2535 100644 --- a/openair3/NGAP/ngap_gNB_handlers.c +++ b/openair3/NGAP/ngap_gNB_handlers.c @@ -50,6 +50,7 @@ #include "ngap_gNB_pdu_session_management.h" #include "ngap_gNB_nas_procedures.h" #include "ngap_gNB_paging.h" +#include "ngap_gNB_NRPPa_transport_procedures.h" #include "ngap_gNB_trace.h" #include "ngap_gNB_ue_context.h" #include "ngap_messages_types.h" @@ -77,6 +78,8 @@ void ngap_handle_ng_setup_message(ngap_gNB_amf_data_t *amf_desc_p, int sctp_shut /* Decrease associated AMF number */ amf_desc_p->ngap_gNB_instance->ngap_amf_associated_nb --; } + /* Release UE context and start reconnection process*/ + ngap_release_ues_for_amf(amf_desc_p); /* If there are no more associated AMF, inform gNB app */ if (amf_desc_p->ngap_gNB_instance->ngap_amf_associated_nb == 0) { @@ -1499,10 +1502,10 @@ const ngap_message_decoded_callback ngap_messages_callback[][3] = { {0, 0, 0}, /* CellTrafficTrace */ {ngap_gNB_handle_deactivate_trace, 0, 0}, /* DeactivateTrace */ {ngap_gNB_handle_nas_downlink, 0, 0}, /* DownlinkNASTransport */ - {0, 0, 0}, /* DownlinkNonUEAssociatedNRPPaTransport */ + {ngap_gNB_handle_downlink_non_ue_associated_nrppa_transport, 0, 0}, /* DownlinkNonUEAssociatedNRPPaTransport */ {0, 0, 0}, /* DownlinkRANConfigurationTransfer */ {ngap_gNB_handle_dl_ran_status_transfer, 0, 0}, /* DownlinkRANStatusTransfer */ - {0, 0, 0}, /* DownlinkUEAssociatedNRPPaTransport */ + {ngap_gNB_handle_downlink_ue_associated_nrppa_transport, 0, 0}, /* DownlinkUEAssociatedNRPPaTransport */ {ngap_gNB_handle_error_indication, 0, 0}, /* ErrorIndication */ {0, ngap_gNB_handle_handover_cancel_ack, 0}, /* HandoverCancel */ {0, 0, 0}, /* HandoverNotification */ diff --git a/openair3/NGAP/ngap_gNB_nas_procedures.c b/openair3/NGAP/ngap_gNB_nas_procedures.c index 2d4bd3eefa..9e341494c6 100644 --- a/openair3/NGAP/ngap_gNB_nas_procedures.c +++ b/openair3/NGAP/ngap_gNB_nas_procedures.c @@ -59,7 +59,7 @@ #include "s1ap_messages_types.h" #include "xer_encoder.h" #include "ds/byte_array.h" - +#include "intertask_interface.h" /** @brief Selects the AMF instance for a given UE based on identity information. * It attempts to select an AMF using the following prioritized criteria: * 1. GUAMI, if provided and valid (via Region ID, Set ID, Pointer). diff --git a/openair3/NGAP/ngap_gNB_ue_context.c b/openair3/NGAP/ngap_gNB_ue_context.c index 994271d822..e50726380f 100644 --- a/openair3/NGAP/ngap_gNB_ue_context.c +++ b/openair3/NGAP/ngap_gNB_ue_context.c @@ -34,6 +34,8 @@ #include "common/utils/T/T.h" #include "ngap_common.h" #include "tree.h" +#include "intertask_interface.h" +#define SCTP_LOOKUP_TIMER_TIMEOUT_SEC 30 /* Tree of UE ordered by gNB_ue_ngap_id's * NO INSTANCE, the 32 bits id is large enough to handle all UEs, regardless the cell, gNB, ... @@ -92,3 +94,31 @@ struct ngap_gNB_ue_context_s *ngap_detach_ue_context(uint32_t gNB_ue_ngap_id) RB_REMOVE(ngap_ue_map, &ngap_ue_head, tmp); return tmp; } + +void ngap_release_ues_for_amf(ngap_gNB_amf_data_t *amf_desc_p) +{ + /* Release all UE contexts for this AMF */ + ngap_gNB_ue_context_t *ue = NULL; + ngap_gNB_ue_context_t *next = NULL; + RB_FOREACH_SAFE(ue, ngap_ue_map, &ngap_ue_head, next) { + if (ue->amf_ref == amf_desc_p) { + LOG_I(NGAP, "Releasing UE context: gNB UE NGAP ID: %u | AMF UE NGAP ID: %lu\n", ue->gNB_ue_ngap_id, ue->amf_ue_ngap_id); + MessageDef *msg_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_UE_CONTEXT_RELEASE_COMMAND); + NGAP_UE_CONTEXT_RELEASE_COMMAND(msg_p).gNB_ue_ngap_id = ue->gNB_ue_ngap_id; + itti_send_msg_to_task(TASK_RRC_GNB, amf_desc_p->ngap_gNB_instance->instance, msg_p); + } + } + /* Reset AMF connection and set reconnect timer */ + /* SCTP lookup timer */ + long tid; + int rc = timer_setup(SCTP_LOOKUP_TIMER_TIMEOUT_SEC, + 0, + TASK_NGAP, + amf_desc_p->ngap_gNB_instance->instance, + TIMER_ONE_SHOT, + amf_desc_p, + &tid); + if (rc == 0) { + amf_desc_p->t_reconnect = tid; + } +} diff --git a/openair3/NGAP/ngap_gNB_ue_context.h b/openair3/NGAP/ngap_gNB_ue_context.h index 8053e8f8c6..1ca458968f 100644 --- a/openair3/NGAP/ngap_gNB_ue_context.h +++ b/openair3/NGAP/ngap_gNB_ue_context.h @@ -74,6 +74,7 @@ typedef struct ngap_gNB_ue_context_s { } ngap_gNB_ue_context_t; void ngap_store_ue_context(const ngap_gNB_ue_context_t *ue_desc_p); +void ngap_release_ues_for_amf(ngap_gNB_amf_data_t *amf_desc_p); ngap_gNB_ue_context_t *ngap_get_ue_context(uint32_t gNB_ue_ngap_id); ngap_gNB_ue_context_t *ngap_get_ue_context_from_amf_ue_ngap_id(uint32_t amf_ue_ngap_id); diff --git a/openair3/NRPPA/CMakeLists.txt b/openair3/NRPPA/CMakeLists.txt index 613cbfc3ce..45f0964667 100644 --- a/openair3/NRPPA/CMakeLists.txt +++ b/openair3/NRPPA/CMakeLists.txt @@ -1,5 +1,15 @@ add_subdirectory(MESSAGES) -add_executable(test_nrppa ${OPENAIR3_DIR}/NRPPA/test_nrppa.c ) -target_link_libraries(test_nrppa asn1_nrppa) - +add_library(nrppa + nrppa_gNB.c + nrppa_gNB_config.c + nrppa_gNB_handlers.c + nrppa_gNB_decoder.c + nrppa_gNB_ue_context.c + nrppa_gNB_location_information_transfer.c + nrppa_gNB_encoder.c + nrppa_gNB_measurement_information_transfer.c + ) + +target_link_libraries(nrppa PUBLIC asn1_nrppa) +target_link_libraries(nrppa PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs) diff --git a/openair3/NRPPA/nrppa_common.h b/openair3/NRPPA/nrppa_common.h new file mode 100644 index 0000000000..b7c613e77a --- /dev/null +++ b/openair3/NRPPA/nrppa_common.h @@ -0,0 +1,62 @@ +/* + * 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 NRPPA_COMMON_H_ +#define NRPPA_COMMON_H_ + +#include "oai_asn1.h" +#include "common/utils/LOG/log.h" +#include "ds/byte_array.h" +#include "nrppa_includes.h" + +#define NRPPA_FIND_PROTOCOLIE_BY_ID(IE_TYPE, ie, container, IE_ID, mandatory) \ + do { \ + IE_TYPE **ptr; \ + ie = NULL; \ + for (ptr = container->protocolIEs.list.array; ptr < &container->protocolIEs.list.array[container->protocolIEs.list.count]; \ + ptr++) { \ + if ((*ptr)->id == IE_ID) { \ + ie = *ptr; \ + break; \ + } \ + } \ + if (ie == NULL) { \ + if (mandatory) { \ + AssertFatal(false, "NRPPA_FIND_PROTOCOLIE_BY_ID ie is NULL (searching for ie: %ld)\n", IE_ID); \ + } else { \ + LOG_I(NRPPA, "NRPPA_FIND_PROTOCOLIE_BY_ID ie is NULL (searching for ie: %ld)\n", IE_ID); \ + } \ + } \ + } while (0); \ + if (mandatory && !ie) \ + return -1 + +// gnb and ue related info in NRPPA message +typedef struct nrppa_gnb_ue_info_s { + instance_t instance; + int32_t gNB_ue_ngap_id; + int64_t amf_ue_ngap_id; + byte_array_t routing_id; +} nrppa_gnb_ue_info_t; + +typedef int (*nrppa_message_decoded_callback)(nrppa_gnb_ue_info_t *nrppa_msg_info, const NRPPA_NRPPA_PDU_t *pdu); + +#endif /* NRPPA_COMMON_H_ */ diff --git a/openair3/NRPPA/nrppa_gNB.c b/openair3/NRPPA/nrppa_gNB.c new file mode 100644 index 0000000000..a561c026fd --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB.c @@ -0,0 +1,92 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "tree.h" +#include "queue.h" + +#include "intertask_interface.h" + +#include "assertions.h" +#include "conversions.h" + +#include "nrppa_gNB.h" +#include "nrppa_common.h" +#include "nrppa_gNB_handlers.h" +#include "nrppa_gNB_location_information_transfer.h" +#include "nrppa_gNB_measurement_information_transfer.h" + +void nrppa_gNB_init(void) +{ + LOG_I(NRPPA, "Starting NRPPA layer\n"); + itti_mark_task_ready(TASK_NRPPA); +} + +void *nrppa_gNB_process_itti_msg(void *notUsed) +{ + MessageDef *received_msg = NULL; + int result; + itti_receive_msg(TASK_NRPPA, &received_msg); + if (received_msg) { + instance_t instance = ITTI_MSG_DESTINATION_INSTANCE(received_msg); + LOG_I(NRPPA, "Received message %s\n", ITTI_MSG_NAME(received_msg)); + switch (ITTI_MSG_ID(received_msg)) { + case TERMINATE_MESSAGE: + LOG_W(NRPPA, " *** Exiting NRPPA thread\n"); + itti_exit_task(); + break; + case NGAP_DOWNLINKUEASSOCIATEDNRPPA: + nrppa_handle_downlink_ue_associated_nrppa_transport(instance, &NGAP_DOWNLINKUEASSOCIATEDNRPPA(received_msg)); + break; + case NGAP_DOWNLINKNONUEASSOCIATEDNRPPA: + nrppa_handle_downlink_non_ue_associated_nrppa_transport(instance, &NGAP_DOWNLINKNONUEASSOCIATEDNRPPA(received_msg)); + break; + case NRPPA_TRP_INFORMATION_RESP: + nrppa_gNB_trp_information_response(instance, received_msg); + break; + case NRPPA_POSITIONING_INFORMATION_RESP: + nrppa_gNB_positioning_information_response(instance, received_msg); + break; + case NRPPA_POSITIONING_ACTIVATION_RESP: + nrppa_gNB_positioning_activation_response(instance, received_msg); + break; + case NRPPA_MEASUREMENT_RESP: + nrppa_gNB_measurement_response(instance, received_msg); + break; + default: + LOG_E(NRPPA, "Received unhandled message: %d:%s\n", ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg)); + break; + } + result = itti_free(ITTI_MSG_ORIGIN_ID(received_msg), received_msg); + AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + } + return NULL; +} + +void *nrppa_gNB_task(void *arg) +{ + nrppa_gNB_init(); + + while (1) { + (void)nrppa_gNB_process_itti_msg(NULL); + } + + return NULL; +} diff --git a/openair3/NRPPA/nrppa_gNB.h b/openair3/NRPPA/nrppa_gNB.h new file mode 100644 index 0000000000..628cfc4587 --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB.h @@ -0,0 +1,32 @@ +/* + * 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 + +#ifndef NRPPA_GNB_H_ +#define NRPPA_GNB_H_ + +void nrppa_gNB_init(void); +void *nrppa_gNB_process_itti_msg(void *notUsed); +void *nrppa_gNB_task(void *arg); + +#endif /* NRPPA_GNB_H_ */ diff --git a/openair3/NRPPA/nrppa_gNB_config.c b/openair3/NRPPA/nrppa_gNB_config.c new file mode 100644 index 0000000000..dc0590f603 --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB_config.c @@ -0,0 +1,84 @@ +/* + * 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 "nrppa_gNB_config.h" +#include "assertions.h" +#include "openair1/PHY/defs_nr_common.h" +#include "openair1/PHY/defs_gNB.h" +#include "common/ran_context.h" +#include "positioning_nr_paramdef.h" + +positioning_config_t RCconfig_nr_positioning(void) +{ + positioning_config_t positioning_config = {0}; + paramdef_t positioning_params_desc[] = POSITIONING_PARAMS_DESC; + int num_params = sizeofArray(positioning_params_desc); + GET_PARAMS_LIST(POSITIONING_ParamList, POSITIONING_Params, POSITIONING_PARAMS_DESC, CONFIG_STRING_POSITIONING_CONFIG, NULL); + + if (POSITIONING_ParamList.numelt > 0) { + paramdef_t *params = POSITIONING_ParamList.paramarray[0]; + + uint8_t num_trp = *gpd(params, num_params, CONFIG_STRING_POSITIONING_NUM_TRPS)->uptr; + if (num_trp == 0) { + LOG_E(NR_PHY, "No TRP configuration found..!!!\n"); + return positioning_config; + } else if (num_trp > MAX_NUM_TRPs) { + AssertFatal(false, "Exceeded MAX number of TRPs\n"); + } + + uint8_t num_ids = gpd(params, num_params, CONFIG_STRING_POSITIONING_TRP_IDS_LIST)->numelt; + uint8_t num_x = gpd(params, num_params, CONFIG_STRING_POSITIONING_TRP_X_AXIS_LIST)->numelt; + uint8_t num_y = gpd(params, num_params, CONFIG_STRING_POSITIONING_TRP_Y_AXIS_LIST)->numelt; + uint8_t num_z = gpd(params, num_params, CONFIG_STRING_POSITIONING_TRP_Z_AXIS_LIST)->numelt; + uint8_t num_unit = gpd(params, num_params, CONFIG_STRING_POSITIONING_TRP_UNIT_LIST)->numelt; + + if (num_trp != num_ids || num_trp != num_x || num_trp != num_y || num_trp != num_z || num_trp != num_unit) { + AssertFatal(false, "Mismatch in the number of TRPs with the number of ids, x-axis, y-axis, z-axis, units\n"); + } + + positioning_config.num_trp = num_trp; + for (int l = 0; l < num_trp; l++) { + positioning_config.trps[l].id = gpd(params, num_params, CONFIG_STRING_POSITIONING_TRP_IDS_LIST)->uptr[l]; + positioning_config.trps[l].x_axis = gpd(params, num_params, CONFIG_STRING_POSITIONING_TRP_X_AXIS_LIST)->uptr[l]; + positioning_config.trps[l].y_axis = gpd(params, num_params, CONFIG_STRING_POSITIONING_TRP_Y_AXIS_LIST)->uptr[l]; + positioning_config.trps[l].z_axis = gpd(params, num_params, CONFIG_STRING_POSITIONING_TRP_Z_AXIS_LIST)->uptr[l]; + positioning_config.trps[l].unit = gpd(params, num_params, CONFIG_STRING_POSITIONING_TRP_UNIT_LIST)->uptr[l]; + } + } else { + LOG_I(NR_PHY, "No " CONFIG_STRING_POSITIONING_CONFIG " configuration found..!!\n"); + } + return positioning_config; +} + +void dump_positioning_config(const positioning_config_t *positioning_config) +{ + uint8_t num_trp = positioning_config->num_trp; + LOG_I(NR_PHY, "-----------------------------------------\n"); + LOG_I(NR_PHY, "Positioning Config\n"); + LOG_I(NR_PHY, "-----------------------------------------\n"); + LOG_I(NR_PHY, "Number of TRPs \t\t%d\n", num_trp); + for (int i = 0; i < num_trp; i++) { + LOG_I(NR_PHY, "X-axis of TRP ID %d \t\t%d\n", positioning_config->trps[i].id, positioning_config->trps[i].x_axis); + LOG_I(NR_PHY, "Y-axis of TRP ID %d \t\t%d\n", positioning_config->trps[i].id, positioning_config->trps[i].y_axis); + LOG_I(NR_PHY, "Z-axis of TRP ID %d \t\t%d\n", positioning_config->trps[i].id, positioning_config->trps[i].z_axis); + } + LOG_I(NR_PHY, "-----------------------------------------\n"); +} diff --git a/openair3/NRPPA/nrppa_gNB_config.h b/openair3/NRPPA/nrppa_gNB_config.h new file mode 100644 index 0000000000..3ae710a62c --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB_config.h @@ -0,0 +1,30 @@ +/* + * 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 GNB_CONFIG_POSITIONING_H_ +#define GNB_CONFIG_POSITIONING_H_ + +#include "openair1/PHY/defs_nr_common.h" + +positioning_config_t RCconfig_nr_positioning(void); +void dump_positioning_config(const positioning_config_t *positioning_config); + +#endif /* GNB_CONFIG_POSITIONING_H_ */ diff --git a/openair3/NRPPA/nrppa_gNB_decoder.c b/openair3/NRPPA/nrppa_gNB_decoder.c new file mode 100644 index 0000000000..756871bc59 --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB_decoder.c @@ -0,0 +1,130 @@ +/* + * 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 "assertions.h" +#include "intertask_interface.h" +#include "nrppa_common.h" +#include "nrppa_gNB_decoder.h" + +static int nrppa_gNB_decode_initiating_message(NRPPA_NRPPA_PDU_t *pdu) +{ + asn_encode_to_new_buffer_result_t res = {NULL, {0, NULL, NULL}}; + DevAssert(pdu != NULL); + + switch (pdu->choice.initiatingMessage->procedureCode) { + case NRPPA_ProcedureCode_id_tRPInformationExchange: // TRPInformationRequest + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NRPPA_NRPPA_PDU, pdu); + LOG_I(NRPPA, "TRP Information Request initiating message\n"); + free(res.buffer); + break; + case NRPPA_ProcedureCode_id_positioningInformationExchange: // PositioningInformationRequest + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NRPPA_NRPPA_PDU, pdu); + LOG_I(NRPPA, "Positioning Information Request initiating message\n"); + free(res.buffer); + break; + case NRPPA_ProcedureCode_id_positioningActivation: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NRPPA_NRPPA_PDU, pdu); + LOG_I(NRPPA, "Positioning Activation initiating message\n"); + free(res.buffer); + break; + case NRPPA_ProcedureCode_id_Measurement: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NRPPA_NRPPA_PDU, pdu); + LOG_I(NRPPA, "Positioning Measurement initiating message\n"); + free(res.buffer); + break; + default: + AssertFatal(false, "Unknown procedure ID (%d) for initiating message\n", (int)pdu->choice.initiatingMessage->procedureCode); + return -1; + } + return 0; +} + +static int nrppa_gNB_decode_successful_outcome(NRPPA_NRPPA_PDU_t *pdu) +{ + asn_encode_to_new_buffer_result_t res = {NULL, {0, NULL, NULL}}; + DevAssert(pdu != NULL); + + switch (pdu->choice.successfulOutcome->procedureCode) { + case NRPPA_ProcedureCode_id_tRPInformationExchange: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NRPPA_NRPPA_PDU, pdu); + LOG_I(NRPPA, "TRP Information Response successfull outcome message\n"); + free(res.buffer); + break; + + default: + AssertFatal(false, + "Unknown procedure ID (%d) for successfull outcome message\n", + (int)pdu->choice.initiatingMessage->procedureCode); + return -1; + } + return 0; +} + +static int nrppa_gNB_decode_unsuccessful_outcome(NRPPA_NRPPA_PDU_t *pdu) +{ + asn_encode_to_new_buffer_result_t res = {NULL, {0, NULL, NULL}}; + DevAssert(pdu != NULL); + + switch (pdu->choice.unsuccessfulOutcome->procedureCode) { + case NRPPA_ProcedureCode_id_tRPInformationExchange: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_NRPPA_NRPPA_PDU, pdu); + LOG_I(NRPPA, "TRP Information Failure unsuccessfull outcome message\n"); + free(res.buffer); + break; + + default: + AssertFatal(false, + "Unknown procedure ID (%d) for unsuccessfull outcome message\n", + (int)pdu->choice.initiatingMessage->procedureCode); + return -1; + } + return 0; +} + +int nrppa_gNB_decode_pdu(NRPPA_NRPPA_PDU_t *pdu, const uint8_t *const buffer, const uint32_t length) +{ + asn_dec_rval_t dec_ret; + DevAssert(pdu != NULL); + DevAssert(buffer != NULL); + asn_codec_ctx_t st = {.max_stack_size = 100 * 1000}; // if we enable asn1c debug the stack size become large + dec_ret = aper_decode(&st, &asn_DEF_NRPPA_NRPPA_PDU, (void **)&pdu, buffer, length, 0, 0); + if (dec_ret.code != RC_OK) { + LOG_E(NRPPA, "Failed to decode pdu\n"); + return -1; + } + + switch (pdu->present) { + case NRPPA_NRPPA_PDU_PR_initiatingMessage: + return nrppa_gNB_decode_initiating_message(pdu); + + case NRPPA_NRPPA_PDU_PR_successfulOutcome: + return nrppa_gNB_decode_successful_outcome(pdu); + + case NRPPA_NRPPA_PDU_PR_unsuccessfulOutcome: + return nrppa_gNB_decode_unsuccessful_outcome(pdu); + + default: + LOG_I(NRPPA, "Unknown presence (%d) or not implemented\n", (int)pdu->present); + break; + } + + return -1; +} diff --git a/openair3/NRPPA/nrppa_gNB_decoder.h b/openair3/NRPPA/nrppa_gNB_decoder.h new file mode 100644 index 0000000000..668208b8a5 --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB_decoder.h @@ -0,0 +1,30 @@ +/* + * 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 "nrppa_common.h" + +#ifndef NRPPA_GNB_DECODER_H_ +#define NRPPA_GNB_DECODER_H_ + +int nrppa_gNB_decode_pdu(NRPPA_NRPPA_PDU_t *pdu, const uint8_t *const buffer, const uint32_t length) + __attribute__((warn_unused_result)); + +#endif /* NRPPA_GNB_DECODER_H_ */ diff --git a/openair3/NRPPA/nrppa_gNB_encoder.c b/openair3/NRPPA/nrppa_gNB_encoder.c new file mode 100644 index 0000000000..9ac0c4ecb0 --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB_encoder.c @@ -0,0 +1,135 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include +#include +#include +#include "nrppa_common.h" +#include "nrppa_gNB_encoder.h" + +static inline int nrppa_gNB_encode_initiating(NRPPA_NRPPA_PDU_t *pdu, uint8_t **buffer, uint32_t *len) +{ + DevAssert(pdu != NULL); + + const NRPPA_ProcedureCode_t tmp[] = {NRPPA_ProcedureCode_id_positioningInformationExchange, + NRPPA_ProcedureCode_id_positioningActivation, + NRPPA_ProcedureCode_id_positioningInformationUpdate, + NRPPA_ProcedureCode_id_positioningDeactivation, + NRPPA_ProcedureCode_id_tRPInformationExchange, + NRPPA_ProcedureCode_id_Measurement, + NRPPA_ProcedureCode_id_MeasurementReport, + NRPPA_ProcedureCode_id_MeasurementFailureIndication, + NRPPA_ProcedureCode_id_MeasurementAbort, + NRPPA_ProcedureCode_id_MeasurementUpdate}; + + int i; + for (i = 0; i < sizeofArray(tmp); i++) + if (pdu->choice.initiatingMessage->procedureCode == tmp[i]) + break; + if (i == sizeofArray(tmp)) { + LOG_E(NRPPA, "Unknown procedure ID (%d) for initiating message\n", (int)pdu->choice.initiatingMessage->procedureCode); + return -1; + } + + asn_encode_to_new_buffer_result_t res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NRPPA_NRPPA_PDU, pdu); + AssertFatal(res.result.encoded > 0, "failed to encode NRPPA msg\n"); + *buffer = res.buffer; + *len = res.result.encoded; + return 0; +} + +static inline int nrppa_gNB_encode_successfull_outcome(NRPPA_NRPPA_PDU_t *pdu, uint8_t **buffer, uint32_t *len) +{ + DevAssert(pdu != NULL); + const NRPPA_ProcedureCode_t tmp[] = {NRPPA_ProcedureCode_id_positioningInformationExchange, + NRPPA_ProcedureCode_id_positioningActivation, + NRPPA_ProcedureCode_id_tRPInformationExchange, + NRPPA_ProcedureCode_id_Measurement}; + int i; + for (i = 0; i < sizeofArray(tmp); i++) + if (pdu->choice.successfulOutcome->procedureCode == tmp[i]) + break; + if (i == sizeofArray(tmp)) { + LOG_E(NRPPA, "Unknown procedure ID (%ld) for successfull outcome message\n", pdu->choice.successfulOutcome->procedureCode); + return -1; + } + // xer_fprint(stdout, &asn_DEF_NRPPA_NRPPA_PDU, pdu); + asn_encode_to_new_buffer_result_t res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NRPPA_NRPPA_PDU, pdu); + AssertFatal(res.result.encoded > 0, "failed to encode NRPPA msg\n"); + *buffer = res.buffer; + *len = res.result.encoded; + return 0; +} + +static inline int nrppa_gNB_encode_unsuccessfull_outcome(NRPPA_NRPPA_PDU_t *pdu, uint8_t **buffer, uint32_t *len) +{ + DevAssert(pdu != NULL); + + const NRPPA_ProcedureCode_t tmp[] = {NRPPA_ProcedureCode_id_positioningInformationExchange, + NRPPA_ProcedureCode_id_positioningActivation, + NRPPA_ProcedureCode_id_tRPInformationExchange, + NRPPA_ProcedureCode_id_Measurement}; + + int i; + for (i = 0; i < sizeofArray(tmp); i++) + if (pdu->choice.unsuccessfulOutcome->procedureCode == tmp[i]) + break; + if (i == sizeofArray(tmp)) { + LOG_W(NRPPA, "Unknown procedure ID (%ld) for unsuccessfull outcome message\n", pdu->choice.unsuccessfulOutcome->procedureCode); + return -1; + } + + asn_encode_to_new_buffer_result_t res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NRPPA_NRPPA_PDU, pdu); + AssertFatal(res.result.encoded > 0, "failed to encode NRPPA msg\n"); + *buffer = res.buffer; + *len = res.result.encoded; + return 0; +} + +int nrppa_gNB_encode_pdu(NRPPA_NRPPA_PDU_t *pdu, uint8_t **buffer, uint32_t *len) +{ + int ret = -1; + DevAssert(pdu != NULL); + DevAssert(buffer != NULL); + DevAssert(len != NULL); + + // xer_fprint(stdout, &asn_DEF_NRPPA_NRPPA_PDU, (void *)pdu); + + switch (pdu->present) { + case NRPPA_NRPPA_PDU_PR_initiatingMessage: + ret = nrppa_gNB_encode_initiating(pdu, buffer, len); + break; + + case NRPPA_NRPPA_PDU_PR_successfulOutcome: + ret = nrppa_gNB_encode_successfull_outcome(pdu, buffer, len); + break; + + case NRPPA_NRPPA_PDU_PR_unsuccessfulOutcome: + ret = nrppa_gNB_encode_unsuccessfull_outcome(pdu, buffer, len); + break; + + default: + LOG_E(NRPPA, "Unknown message outcome (%d) or not implemented", (int)pdu->present); + return -1; + } + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, pdu); + return ret; +} diff --git a/openair3/NRPPA/nrppa_gNB_encoder.h b/openair3/NRPPA/nrppa_gNB_encoder.h new file mode 100644 index 0000000000..dee34a2060 --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB_encoder.h @@ -0,0 +1,27 @@ +/* + * 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 NRPPA_GNB_ENCODER_H_ +#define NRPPA_GNB_ENCODER_H_ + +int nrppa_gNB_encode_pdu(NRPPA_NRPPA_PDU_t *pdu, uint8_t **buffer, uint32_t *len) __attribute__((warn_unused_result)); + +#endif /* NRPPA_GNB_ENCODER_H_ */ diff --git a/openair3/NRPPA/nrppa_gNB_handlers.c b/openair3/NRPPA/nrppa_gNB_handlers.c new file mode 100644 index 0000000000..476729cd36 --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB_handlers.c @@ -0,0 +1,184 @@ +/* + * 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 "intertask_interface.h" +#include "nrppa_gNB_handlers.h" +#include "nrppa_gNB_decoder.h" +#include "nrppa_common.h" +#include "nrppa_gNB_location_information_transfer.h" +#include "nrppa_gNB_measurement_information_transfer.h" + +char *nrppa_direction2String(int nrppa_dir) +{ + static char *nrppa_direction_String[] = { + "", /* Nothing */ + "Originating message", /* originating message */ + "Successfull outcome", /* successfull outcome */ + "UnSuccessfull outcome", /* successfull outcome */ + }; + return (nrppa_direction_String[nrppa_dir]); +} + +/* Handlers matrix. Only gNB related procedure present here */ +nrppa_message_decoded_callback nrppa_messages_callback[][3] = { + {0, 0, 0}, // NRPPA_ProcedureCode_id_errorIndication ((NRPPA_ProcedureCode_t)0) + {0, 0, 0}, // NRPPA_ProcedureCode_id_privateMessage ((NRPPA_ProcedureCode_t)1) + {0, 0, 0}, // NRPPA_ProcedureCode_id_e_CIDMeasurementInitiation ((NRPPA_ProcedureCode_t)2) + {0, 0, 0}, // NRPPA_ProcedureCode_id_e_CIDMeasurementFailureIndication ((NRPPA_ProcedureCode_t)3) + {0, 0, 0}, // NRPPA_ProcedureCode_id_e_CIDMeasurementReport ((NRPPA_ProcedureCode_t)4) + {0, 0, 0}, // NRPPA_ProcedureCode_id_e_CIDMeasurementTermination ((NRPPA_ProcedureCode_t)5) + {0, 0, 0}, // NRPPA_ProcedureCode_id_oTDOAInformationExchange ((NRPPA_ProcedureCode_t)6) + {0, 0, 0}, // NRPPA_ProcedureCode_id_assistanceInformationControl ((NRPPA_ProcedureCode_t)7) + {0, 0, 0}, // NRPPA_ProcedureCode_id_assistanceInformationFeedback ((NRPPA_ProcedureCode_t)8) + {nrppa_gNB_handle_positioning_information_request, + 0, + 0}, // NRPPA_ProcedureCode_id_positioningInformationExchange ((NRPPA_ProcedureCode_t)9) + {0, 0, 0}, // NRPPA_ProcedureCode_id_positioningInformationUpdate ((NRPPA_ProcedureCode_t)10) + {nrppa_gNB_handle_measurement_request, 0, 0}, // NRPPA_ProcedureCode_id_Measurement ((NRPPA_ProcedureCode_t)11) + {0, 0, 0}, // NRPPA_ProcedureCode_id_MeasurementReport ((NRPPA_ProcedureCode_t)12) + {0, 0, 0}, // NRPPA_ProcedureCode_id_MeasurementUpdate ((NRPPA_ProcedureCode_t)13) + {0, 0, 0}, // NRPPA_ProcedureCode_id_MeasurementAbort ((NRPPA_ProcedureCode_t)14) + {0, 0, 0}, // NRPPA_ProcedureCode_id_MeasurementFailureIndication ((NRPPA_ProcedureCode_t)15) + {nrppa_gNB_handle_trp_information_request, 0, 0}, // NRPPA_ProcedureCode_id_tRPInformationExchange ((NRPPA_ProcedureCode_t)16) + {nrppa_gNB_handle_positioning_activation_request, + 0, + 0}, // NRPPA_ProcedureCode_id_positioningActivation ((NRPPA_ProcedureCode_t)17) + {0, 0, 0}, // NRPPA_ProcedureCode_id_positioningDeactivation ((NRPPA_ProcedureCode_t)18) +}; + +// Processing DOWNLINK UE ASSOCIATED NRPPA TRANSPORT (9.2.9.1 of TS 38.413 Version 16.0.0) +int nrppa_handle_downlink_ue_associated_nrppa_transport(instance_t instance, const ngap_downlink_ue_associated_nrppa_t *msg) +{ + LOG_I(NRPPA, "Handling DOWNLINKUEASSOCIATEDNRPPA TRANSPORT\n"); + uint8_t *const data = msg->nrppa_pdu.buf; + const uint32_t data_length = msg->nrppa_pdu.len; + NRPPA_NRPPA_PDU_t pdu; + int ret; + DevAssert(data != NULL); + memset(&pdu, 0, sizeof(pdu)); + + if (nrppa_gNB_decode_pdu(&pdu, data, data_length) < 0) { + LOG_E(NRPPA, "Failed to decode PDU\n"); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return -1; + } + /* Checking procedure Code and direction of message*/ + if (pdu.choice.initiatingMessage->procedureCode >= sizeof(nrppa_messages_callback) / (3 * sizeof(nrppa_message_decoded_callback)) + || (pdu.present > NRPPA_NRPPA_PDU_PR_unsuccessfulOutcome)) { + LOG_E(NRPPA, + "Either procedureCode %ld or direction %d exceed expected\n", + pdu.choice.initiatingMessage->procedureCode, + pdu.present); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return -1; + } + + /* No handler present. + * This can mean not implemented or no procedure for gNB (wrong direction).*/ + if (nrppa_messages_callback[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1] == NULL) { + LOG_E(NRPPA, + "No handler for procedureCode %ld in %s\n", + pdu.choice.initiatingMessage->procedureCode, + nrppa_direction2String(pdu.present - 1)); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return -1; + } + + /* Calling the right handler*/ + nrppa_gnb_ue_info_t nrppa_msg_info; + nrppa_msg_info.instance = instance; + nrppa_msg_info.gNB_ue_ngap_id = msg->gNB_ue_ngap_id; + nrppa_msg_info.amf_ue_ngap_id = msg->amf_ue_ngap_id; + nrppa_msg_info.routing_id.buf = msg->routing_id.buf; + nrppa_msg_info.routing_id.len = msg->routing_id.len; + ret = (*nrppa_messages_callback[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1])(&nrppa_msg_info, &pdu); + + if (msg->routing_id.buf) { + free(msg->routing_id.buf); + } + + if (msg->nrppa_pdu.buf) { + free(msg->nrppa_pdu.buf); + } + + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return ret; +} + +// Processing DOWNLINK NON UE ASSOCIATED NRPPA TRANSPORT (9.2.9.3 of TS 38.413 Version 16.0.0) +int nrppa_handle_downlink_non_ue_associated_nrppa_transport(instance_t instance, const ngap_downlink_non_ue_associated_nrppa_t *msg) +{ + LOG_I(NRPPA, "Handling DOWNLINKNONUEASSOCIATEDNRPPA TRANSPORT\n"); + uint8_t *const data = msg->nrppa_pdu.buf; + const uint32_t data_length = msg->nrppa_pdu.len; + NRPPA_NRPPA_PDU_t pdu; + int ret; + DevAssert(data != NULL); + memset(&pdu, 0, sizeof(pdu)); + + if (nrppa_gNB_decode_pdu(&pdu, data, data_length) < 0) { + LOG_E(NRPPA, "Failed to decode Downlink Non UE Associated NRPPa PDU\n"); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return -1; + } + + /* Checking procedure Code and direction of message*/ + if (pdu.choice.initiatingMessage->procedureCode >= sizeof(nrppa_messages_callback) / (3 * sizeof(nrppa_message_decoded_callback)) + || (pdu.present > NRPPA_NRPPA_PDU_PR_unsuccessfulOutcome)) { + LOG_E(NRPPA, + "Either procedureCode %ld or direction %d exceed expected\n", + pdu.choice.initiatingMessage->procedureCode, + pdu.present); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return -1; + } + + /* No handler present. + * This can mean not implemented or no procedure for gNB (wrong direction).*/ + if (nrppa_messages_callback[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1] == NULL) { + LOG_E(NRPPA, + "No handler for procedureCode %ld in %s\n", + pdu.choice.initiatingMessage->procedureCode, + nrppa_direction2String(pdu.present - 1)); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return -1; + } + + /* Calling the right handler*/ + nrppa_gnb_ue_info_t nrppa_msg_info; + nrppa_msg_info.instance = instance; + nrppa_msg_info.gNB_ue_ngap_id = 0; // non-ue associated + nrppa_msg_info.amf_ue_ngap_id = 0; // non-ue associated + nrppa_msg_info.routing_id.buf = msg->routing_id.buf; + nrppa_msg_info.routing_id.len = msg->routing_id.len; + ret = (*nrppa_messages_callback[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1])(&nrppa_msg_info, &pdu); + + if (msg->routing_id.buf) { + free(msg->routing_id.buf); + } + + if (msg->nrppa_pdu.buf) { + free(msg->nrppa_pdu.buf); + } + + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return ret; +} diff --git a/openair3/NRPPA/nrppa_gNB_handlers.h b/openair3/NRPPA/nrppa_gNB_handlers.h new file mode 100644 index 0000000000..ecee41caa1 --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB_handlers.h @@ -0,0 +1,28 @@ +/* + * 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 NRPPA_GNB_HANDLERS_H_ +#define NRPPA_GNB_HANDLERS_H_ + +int nrppa_handle_downlink_ue_associated_nrppa_transport(instance_t instance, const ngap_downlink_ue_associated_nrppa_t *msg); +int nrppa_handle_downlink_non_ue_associated_nrppa_transport(instance_t instance, + const ngap_downlink_non_ue_associated_nrppa_t *msg); +#endif /* NRPPA_GNB_HANDLERS_H_ */ diff --git a/openair3/NRPPA/nrppa_gNB_location_information_transfer.c b/openair3/NRPPA/nrppa_gNB_location_information_transfer.c new file mode 100644 index 0000000000..bb3bc9f8bd --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB_location_information_transfer.c @@ -0,0 +1,1379 @@ +/* + * 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 "intertask_interface.h" +#include "nrppa_common.h" +#include "nrppa_gNB_location_information_transfer.h" +#include "nrppa_gNB_ue_context.h" +#include "nrppa_messages_types.h" +#include "nrppa_gNB_encoder.h" +#include "openair3/UTILS/conversions.h" + +void free_trp_information_request(nrppa_trp_information_req_t *msg) +{ + if (msg->trp_information_type_list.trp_information_type_item) { + free(msg->trp_information_type_list.trp_information_type_item); + } +} + +static NRPPA_TRPPositionDirect_t encode_trp_position_direct(nrppa_trp_position_direct_t *in) +{ + NRPPA_TRPPositionDirect_t out = {0}; + + switch (in->accuracy.present) { + case NRPPA_TRP_POSITION_DIRECT_ACCURACY_PR_NOTHING: + out.accuracy.present = NRPPA_TRPPositionDirectAccuracy_PR_NOTHING; + break; + case NRPPA_TRP_POSITION_DIRECT_ACCURACY_PR_TRPPOSITION: + out.accuracy.present = NRPPA_TRPPositionDirectAccuracy_PR_tRPPosition; + asn1cCalloc(out.accuracy.choice.tRPPosition, out_pos); + nrppa_access_point_position_t *in_pos = &in->accuracy.choice.trp_position; + + out_pos->latitudeSign = in_pos->latitude_sign; + out_pos->latitude = in_pos->latitude; + out_pos->longitude = in_pos->longitude; + out_pos->directionOfAltitude = in_pos->direction_of_altitude; + out_pos->altitude = in_pos->altitude; + out_pos->uncertaintySemi_major = in_pos->uncertainty_semi_major; + out_pos->uncertaintySemi_minor = in_pos->uncertainty_semi_minor; + out_pos->orientationOfMajorAxis = in_pos->orientation_of_major_axis; + out_pos->uncertaintyAltitude = in_pos->uncertainty_altitude; + out_pos->confidence = in_pos->confidence; + break; + case NRPPA_TRP_POSITION_DIRECT_ACCURACY_PR_TRPHAPOSITION: + out.accuracy.present = NRPPA_TRPPositionDirectAccuracy_PR_tRPHAposition; + asn1cCalloc(out.accuracy.choice.tRPHAposition, out_ha_pos); + nrppa_ngran_high_accuracy_access_point_position_t *in_ha_pos = &in->accuracy.choice.trp_HAposition; + out_ha_pos->latitude = in_ha_pos->latitude; + out_ha_pos->longitude = in_ha_pos->longitude; + out_ha_pos->altitude = in_ha_pos->altitude; + out_ha_pos->uncertaintySemi_major = in_ha_pos->uncertainty_semi_major; + out_ha_pos->uncertaintySemi_minor = in_ha_pos->uncertainty_semi_minor; + out_ha_pos->orientationOfMajorAxis = in_ha_pos->orientation_of_major_axis; + out_ha_pos->horizontalConfidence = in_ha_pos->horizontal_confidence; + out_ha_pos->uncertaintyAltitude = in_ha_pos->uncertainty_altitude; + out_ha_pos->verticalConfidence = in_ha_pos->vertical_confidence; + break; + default: + AssertFatal(false, "illegal direct accuracy entry\n"); + break; + } + return out; +} + +static NRPPA_TRPPositionReferenced_t encode_trp_position_referenced(nrppa_trp_position_referenced_t *in) +{ + NRPPA_TRPPositionReferenced_t out = {0}; + NRPPA_ReferencePoint_t *out_ref_point = &out.referencePoint; + nrppa_reference_point_t *in_ref_point = &in->reference_point; + switch (in_ref_point->present) { + case NRPPA_REFERENCE_POINT_PR_NOTHING: + out_ref_point->present = NRPPA_ReferencePoint_PR_NOTHING; + break; + case NRPPA_REFERENCE_POINT_PR_COORDINATEID: + out_ref_point->present = NRPPA_ReferencePoint_PR_relativeCoordinateID; + out_ref_point->choice.relativeCoordinateID = in_ref_point->choice.coordinate_id; + break; + case NRPPA_REFERENCE_POINT_PR_REFERENCEPOINTCOORDINATE: + out_ref_point->present = NRPPA_ReferencePoint_PR_referencePointCoordinate; + asn1cCalloc(out_ref_point->choice.referencePointCoordinate, out_ref_coord); + nrppa_access_point_position_t *in_ref_coord = &in_ref_point->choice.reference_point_coordinate; + out_ref_coord->latitudeSign = in_ref_coord->latitude_sign; + out_ref_coord->latitude = in_ref_coord->latitude; + out_ref_coord->longitude = in_ref_coord->longitude; + out_ref_coord->directionOfAltitude = in_ref_coord->direction_of_altitude; + out_ref_coord->altitude = in_ref_coord->altitude; + out_ref_coord->uncertaintySemi_major = in_ref_coord->uncertainty_semi_major; + out_ref_coord->uncertaintySemi_minor = in_ref_coord->uncertainty_semi_minor; + out_ref_coord->orientationOfMajorAxis = in_ref_coord->orientation_of_major_axis; + out_ref_coord->uncertaintyAltitude = in_ref_coord->uncertainty_altitude; + out_ref_coord->confidence = in_ref_coord->confidence; + break; + case NRPPA_REFERENCE_POINT_PR_REFERENCEPOINTCOORDINATEHA: + out_ref_point->present = NRPPA_ReferencePoint_PR_referencePointCoordinateHA; + asn1cCalloc(out_ref_point->choice.referencePointCoordinateHA, out_ref_coord_ha); + nrppa_ngran_high_accuracy_access_point_position_t *in_ref_coord_ha = &in_ref_point->choice.reference_point_coordinateHA; + out_ref_coord_ha->latitude = in_ref_coord_ha->latitude; + out_ref_coord_ha->longitude = in_ref_coord_ha->longitude; + out_ref_coord_ha->altitude = in_ref_coord_ha->altitude; + out_ref_coord_ha->uncertaintySemi_major = in_ref_coord_ha->uncertainty_semi_major; + out_ref_coord_ha->uncertaintySemi_minor = in_ref_coord_ha->uncertainty_semi_minor; + out_ref_coord_ha->orientationOfMajorAxis = in_ref_coord_ha->orientation_of_major_axis; + out_ref_coord_ha->horizontalConfidence = in_ref_coord_ha->horizontal_confidence; + out_ref_coord_ha->uncertaintyAltitude = in_ref_coord_ha->uncertainty_altitude; + out_ref_coord_ha->verticalConfidence = in_ref_coord_ha->vertical_confidence; + break; + default: + AssertFatal(false, "illegal reference point entry\n"); + break; + } + + NRPPA_TRPReferencePointType_t *out_ref_point_type = &out.referencePointType; + nrppa_trp_reference_point_type_t *in_ref_point_type = &in->reference_point_type; + switch (in_ref_point_type->present) { + case NRPPA_TRP_REFERENCE_POINT_TYPE_PR_NOTHING: + out_ref_point_type->present = NRPPA_TRPReferencePointType_PR_NOTHING; + break; + case NRPPA_TRP_REFERENCE_POINT_TYPE_PR_TRPPOSITION_RELATIVE_GEODETIC: + out_ref_point_type->present = NRPPA_TRPReferencePointType_PR_tRPPositionRelativeGeodetic; + asn1cCalloc(out_ref_point_type->choice.tRPPositionRelativeGeodetic, out_geodetic); + nrppa_relative_geodetic_location_t *in_geodetic = &in_ref_point_type->choice.trp_position_relative_geodetic; + out_geodetic->milli_Arc_SecondUnits = in_geodetic->milli_arc_second_units; + out_geodetic->heightUnits = in_geodetic->height_units; + out_geodetic->deltaLatitude = in_geodetic->delta_latitude; + out_geodetic->deltaLongitude = in_geodetic->delta_longitude; + out_geodetic->deltaHeight = in_geodetic->delta_height; + NRPPA_LocationUncertainty_t *out_loc_uncertainty_g = &out_geodetic->locationUncertainty; + nrppa_location_uncertainty_t *in_loc_uncertainty_g = &in_geodetic->location_uncertainty; + out_loc_uncertainty_g->horizontalUncertainty = in_loc_uncertainty_g->horizontal_uncertainty; + out_loc_uncertainty_g->horizontalConfidence = in_loc_uncertainty_g->horizontal_confidence; + out_loc_uncertainty_g->verticalUncertainty = in_loc_uncertainty_g->vertical_uncertainty; + out_loc_uncertainty_g->verticalConfidence = in_loc_uncertainty_g->vertical_confidence; + break; + case NRPPA_TRP_REFERENCE_POINT_TYPE_PR_TRPPOSITION_RELATIVE_CARTESIAN: + out_ref_point_type->present = NRPPA_TRPReferencePointType_PR_tRPPositionRelativeCartesian; + asn1cCalloc(out_ref_point_type->choice.tRPPositionRelativeCartesian, out_cartesian); + nrppa_relative_cartesian_location_t *in_cartesian = &in_ref_point_type->choice.trp_position_relative_cartesian; + + out_cartesian->xYZunit = in_cartesian->xyz_unit; + out_cartesian->xvalue = in_cartesian->xvalue; + out_cartesian->yvalue = in_cartesian->yvalue; + out_cartesian->zvalue = in_cartesian->zvalue; + NRPPA_LocationUncertainty_t *out_loc_uncertainty_c = &out_cartesian->locationUncertainty; + nrppa_location_uncertainty_t *in_loc_uncertainty_c = &in_cartesian->location_uncertainty; + out_loc_uncertainty_c->horizontalUncertainty = in_loc_uncertainty_c->horizontal_uncertainty; + out_loc_uncertainty_c->horizontalConfidence = in_loc_uncertainty_c->horizontal_confidence; + out_loc_uncertainty_c->verticalUncertainty = in_loc_uncertainty_c->vertical_uncertainty; + out_loc_uncertainty_c->verticalConfidence = in_loc_uncertainty_c->vertical_confidence; + break; + default: + AssertFatal(false, "illegal trp reference point type entry\n"); + break; + } + return out; +} + +static NRPPA_GeographicalCoordinates_t encode_geographical_coordinates_nrppa(nrppa_geographical_coordinates_t *in) +{ + NRPPA_GeographicalCoordinates_t out = {0}; + NRPPA_TRPPositionDefinitionType_t *out_type = &out.tRPPositionDefinitionType; + nrppa_trp_position_definition_type_t *in_type = &in->trp_position_definition_type; + switch (in_type->present) { + case NRPPA_TRP_POSITION_DEFINITION_TYPE_PR_NOTHING: + out_type->present = NRPPA_TRPPositionDefinitionType_PR_NOTHING; + break; + case NRPPA_TRP_POSITION_DEFINITION_TYPE_PR_DIRECT: + out_type->present = NRPPA_TRPPositionDefinitionType_PR_direct; + asn1cCalloc(out_type->choice.direct, direct); + *direct = encode_trp_position_direct(&in_type->choice.direct); + break; + case NRPPA_TRP_POSITION_DEFINITION_TYPE_PR_REFERENCED: + out_type->present = NRPPA_TRPPositionDefinitionType_PR_referenced; + asn1cCalloc(out_type->choice.referenced, referenced); + *referenced = encode_trp_position_referenced(&in_type->choice.referenced); + break; + default: + AssertFatal(false, "illegal Geographical Coordinates entry\n"); + break; + } + return out; +} + +NRPPA_TRPInformationItem_t encode_trp_info_type_response_item_nrppa(nrppa_trp_information_type_response_item_t *in) +{ + NRPPA_TRPInformationItem_t out = {0}; + switch (in->present) { + case NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NOTHING: + out.present = NRPPA_TRPInformationItem_PR_NOTHING; + break; + case NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_PCI_NR: + out.present = NRPPA_TRPInformationItem_PR_pCI_NR; + out.choice.pCI_NR = in->choice.pci_nr; + break; + case NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NG_RAN_CGI: + out.present = NRPPA_TRPInformationItem_PR_nG_RAN_CGI; + asn1cCalloc(out.choice.nG_RAN_CGI, nG_RAN_CGI); + MCC_MNC_TO_PLMNID(in->choice.ng_ran_cgi.plmn.mcc, + in->choice.ng_ran_cgi.plmn.mnc, + in->choice.ng_ran_cgi.plmn.mnc_digit_length, + &(nG_RAN_CGI->pLMN_Identity)); + nG_RAN_CGI->nG_RANcell.present = NRPPA_NG_RANCell_PR_nR_CellID; + NR_CELL_ID_TO_BIT_STRING(in->choice.ng_ran_cgi.nr_cellid, &(nG_RAN_CGI->nG_RANcell.choice.nR_CellID)); + break; + case NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NRARFCN: + out.present = NRPPA_TRPInformationItem_PR_aRFCN; + out.choice.aRFCN = in->choice.nr_arfcn; + break; + case NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_PRSCONFIGURATION: + out.present = NRPPA_TRPInformationItem_PR_pRSConfiguration; + AssertFatal(false, "TRP information type response item PRS configuration unsupported\n"); + break; + case NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SSBINFORMATION: + out.present = NRPPA_TRPInformationItem_PR_sSBinformation; + AssertFatal(false, "TRP information type response item SSB Information unsupported\n"); + break; + case NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SFNINITIALISATIONTIME: + out.present = NRPPA_TRPInformationItem_PR_sFNInitialisationTime; + AssertFatal(false, "TRP information type response item SFN Initialization Time unsupported\n"); + break; + case NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_SPATIALDIRECTIONINFORMATION: + out.present = NRPPA_TRPInformationItem_PR_spatialDirectionInformation; + AssertFatal(false, "TRP information type response item Spatial Direction Information unsupported\n"); + break; + case NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_GEOGRAPHICALCOORDINATES: + out.present = NRPPA_TRPInformationItem_PR_geographicalCoordinates; + asn1cCalloc(out.choice.geographicalCoordinates, nrppa_geo_coord); + nrppa_geographical_coordinates_t *geo_coord = &in->choice.geographical_coordinates; + *nrppa_geo_coord = encode_geographical_coordinates_nrppa(geo_coord); + break; + default: + AssertFatal(false, "received illegal trp information type response item %d\n", in->present); + break; + } + return out; +} + +void free_trp_information_response(nrppa_trp_information_resp_t *msg) +{ + nrppa_trp_information_list_t *trp_information_list = &msg->trp_information_list; + uint32_t trp_info_item_length = trp_information_list->trp_information_item_length; + for (int i = 0; i < trp_info_item_length; i++) { + nrppa_trp_information_t *trp_information_item = &trp_information_list->trp_information_item[i]; + nrppa_trp_information_type_response_list_t *trp_info_type_resp_list = &trp_information_item->trp_information_type_response_list; + free(trp_info_type_resp_list->trp_information_type_response_item); + } + free(msg->trp_information_list.trp_information_item); +} + +static NRPPA_SRSConfig_t encode_srs_config(const nrppa_srs_config_t *in_config) +{ + NRPPA_SRSConfig_t out_config = {0}; + // optional: srs_resource_list + if (in_config->srs_resource_list) { + nrppa_srs_resource_list_t *srs_resource_list = in_config->srs_resource_list; + uint32_t srs_resource_list_length = srs_resource_list->srs_resource_list_length; + asn1cCalloc(out_config.sRSResource_List, nrppa_sRSResource_List); + for (int i = 0; i < srs_resource_list_length; i++) { + asn1cSequenceAdd(nrppa_sRSResource_List->list, NRPPA_SRSResource_t, nrppa_srs_resource); + nrppa_srs_resource_t *srs_resource = &srs_resource_list->srs_resource[i]; + nrppa_srs_resource->sRSResourceID = srs_resource->srs_resource_id; + + switch (srs_resource->nr_of_srs_ports) { + case NRPPA_SRS_NUMBER_OF_PORTS_N1: + nrppa_srs_resource->nrofSRS_Ports = NRPPA_SRSResource__nrofSRS_Ports_port1; + break; + case NRPPA_SRS_NUMBER_OF_PORTS_N2: + nrppa_srs_resource->nrofSRS_Ports = NRPPA_SRSResource__nrofSRS_Ports_ports2; + break; + case NRPPA_SRS_NUMBER_OF_PORTS_N4: + nrppa_srs_resource->nrofSRS_Ports = NRPPA_SRSResource__nrofSRS_Ports_ports4; + break; + default: + AssertFatal(false, "illegal number of srs ports %d\n", srs_resource->nr_of_srs_ports); + break; + } + + nrppa_transmission_comb_t *srs_res_tx_comb = &srs_resource->transmission_comb; + switch (srs_res_tx_comb->present) { + case NRPPA_TRANSMISSION_COMB_PR_NOTHING: + nrppa_srs_resource->transmissionComb.present = NRPPA_TransmissionComb_PR_NOTHING; + break; + case NRPPA_TRANSMISSION_COMB_PR_N2: + nrppa_srs_resource->transmissionComb.present = NRPPA_TransmissionComb_PR_n2; + asn1cCalloc(nrppa_srs_resource->transmissionComb.choice.n2, nrppa_n2); + nrppa_n2->combOffset_n2 = srs_res_tx_comb->choice.n2.comb_offset_n2; + nrppa_n2->cyclicShift_n2 = srs_res_tx_comb->choice.n2.cyclic_shift_n2; + break; + case NRPPA_TRANSMISSION_COMB_PR_N4: + nrppa_srs_resource->transmissionComb.present = NRPPA_TransmissionComb_PR_n4; + asn1cCalloc(nrppa_srs_resource->transmissionComb.choice.n4, nrppa_n4); + nrppa_n4->combOffset_n4 = srs_res_tx_comb->choice.n4.comb_offset_n4; + nrppa_n4->cyclicShift_n4 = srs_res_tx_comb->choice.n4.cyclic_shift_n4; + break; + default: + AssertFatal(false, "illegal transmissionComb %d\n", srs_res_tx_comb->present); + break; + } + + nrppa_srs_resource->startPosition = srs_resource->start_position; + + switch (srs_resource->nr_of_symbols) { + case NRPPA_SRS_NUMBER_OF_SYMBOLS_N1: + nrppa_srs_resource->nrofSymbols = NRPPA_SRSResource__nrofSymbols_n1; + break; + case NRPPA_SRS_NUMBER_OF_SYMBOLS_N2: + nrppa_srs_resource->nrofSymbols = NRPPA_SRSResource__nrofSymbols_n2; + break; + case NRPPA_SRS_NUMBER_OF_SYMBOLS_N4: + nrppa_srs_resource->nrofSymbols = NRPPA_SRSResource__nrofSymbols_n4; + break; + default: + AssertFatal(false, "illegal number of symbols %d\n", srs_resource->nr_of_symbols); + break; + } + + switch (srs_resource->repetition_factor) { + case NRPPA_SRS_REPETITION_FACTOR_RF1: + nrppa_srs_resource->repetitionFactor = NRPPA_SRSResource__repetitionFactor_n1; + break; + case NRPPA_SRS_REPETITION_FACTOR_RF2: + nrppa_srs_resource->repetitionFactor = NRPPA_SRSResource__repetitionFactor_n2; + break; + case NRPPA_SRS_REPETITION_FACTOR_RF4: + nrppa_srs_resource->repetitionFactor = NRPPA_SRSResource__repetitionFactor_n4; + break; + default: + AssertFatal(false, "illegal repetition factor %d\n", srs_resource->repetition_factor); + break; + } + + nrppa_srs_resource->freqDomainPosition = srs_resource->freq_domain_position; + nrppa_srs_resource->freqDomainShift = srs_resource->freq_domain_shift; + nrppa_srs_resource->c_SRS = srs_resource->c_srs; + nrppa_srs_resource->b_SRS = srs_resource->b_srs; + nrppa_srs_resource->b_hop = srs_resource->b_hop; + + switch (srs_resource->group_or_sequence_hopping) { + case NRPPA_GROUPORSEQUENCEHOPPING_NOTHING: + nrppa_srs_resource->groupOrSequenceHopping = NRPPA_SRSResource__groupOrSequenceHopping_neither; + break; + case NRPPA_GROUPORSEQUENCEHOPPING_GROUPHOPPING: + nrppa_srs_resource->groupOrSequenceHopping = NRPPA_SRSResource__groupOrSequenceHopping_groupHopping; + break; + case NRPPA_GROUPORSEQUENCEHOPPING_SEQUENCEHOPPING: + nrppa_srs_resource->groupOrSequenceHopping = NRPPA_SRSResource__groupOrSequenceHopping_sequenceHopping; + break; + default: + AssertFatal(false, "illegal groupOrSequenceHopping %d\n", srs_resource->group_or_sequence_hopping); + break; + } + + NRPPA_ResourceType_t *nrppa_resourceType = &nrppa_srs_resource->resourceType; + nrppa_resource_type_t *resource_type = &srs_resource->resource_type; + if (resource_type->present == NRPPA_RESOURCE_TYPE_PR_NOTHING) { + nrppa_resourceType->present = NRPPA_ResourceType_PR_NOTHING; + } else if (resource_type->present == NRPPA_RESOURCE_TYPE_PR_PERIODIC) { + nrppa_resourceType->present = NRPPA_ResourceType_PR_periodic; + asn1cCalloc(nrppa_resourceType->choice.periodic, nrppa_periodic); + switch (resource_type->choice.periodic.periodicity) { + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT1: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot1; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT2: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot2; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT4: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot4; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT5: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot5; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT8: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot8; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT10: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot10; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT16: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot16; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT20: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot20; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT32: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot32; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT40: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot40; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT64: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot64; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT80: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot80; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT160: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot160; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT320: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot320; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT640: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot640; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT1280: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot1280; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT2560: + nrppa_periodic->periodicity = NRPPA_ResourceTypePeriodic__periodicity_slot2560; + break; + default: + AssertFatal(false, "illegal periodicity %d\n", resource_type->choice.periodic.periodicity); + break; + } + nrppa_periodic->offset = resource_type->choice.periodic.offset; + } else if (resource_type->present == NRPPA_RESOURCE_TYPE_PR_SEMI_PERSISTENT) { + nrppa_resourceType->present = NRPPA_ResourceType_PR_semi_persistent; + asn1cCalloc(nrppa_resourceType->choice.semi_persistent, nrppa_semi_persistent); + switch (resource_type->choice.semi_persistent.periodicity) { + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT1: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot1; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT2: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot2; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT4: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot4; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT5: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot5; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT8: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot8; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT10: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot10; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT16: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot16; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT20: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot20; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT32: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot32; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT40: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot40; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT64: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot64; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT80: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot80; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT160: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot160; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT320: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot320; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT640: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot640; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT1280: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot1280; + break; + case NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT2560: + nrppa_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistent__periodicity_slot2560; + break; + default: + AssertFatal(false, "illegal periodicity %d\n", resource_type->choice.semi_persistent.periodicity); + break; + } + nrppa_semi_persistent->offset = resource_type->choice.semi_persistent.offset; + } else if (resource_type->present == NRPPA_RESOURCE_TYPE_PR_APERIODIC) { + nrppa_resourceType->present = NRPPA_ResourceType_PR_aperiodic; + asn1cCalloc(nrppa_resourceType->choice.aperiodic, nrppa_aperiodic); + nrppa_aperiodic->aperiodicResourceType = resource_type->choice.aperiodic; + } else { + AssertFatal(false, "illegal resourceType %d\n", resource_type->present); + } + + nrppa_srs_resource->sequenceId = srs_resource->sequence_id; + } + } + + // optional: pos_srs_resource_list + if (in_config->pos_srs_resource_list) { + nrppa_pos_srs_resource_list_t *pos_srs_resource_list = in_config->pos_srs_resource_list; + uint32_t pos_srs_resource_list_length = pos_srs_resource_list->pos_srs_resource_list_length; + asn1cCalloc(out_config.posSRSResource_List, nrppa_posSRSResource_List); + for (int i = 0; i < pos_srs_resource_list_length; i++) { + asn1cSequenceAdd(nrppa_posSRSResource_List->list, NRPPA_PosSRSResource_Item_t, nrppa_pos_srs_resource); + nrppa_pos_srs_resource_item_t *pos_srs_resource = &pos_srs_resource_list->pos_srs_resource_item[i]; + nrppa_pos_srs_resource->srs_PosResourceId = pos_srs_resource->srs_pos_resource_id; + + nrppa_transmission_comb_pos_t *pos_srs_res_tx_comb = &pos_srs_resource->transmission_comb_pos; + switch (pos_srs_res_tx_comb->present) { + case NRPPA_TRANSMISSION_COMB_POS_PR_NOTHING: + nrppa_pos_srs_resource->transmissionCombPos.present = NRPPA_TransmissionCombPos_PR_NOTHING; + break; + case NRPPA_TRANSMISSION_COMB_POS_PR_N2: + nrppa_pos_srs_resource->transmissionCombPos.present = NRPPA_TransmissionCombPos_PR_n2; + asn1cCalloc(nrppa_pos_srs_resource->transmissionCombPos.choice.n2, nrppa_pos_srs_resource_n2); + nrppa_transmission_comb_pos_n2_t *pos_srs_resource_n2 = &pos_srs_res_tx_comb->choice.n2; + nrppa_pos_srs_resource_n2->combOffset_n2 = pos_srs_resource_n2->comb_offset_n2; + nrppa_pos_srs_resource_n2->cyclicShift_n2 = pos_srs_resource_n2->cyclic_shift_n2; + break; + case NRPPA_TRANSMISSION_COMB_POS_PR_N4: + nrppa_pos_srs_resource->transmissionCombPos.present = NRPPA_TransmissionCombPos_PR_n4; + asn1cCalloc(nrppa_pos_srs_resource->transmissionCombPos.choice.n4, nrppa_pos_srs_resource_n4); + nrppa_transmission_comb_pos_n4_t *pos_srs_resource_n4 = &pos_srs_res_tx_comb->choice.n4; + nrppa_pos_srs_resource_n4->combOffset_n4 = pos_srs_resource_n4->comb_offset_n4; + nrppa_pos_srs_resource_n4->cyclicShift_n4 = pos_srs_resource_n4->cyclic_shift_n4; + break; + case NRPPA_TRANSMISSION_COMB_POS_PR_N8: + nrppa_pos_srs_resource->transmissionCombPos.present = NRPPA_TransmissionCombPos_PR_n8; + asn1cCalloc(nrppa_pos_srs_resource->transmissionCombPos.choice.n8, nrppa_pos_srs_resource_n8); + nrppa_transmission_comb_pos_n8_t *pos_srs_resource_n8 = &pos_srs_res_tx_comb->choice.n8; + nrppa_pos_srs_resource_n8->combOffset_n8 = pos_srs_resource_n8->comb_offset_n8; + nrppa_pos_srs_resource_n8->cyclicShift_n8 = pos_srs_resource_n8->cyclic_shift_n8; + break; + default: + AssertFatal(false, "illegal transmissionComb %d\n", pos_srs_res_tx_comb->present); + break; + } + + nrppa_pos_srs_resource->startPosition = pos_srs_resource->start_position; + + switch (pos_srs_resource->nr_of_symbols) { + case NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N1: + nrppa_pos_srs_resource->nrofSymbols = NRPPA_PosSRSResource_Item__nrofSymbols_n1; + break; + case NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N2: + nrppa_pos_srs_resource->nrofSymbols = NRPPA_PosSRSResource_Item__nrofSymbols_n2; + break; + case NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N4: + nrppa_pos_srs_resource->nrofSymbols = NRPPA_PosSRSResource_Item__nrofSymbols_n4; + break; + case NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N8: + nrppa_pos_srs_resource->nrofSymbols = NRPPA_PosSRSResource_Item__nrofSymbols_n8; + break; + case NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N12: + nrppa_pos_srs_resource->nrofSymbols = NRPPA_PosSRSResource_Item__nrofSymbols_n12; + break; + default: + AssertFatal(false, "illegal number of symbols %d\n", pos_srs_resource->nr_of_symbols); + break; + } + + nrppa_pos_srs_resource->freqDomainShift = pos_srs_resource->freq_domain_shift; + nrppa_pos_srs_resource->c_SRS = pos_srs_resource->c_srs; + + switch (pos_srs_resource->group_or_sequence_hopping) { + case NRPPA_GROUPORSEQUENCEHOPPING_NOTHING: + nrppa_pos_srs_resource->groupOrSequenceHopping = NRPPA_PosSRSResource_Item__groupOrSequenceHopping_neither; + break; + case NRPPA_GROUPORSEQUENCEHOPPING_GROUPHOPPING: + nrppa_pos_srs_resource->groupOrSequenceHopping = NRPPA_PosSRSResource_Item__groupOrSequenceHopping_groupHopping; + break; + case NRPPA_GROUPORSEQUENCEHOPPING_SEQUENCEHOPPING: + nrppa_pos_srs_resource->groupOrSequenceHopping = NRPPA_PosSRSResource_Item__groupOrSequenceHopping_sequenceHopping; + break; + default: + AssertFatal(false, "illegal groupOrSequenceHopping %d\n", pos_srs_resource->group_or_sequence_hopping); + break; + } + + nrppa_resource_type_pos_t *resource_type_pos = &pos_srs_resource->resource_type_pos; + NRPPA_ResourceTypePos_t *nrppa_resourceTypePos = &nrppa_pos_srs_resource->resourceTypePos; + if (resource_type_pos->present == NRPPA_RESOURCE_TYPE_POS_PR_NOTHING) { + nrppa_resourceTypePos->present = NRPPA_ResourceTypePos_PR_NOTHING; + } else if (resource_type_pos->present == NRPPA_RESOURCE_TYPE_POS_PR_PERIODIC) { + nrppa_resourceTypePos->present = NRPPA_ResourceTypePos_PR_periodic; + asn1cCalloc(nrppa_resourceTypePos->choice.periodic, nrppa_pos_periodic); + switch (resource_type_pos->choice.periodic.periodicity) { + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT1: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot1; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT2: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot2; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT4: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot4; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT5: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot5; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT8: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot8; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT10: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot10; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT16: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot16; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT20: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot20; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT32: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot32; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT40: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot40; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT64: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot64; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT80: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot80; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT160: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot160; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT320: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot320; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT640: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot640; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT1280: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot1280; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT2560: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot2560; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT5120: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot5120; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT10240: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot10240; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT20480: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot20480; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT40960: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot40960; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT81920: + nrppa_pos_periodic->periodicity = NRPPA_ResourceTypePeriodicPos__periodicity_slot81920; + break; + default: + AssertFatal(false, "illegal periodicity %d\n", resource_type_pos->choice.periodic.periodicity); + break; + } + + nrppa_pos_periodic->offset = resource_type_pos->choice.periodic.offset; + } else if (resource_type_pos->present == NRPPA_RESOURCE_TYPE_POS_PR_SEMI_PERSISTENT) { + nrppa_resourceTypePos->present = NRPPA_ResourceTypePos_PR_semi_persistent; + asn1cCalloc(nrppa_resourceTypePos->choice.semi_persistent, nrppa_pos_semi_persistent); + switch (resource_type_pos->choice.semi_persistent.periodicity) { + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT1: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot1; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT2: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot2; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT4: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot4; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT5: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot5; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT8: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot8; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT10: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot10; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT16: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot16; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT20: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot20; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT32: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot32; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT40: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot40; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT64: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot64; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT80: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot80; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT160: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot160; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT320: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot320; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT640: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot640; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT1280: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot1280; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT2560: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot2560; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT5120: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot5120; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT10240: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot10240; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT20480: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot20480; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT40960: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot40960; + break; + case NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT81920: + nrppa_pos_semi_persistent->periodicity = NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot81920; + break; + default: + AssertFatal(false, "illegal periodicity %d\n", resource_type_pos->choice.semi_persistent.periodicity); + break; + } + nrppa_pos_semi_persistent->offset = resource_type_pos->choice.semi_persistent.offset; + } else if (resource_type_pos->present == NRPPA_RESOURCE_TYPE_POS_PR_APERIODIC) { + nrppa_resourceTypePos->present = NRPPA_ResourceTypePos_PR_aperiodic; + asn1cCalloc(nrppa_resourceTypePos->choice.aperiodic, nrppa_pos_aperiodic); + nrppa_pos_aperiodic->slotOffset = resource_type_pos->choice.aperiodic.slot_offset; + } else { + AssertFatal(false, "illegal resourceType %d\n", resource_type_pos->present); + } + + nrppa_pos_srs_resource->sequenceId = pos_srs_resource->sequence_id; + } + } + + // optional: srs_resource_set_list + if (in_config->srs_resource_set_list) { + nrppa_srs_resource_set_list_t *srs_resource_set_list = in_config->srs_resource_set_list; + uint32_t srs_resource_set_list_length = srs_resource_set_list->srs_resource_set_list_length; + asn1cCalloc(out_config.sRSResourceSet_List, nrppa_sRSResourceSet_List); + for (int i = 0; i < srs_resource_set_list_length; i++) { + asn1cSequenceAdd(nrppa_sRSResourceSet_List->list, NRPPA_SRSResourceSet_t, nrppa_srs_resource_set); + nrppa_srs_resource_set_t *srs_resource_set = &srs_resource_set_list->srs_resource_set[i]; + nrppa_srs_resource_set->sRSResourceSetID = srs_resource_set->srs_resource_set_id; + uint8_t srs_resource_id_list_length = srs_resource_set->srs_resource_id_list.srs_resource_id_list_length; + for (int j = 0; j < srs_resource_id_list_length; j++) { + asn1cSequenceAdd(nrppa_srs_resource_set->sRSResourceID_List.list, NRPPA_SRSResourceID_t, nrppa_srs_resource_id); + *nrppa_srs_resource_id = srs_resource_set->srs_resource_id_list.srs_resource_id[j]; + } + + NRPPA_ResourceSetType_t *nrppa_resourceSetType = &nrppa_srs_resource_set->resourceSetType; + nrppa_resource_set_type_t *resource_set_type = &srs_resource_set->resource_set_type; + switch (resource_set_type->present) { + case NRPPA_RESOURCE_SET_TYPE_PR_NOTHING: + nrppa_resourceSetType->present = NRPPA_ResourceSetType_PR_NOTHING; + break; + case NRPPA_RESOURCE_SET_TYPE_PR_PERIODIC: + nrppa_resourceSetType->present = NRPPA_ResourceSetType_PR_periodic; + asn1cCalloc(nrppa_resourceSetType->choice.periodic, nrppa_periodic_set_type); + nrppa_periodic_set_type->periodicSet = resource_set_type->choice.periodic; + break; + case NRPPA_RESOURCE_SET_TYPE_PR_SEMI_PERSISTENT: + nrppa_resourceSetType->present = NRPPA_ResourceSetType_PR_semi_persistent; + asn1cCalloc(nrppa_resourceSetType->choice.semi_persistent, nrppa_semi_persistent_set_type); + nrppa_semi_persistent_set_type->semi_persistentSet = resource_set_type->choice.semi_persistent; + break; + case NRPPA_RESOURCE_SET_TYPE_PR_APERIODIC: + nrppa_resourceSetType->present = NRPPA_ResourceSetType_PR_aperiodic; + asn1cCalloc(nrppa_resourceSetType->choice.aperiodic, nrppa_aperiodic_set_type); + nrppa_aperiodic_set_type->sRSResourceTrigger = resource_set_type->choice.aperiodic.srs_resource_trigger; + nrppa_aperiodic_set_type->slotoffset = resource_set_type->choice.aperiodic.slot_offset; + break; + default: + AssertFatal(false, "illegal resource set type %d\n", resource_set_type->present); + break; + } + } + } + + // optional: pos_srs_resource_set_list + if (in_config->pos_srs_resource_set_list) { + nrppa_pos_srs_resource_set_list_t *pos_srs_resource_set_list = in_config->pos_srs_resource_set_list; + uint32_t pos_srs_resource_set_list_length = pos_srs_resource_set_list->pos_srs_resource_set_list_length; + asn1cCalloc(out_config.posSRSResourceSet_List, nrppa_posSRSResourceSet_List); + for (int i = 0; i < pos_srs_resource_set_list_length; i++) { + asn1cSequenceAdd(nrppa_posSRSResourceSet_List->list, NRPPA_PosSRSResourceSet_Item_t, nrppa_pos_srs_resource_set); + nrppa_pos_srs_resource_set_item_t *pos_srs_resource_set = &pos_srs_resource_set_list->pos_srs_resource_set_item[i]; + nrppa_pos_srs_resource_set->possrsResourceSetID = pos_srs_resource_set->pos_srs_resource_set_id; + uint8_t pos_srs_resource_id_list_length = pos_srs_resource_set->pos_srs_resource_id_list.pos_srs_resource_id_list_length; + for (int j = 0; j < pos_srs_resource_id_list_length; j++) { + asn1cSequenceAdd(nrppa_pos_srs_resource_set->possRSResourceID_List.list, + NRPPA_SRSPosResourceID_t, + nrppa_pos_srs_resource_id); + *nrppa_pos_srs_resource_id = pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id[j]; + } + + NRPPA_PosResourceSetType_t *nrppa_posresourceSetType = &nrppa_pos_srs_resource_set->posresourceSetType; + nrppa_pos_resource_set_type_t *pos_resource_set_type = &pos_srs_resource_set->pos_resource_set_type; + switch (pos_resource_set_type->present) { + case NRPPA_POS_RESOURCE_SET_TYPE_PR_NOTHING: + nrppa_posresourceSetType->present = NRPPA_PosResourceSetType_PR_NOTHING; + break; + case NRPPA_POS_RESOURCE_SET_TYPE_PR_PERIODIC: + nrppa_posresourceSetType->present = NRPPA_PosResourceSetType_PR_periodic; + asn1cCalloc(nrppa_posresourceSetType->choice.periodic, nrppa_pos_periodic_set_type); + nrppa_pos_periodic_set_type->posperiodicSet = pos_resource_set_type->choice.periodic; + break; + case NRPPA_POS_RESOURCE_SET_TYPE_PR_SEMI_PERSISTENT: + nrppa_posresourceSetType->present = NRPPA_PosResourceSetType_PR_semi_persistent; + asn1cCalloc(nrppa_posresourceSetType->choice.semi_persistent, nrppa_pos_semi_persistent_set_type); + nrppa_pos_semi_persistent_set_type->possemi_persistentSet = pos_resource_set_type->choice.semi_persistent; + break; + case NRPPA_POS_RESOURCE_SET_TYPE_PR_APERIODIC: + nrppa_posresourceSetType->present = NRPPA_PosResourceSetType_PR_aperiodic; + asn1cCalloc(nrppa_posresourceSetType->choice.aperiodic, nrppa_pos_aperiodic_set_type); + nrppa_pos_aperiodic_set_type->sRSResourceTrigger = pos_resource_set_type->choice.srs_resource; + break; + default: + AssertFatal(false, "illegal resource set type pos %d\n", pos_resource_set_type->present); + break; + } + } + } + return out_config; +} + +static NRPPA_SRSCarrier_List_Item_t encode_srs_carrier_list_item(const nrppa_srs_carrier_list_item_t *in_item) +{ + NRPPA_SRSCarrier_List_Item_t out_item = {0}; + // pointA + out_item.pointA = in_item->pointA; + + // Uplink Channel BW-PerSCS-List + const nrppa_uplink_channel_bw_per_scs_list_t *uplink_channel_bw_per_scs_list = &in_item->uplink_channel_bw_per_scs_list; + NRPPA_UplinkChannelBW_PerSCS_List_t *nrppa_uplink_channel_bw_per_scs_list = &out_item.uplinkChannelBW_PerSCS_List; + + uint32_t scs_specific_carrier_list_length = uplink_channel_bw_per_scs_list->scs_specific_carrier_list_length; + for (int i = 0; i < scs_specific_carrier_list_length; i++) { + asn1cSequenceAdd(nrppa_uplink_channel_bw_per_scs_list->list, NRPPA_SCS_SpecificCarrier_t, nrppa_scs_specific_carrier); + nrppa_scs_specific_carrier_t *scs_specific_carrier = &uplink_channel_bw_per_scs_list->scs_specific_carrier[i]; + // offset to carrier + nrppa_scs_specific_carrier->offsetToCarrier = scs_specific_carrier->offset_to_carrier; + // subcarrier spacing + switch (scs_specific_carrier->subcarrier_spacing) { + case NRPPA_SUBCARRIER_SPACING_15KHZ: + nrppa_scs_specific_carrier->subcarrierSpacing = NRPPA_SCS_SpecificCarrier__subcarrierSpacing_kHz15; + break; + case NRPPA_SUBCARRIER_SPACING_30KHZ: + nrppa_scs_specific_carrier->subcarrierSpacing = NRPPA_SCS_SpecificCarrier__subcarrierSpacing_kHz30; + break; + case NRPPA_SUBCARRIER_SPACING_60KHZ: + nrppa_scs_specific_carrier->subcarrierSpacing = NRPPA_SCS_SpecificCarrier__subcarrierSpacing_kHz60; + break; + case NRPPA_SUBCARRIER_SPACING_120KHZ: + nrppa_scs_specific_carrier->subcarrierSpacing = NRPPA_SCS_SpecificCarrier__subcarrierSpacing_kHz120; + break; + default: + AssertFatal(false, "illegal subcarrier spacing %d\n", scs_specific_carrier->subcarrier_spacing); + break; + } + // carrier bandwidth + nrppa_scs_specific_carrier->carrierBandwidth = scs_specific_carrier->carrier_bandwidth; + } + + // Active UL BWP + NRPPA_ActiveULBWP_t *nrppa_active_ul_bwp = &out_item.activeULBWP; + const nrppa_active_ul_bwp_t *active_ul_bwp = &in_item->active_ul_bwp; + + // location and bandwidth + nrppa_active_ul_bwp->locationAndBandwidth = active_ul_bwp->location_and_bandwidth; + // subcarrier spacing + switch (active_ul_bwp->subcarrier_spacing) { + case NRPPA_SUBCARRIER_SPACING_15KHZ: + nrppa_active_ul_bwp->subcarrierSpacing = NRPPA_ActiveULBWP__subcarrierSpacing_kHz15; + break; + case NRPPA_SUBCARRIER_SPACING_30KHZ: + nrppa_active_ul_bwp->subcarrierSpacing = NRPPA_ActiveULBWP__subcarrierSpacing_kHz30; + break; + case NRPPA_SUBCARRIER_SPACING_60KHZ: + nrppa_active_ul_bwp->subcarrierSpacing = NRPPA_ActiveULBWP__subcarrierSpacing_kHz60; + break; + case NRPPA_SUBCARRIER_SPACING_120KHZ: + nrppa_active_ul_bwp->subcarrierSpacing = NRPPA_ActiveULBWP__subcarrierSpacing_kHz120; + break; + default: + AssertFatal(false, "illegal subcarrier spacing %d\n", active_ul_bwp->subcarrier_spacing); + break; + } + + // cyclic prefix + if (active_ul_bwp->cyclic_prefix == NRPPA_CP_TYPE_NORMAL) + nrppa_active_ul_bwp->cyclicPrefix = NRPPA_ActiveULBWP__cyclicPrefix_normal; + else + nrppa_active_ul_bwp->cyclicPrefix = NRPPA_ActiveULBWP__cyclicPrefix_extended; + + // Tx Direct Current Location + nrppa_active_ul_bwp->txDirectCurrentLocation = active_ul_bwp->tx_direct_current_location; + + // SRS Config + const nrppa_srs_config_t *sRSConfig = &active_ul_bwp->srs_config; + nrppa_active_ul_bwp->sRSConfig = encode_srs_config(sRSConfig); + return out_item; +} + +NRPPA_SRSCarrier_List_t encode_srs_carrier_list_nrppa(const nrppa_srs_carrier_list_t *in_list) +{ + NRPPA_SRSCarrier_List_t out_list = {0}; + uint32_t list_len = in_list->srs_carrier_list_length; + for (int i = 0; i < list_len; i++) { + asn1cSequenceAdd(out_list.list, NRPPA_SRSCarrier_List_Item_t, out_item); + nrppa_srs_carrier_list_item_t *in_item = &in_list->srs_carrier_list_item[i]; + *out_item = encode_srs_carrier_list_item(in_item); + } + return out_list; +} + +void free_srs_carrier_list(nrppa_srs_carrier_list_t *srs_carrier_list) +{ + uint32_t srs_carrier_list_len = srs_carrier_list->srs_carrier_list_length; + for (int i = 0; i < srs_carrier_list_len; i++) { + nrppa_srs_carrier_list_item_t *srs_carrier_list_item = &srs_carrier_list->srs_carrier_list_item[i]; + free(srs_carrier_list_item->uplink_channel_bw_per_scs_list.scs_specific_carrier); + + nrppa_active_ul_bwp_t *active_ul_bwp = &srs_carrier_list_item->active_ul_bwp; + nrppa_srs_config_t *sRSConfig = &active_ul_bwp->srs_config; + if (sRSConfig->srs_resource_list) { + nrppa_srs_resource_list_t *srs_resource_list = sRSConfig->srs_resource_list; + free(srs_resource_list->srs_resource); + free(sRSConfig->srs_resource_list); + } + if (sRSConfig->pos_srs_resource_list) { + nrppa_pos_srs_resource_list_t *pos_srs_resource_list = sRSConfig->pos_srs_resource_list; + free(pos_srs_resource_list->pos_srs_resource_item); + free(sRSConfig->pos_srs_resource_list); + } + if (sRSConfig->srs_resource_set_list) { + nrppa_srs_resource_set_list_t *srs_resource_set_list = sRSConfig->srs_resource_set_list; + uint32_t srs_resource_set_list_length = srs_resource_set_list->srs_resource_set_list_length; + for (int j = 0; j < srs_resource_set_list_length; j++) { + nrppa_srs_resource_set_t *srs_resource_set = &srs_resource_set_list->srs_resource_set[j]; + free(srs_resource_set->srs_resource_id_list.srs_resource_id); + } + free(srs_resource_set_list->srs_resource_set); + free(sRSConfig->srs_resource_set_list); + } + if (sRSConfig->pos_srs_resource_set_list) { + nrppa_pos_srs_resource_set_list_t *pos_srs_resource_set_list = sRSConfig->pos_srs_resource_set_list; + uint32_t pos_srs_resource_set_list_length = pos_srs_resource_set_list->pos_srs_resource_set_list_length; + for (int j = 0; j < pos_srs_resource_set_list_length; j++) { + nrppa_pos_srs_resource_set_item_t *pos_srs_resource_set = &pos_srs_resource_set_list->pos_srs_resource_set_item[j]; + free(pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id); + } + free(pos_srs_resource_set_list->pos_srs_resource_set_item); + free(sRSConfig->pos_srs_resource_set_list); + } + } + free(srs_carrier_list->srs_carrier_list_item); +} + +void free_positioning_information_response(nrppa_positioning_information_resp_t *msg) +{ + /* SRS Configuration (O) */ + if (msg->srs_configuration) { + nrppa_srs_carrier_list_t *srs_carrier_list = &msg->srs_configuration->srs_carrier_list; + free_srs_carrier_list(srs_carrier_list); + free(msg->srs_configuration); + } +} + +void decode_nrppa_srstype(NRPPA_SRSType_t *srs_type, nrppa_srs_type_t *out) +{ + switch (srs_type->present) { + case NRPPA_SRSType_PR_NOTHING: + out->present = NRPPA_SRS_TYPE_PR_NOTHING; + break; + case NRPPA_SRSType_PR_semipersistentSRS: + out->present = NRPPA_SRS_TYPE_PR_SEMIPERSISTENTSRS; + out->choice.srs_resource_set_id = calloc_or_fail(1, sizeof(*out->choice.srs_resource_set_id)); + *out->choice.srs_resource_set_id = srs_type->choice.semipersistentSRS->sRSResourceSetID; + break; + case NRPPA_SRSType_PR_aperiodicSRS: + out->present = NRPPA_SRS_TYPE_PR_APERIODICSRS; + out->choice.aperiodic = calloc_or_fail(1, sizeof(*out->choice.aperiodic)); + *out->choice.aperiodic = srs_type->choice.aperiodicSRS->aperiodic; + break; + default: + AssertFatal(false, "received illegal SRS type\n"); + break; + } +} + +void free_positioning_activation_request(nrppa_positioning_activation_req_t *msg) +{ + if (msg->srs_type.present == NRPPA_SRS_TYPE_PR_SEMIPERSISTENTSRS) { + free(msg->srs_type.choice.srs_resource_set_id); + } else if (msg->srs_type.present == NRPPA_SRS_TYPE_PR_APERIODICSRS) { + free(msg->srs_type.choice.aperiodic); + } +} + +int nrppa_gNB_handle_trp_information_request(nrppa_gnb_ue_info_t *nrppa_msg_info, const NRPPA_NRPPA_PDU_t *pdu) +{ + LOG_I(NRPPA, "Processing Received TRP Information Request \n"); + DevAssert(pdu != NULL); + DevAssert(nrppa_msg_info != NULL); + + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + xer_fprint(stdout, &asn_DEF_NRPPA_NRPPA_PDU, pdu); + } + + // Forward request to RRC + MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, NRPPA_TRP_INFORMATION_REQ); + nrppa_trp_information_req_t *req = &NRPPA_TRP_INFORMATION_REQ(msg); + + // Processing Received TRPInformationRequest + NRPPA_TRPInformationRequest_t *container = NULL; + NRPPA_TRPInformationRequest_IEs_t *ie = NULL; + + // IE 9.2.3 Message type : mandatory + container = &pdu->choice.initiatingMessage->value.choice.TRPInformationRequest; + + // IE 9.2.4 nrppatransactionID : mandatory + req->transaction_id = pdu->choice.initiatingMessage->nrppatransactionID; + + // IE TRP List : optional + NRPPA_FIND_PROTOCOLIE_BY_ID(NRPPA_TRPInformationRequest_IEs_t, ie, container, NRPPA_ProtocolIE_ID_id_TRPList, false); + + if (ie == NULL) { + req->has_trp_list = false; + } else { + LOG_W(NRPPA, "TRPInformationRequest IE TRP List : not handled\n"); + } + + // IE TRP Information Type List: mandatory + // not implemented in oai-lmf + NRPPA_FIND_PROTOCOLIE_BY_ID(NRPPA_TRPInformationRequest_IEs_t, + ie, + container, + NRPPA_ProtocolIE_ID_id_TRPInformationTypeList, + false); + + if (ie == NULL) { + LOG_W(NRPPA, "TRPInformationRequest IE TRP Information Type List is mandatory but not handled\n"); + } else { + uint8_t trp_info_list_len = ie->value.choice.TRPInformationTypeList.list.count; + AssertError(trp_info_list_len > 0, return false, "at least 1 TRP Information Type must be present"); + nrppa_trp_information_type_list_t *trp_info_list = &req->trp_information_type_list; + trp_info_list->trp_information_type_list_length = trp_info_list_len; + trp_info_list->trp_information_type_item = calloc_or_fail(trp_info_list_len, sizeof(*trp_info_list->trp_information_type_item)); + for (int i = 0; i < trp_info_list_len; i++) { + trp_info_list->trp_information_type_item[i] = *ie->value.choice.TRPInformationTypeList.list.array[i]; + } + } + + nrppa_store_ue_context(nrppa_msg_info, req->transaction_id); + + LOG_I(NRPPA, "Forwarding to RRC TRPInformationRequest transaction_id=%d\n", req->transaction_id); + itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return 0; +} + +int nrppa_gNB_trp_information_response(instance_t instance, MessageDef *msg_p) +{ + DevAssert(msg_p); + nrppa_trp_information_resp_t *resp = &NRPPA_TRP_INFORMATION_RESP(msg_p); + nrppa_gNB_ue_context_t *ue_info = nrppa_detach_ue_context(resp->transaction_id); + + if (ue_info->gNB_ue_ngap_id != 0 && ue_info->amf_ue_ngap_id != 0) { + LOG_E(NRPPA, "Illegal gNB_ue_ngap_id %d and amf_ue_ngap_id %ld\n", ue_info->gNB_ue_ngap_id, ue_info->amf_ue_ngap_id); + free_trp_information_response(resp); + nrppa_free_ue_context(ue_info); + return -1; + } + + LOG_I(NRPPA, "Received TRP Information Response info from RRC with transaction_id = %u\n", ue_info->transaction_id); + + // Prepare NRPPA TRP Information transfer Response + NRPPA_NRPPA_PDU_t pdu = {0}; + + // IE: 9.2.3 Message Type : mandatory + pdu.present = NRPPA_NRPPA_PDU_PR_successfulOutcome; + asn1cCalloc(pdu.choice.successfulOutcome, head); + head->procedureCode = NRPPA_ProcedureCode_id_tRPInformationExchange; + head->criticality = NRPPA_Criticality_reject; + head->value.present = NRPPA_SuccessfulOutcome__value_PR_TRPInformationResponse; + + // IE 9.2.4 nrppatransactionID : mandatory + head->nrppatransactionID = resp->transaction_id; + NRPPA_TRPInformationResponse_t *out = &head->value.choice.TRPInformationResponse; + + // IE TRP Information List : mandatory + { + asn1cSequenceAdd(out->protocolIEs.list, NRPPA_TRPInformationResponse_IEs_t, ie); + ie->id = NRPPA_ProtocolIE_ID_id_TRPInformationList; + ie->criticality = NRPPA_Criticality_ignore; + ie->value.present = NRPPA_TRPInformationResponse_IEs__value_PR_TRPInformationList; + + uint32_t trp_info_item_len = resp->trp_information_list.trp_information_item_length; + for (int i = 0; i < trp_info_item_len; i++) { + // TRPInformationItem (M) + asn1cSequenceAdd(ie->value.choice.TRPInformationList.list, TRPInformationList__Member, trpinfolist_member); + nrppa_trp_information_t *nrppa_tRPInformation = &resp->trp_information_list.trp_information_item[i]; + + trpinfolist_member->tRP_ID = nrppa_tRPInformation->trp_id; + + NRPPA_TRPInformation_t *trp_info = &trpinfolist_member->tRPInformation; + + nrppa_trp_information_type_response_list_t *nrppa_tRPInformationTypeResponseList = + &nrppa_tRPInformation->trp_information_type_response_list; + uint8_t trp_info_type_resp_item_len = nrppa_tRPInformationTypeResponseList->trp_information_type_response_item_length; + + for (int j = 0; j < trp_info_type_resp_item_len; j++) { + asn1cSequenceAdd(trp_info->list, NRPPA_TRPInformationItem_t, trp_info_item); + nrppa_trp_information_type_response_item_t *resp_item = + &nrppa_tRPInformationTypeResponseList->trp_information_type_response_item[j]; + *trp_info_item = encode_trp_info_type_response_item_nrppa(resp_item); + } + } + } + + free_trp_information_response(resp); + + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + xer_fprint(stdout, &asn_DEF_NRPPA_NRPPA_PDU, &pdu); + } + + // Encode NRPPA message + uint8_t *buffer = NULL; + uint32_t length = 0; + if (nrppa_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { + LOG_E(NRPPA, "Failed to encode Uplink NRPPa TRP Information Response\n"); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return -1; + } + + MessageDef *msg = itti_alloc_new_message(TASK_NRPPA, 0, NGAP_UPLINKNONUEASSOCIATEDNRPPA); + ngap_uplink_non_ue_associated_nrppa_t *ULNRPPA = &NGAP_UPLINKNONUEASSOCIATEDNRPPA(msg); + + // Routing ID + ULNRPPA->routing_id = create_byte_array(ue_info->routing_id.len, ue_info->routing_id.buf); + + // NRPPa PDU + ULNRPPA->nrppa_pdu = create_byte_array(length, buffer); + + // Forward the NRPPA PDU to NGAP + itti_send_msg_to_task(TASK_NGAP, instance, msg); + nrppa_free_ue_context(ue_info); + free(buffer); + + return length; +} + +int nrppa_gNB_handle_positioning_information_request(nrppa_gnb_ue_info_t *nrppa_msg_info, const NRPPA_NRPPA_PDU_t *pdu) +{ + DevAssert(pdu != NULL); + DevAssert(nrppa_msg_info != NULL); + + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + xer_fprint(stdout, &asn_DEF_NRPPA_NRPPA_PDU, pdu); + } + + LOG_I(NRPPA, "Processing Received Positioning Information Request\n"); + + // Preparing positioning information request for RRC + MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, NRPPA_POSITIONING_INFORMATION_REQ); + nrppa_positioning_information_req_t *req = &NRPPA_POSITIONING_INFORMATION_REQ(msg); + + // IE 9.2.4 nrppatransactionID : mandatory + req->transaction_id = pdu->choice.initiatingMessage->nrppatransactionID; + + nrppa_store_ue_context(nrppa_msg_info, req->transaction_id); + + LOG_I(NRPPA, "Forwarding to RRC Positioning Information Request transaction id=%d\n", req->transaction_id); + + itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return 0; +} + +int nrppa_gNB_positioning_information_response(instance_t instance, MessageDef *msg_p) +{ + DevAssert(msg_p); + nrppa_positioning_information_resp_t *resp = &NRPPA_POSITIONING_INFORMATION_RESP(msg_p); + nrppa_gNB_ue_context_t *ue_info = nrppa_detach_ue_context(resp->transaction_id); + + if (ue_info->gNB_ue_ngap_id <= 0 && ue_info->amf_ue_ngap_id <= 0) { + LOG_E(NRPPA, "Illegal gNB_ue_ngap_id %d and amf_ue_ngap_id %ld\n", ue_info->gNB_ue_ngap_id, ue_info->amf_ue_ngap_id); + free_positioning_information_response(resp); + nrppa_free_ue_context(ue_info); + return -1; + } + + LOG_I(NRPPA, + "Received Positioning Information Response info from RRC with transaction_id = %u and gNB_ue_ngap_id %u\n", + ue_info->transaction_id, + ue_info->gNB_ue_ngap_id); + + // Prepare NRPPA TRP Information transfer Response + NRPPA_NRPPA_PDU_t pdu = {0}; + + // IE: 9.2.3 Message Type : mandatory + pdu.present = NRPPA_NRPPA_PDU_PR_successfulOutcome; + asn1cCalloc(pdu.choice.successfulOutcome, head); + head->procedureCode = NRPPA_ProcedureCode_id_positioningInformationExchange; + head->criticality = NRPPA_Criticality_reject; + head->value.present = NRPPA_SuccessfulOutcome__value_PR_PositioningInformationResponse; + + // IE 9.2.4 nrppatransactionID : mandatory + head->nrppatransactionID = resp->transaction_id; + NRPPA_PositioningInformationResponse_t *out = &head->value.choice.PositioningInformationResponse; + + // IE SRS Configuration : optional + { + if (resp->srs_configuration) { + asn1cSequenceAdd(out->protocolIEs.list, NRPPA_PositioningInformationResponse_IEs_t, ie); + ie->id = NRPPA_ProtocolIE_ID_id_SRSConfiguration; + ie->criticality = NRPPA_Criticality_ignore; + ie->value.present = NRPPA_PositioningInformationResponse_IEs__value_PR_SRSConfiguration; + nrppa_srs_carrier_list_t *srs_carrier_list = &resp->srs_configuration->srs_carrier_list; + ie->value.choice.SRSConfiguration.sRSCarrier_List = encode_srs_carrier_list_nrppa(srs_carrier_list); + } + } + + free_positioning_information_response(resp); + + LOG_I(NRPPA, "Calling encoder for Positioning Information Response \n"); + + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + xer_fprint(stdout, &asn_DEF_NRPPA_NRPPA_PDU, &pdu); + } + + // Encode NRPPA message + uint8_t *buffer = NULL; + uint32_t length = 0; + if (nrppa_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { + LOG_E(NRPPA, "Failed to encode Uplink NRPPa PositioningInformationResponse\n"); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return -1; + } + + MessageDef *msg = itti_alloc_new_message(TASK_NRPPA, 0, NGAP_UPLINKUEASSOCIATEDNRPPA); + ngap_uplink_ue_associated_nrppa_t *ULNRPPA = &NGAP_UPLINKUEASSOCIATEDNRPPA(msg); + + ULNRPPA->gNB_ue_ngap_id = ue_info->gNB_ue_ngap_id; + ULNRPPA->amf_ue_ngap_id = ue_info->amf_ue_ngap_id; + + // Routing ID + ULNRPPA->routing_id = create_byte_array(ue_info->routing_id.len, ue_info->routing_id.buf); + + // NRPPA PDU + ULNRPPA->nrppa_pdu = create_byte_array(length, buffer); + + // Forward the NRPPA PDU to NGAP + itti_send_msg_to_task(TASK_NGAP, instance, msg); + nrppa_free_ue_context(ue_info); + free(buffer); + return length; +} + +int nrppa_gNB_handle_positioning_activation_request(nrppa_gnb_ue_info_t *nrppa_msg_info, const NRPPA_NRPPA_PDU_t *pdu) +{ + LOG_I(NRPPA, "Processing Received Positioning Activation Request \n"); + DevAssert(pdu != NULL); + DevAssert(nrppa_msg_info != NULL); + + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + xer_fprint(stdout, &asn_DEF_NRPPA_NRPPA_PDU, pdu); + } + + // Preparing positioning information request for RRC + MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, NRPPA_POSITIONING_ACTIVATION_REQ); + nrppa_positioning_activation_req_t *req = &NRPPA_POSITIONING_ACTIVATION_REQ(msg); + + // Processing Received PositioningActivationRequest + NRPPA_PositioningActivationRequest_t *container = NULL; + NRPPA_PositioningActivationRequestIEs_t *ie = NULL; + + // IE 9.2.3 Message type : mandatory + container = &pdu->choice.initiatingMessage->value.choice.PositioningActivationRequest; + + // IE 9.2.4 nrppatransactionID : mandatory + req->transaction_id = pdu->choice.initiatingMessage->nrppatransactionID; + + // IE SRSType : mandatory + NRPPA_FIND_PROTOCOLIE_BY_ID(NRPPA_PositioningActivationRequestIEs_t, ie, container, NRPPA_ProtocolIE_ID_id_SRSType, true); + decode_nrppa_srstype(&ie->value.choice.SRSType, &req->srs_type); + + nrppa_store_ue_context(nrppa_msg_info, req->transaction_id); + + LOG_I(NRPPA, "Forwarding to RRC Positioning Activation Request transaction id = %d\n", req->transaction_id); + + itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return 0; +} + +int nrppa_gNB_positioning_activation_response(instance_t instance, MessageDef *msg_p) +{ + DevAssert(msg_p); + nrppa_positioning_activation_resp_t *resp = &NRPPA_POSITIONING_ACTIVATION_RESP(msg_p); + nrppa_gNB_ue_context_t *ue_info = nrppa_detach_ue_context(resp->transaction_id); + + if (ue_info->gNB_ue_ngap_id <= 0 && ue_info->amf_ue_ngap_id <= 0) { + LOG_E(NRPPA, "Illegal gNB_ue_ngap_id %d and amf_ue_ngap_id %ld\n", ue_info->gNB_ue_ngap_id, ue_info->amf_ue_ngap_id); + nrppa_free_ue_context(ue_info); + return -1; + } + + LOG_I(NRPPA, + "Received PositioningInformationResponse info from RRC with transaction_id=%u and gNB_ue_ngap_id %u\n", + ue_info->transaction_id, + ue_info->gNB_ue_ngap_id); + + // Prepare NRPPA TRP Information transfer Response + NRPPA_NRPPA_PDU_t pdu = {0}; + + // IE: 9.2.3 Message Type : mandatory + pdu.present = NRPPA_NRPPA_PDU_PR_successfulOutcome; + asn1cCalloc(pdu.choice.successfulOutcome, head); + head->procedureCode = NRPPA_ProcedureCode_id_positioningActivation; + head->criticality = NRPPA_Criticality_reject; + head->value.present = NRPPA_SuccessfulOutcome__value_PR_PositioningActivationResponse; + + // IE 9.2.4 nrppatransactionID : mandatory + head->nrppatransactionID = resp->transaction_id; + + LOG_I(NRPPA, "Calling encoder for PositioningActivationResponse \n"); + + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + xer_fprint(stdout, &asn_DEF_NRPPA_NRPPA_PDU, &pdu); + } + + // Encode NRPPA message + uint8_t *buffer = NULL; + uint32_t length = 0; + if (nrppa_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { + LOG_E(NRPPA, "Failed to encode Uplink NRPPa PositioningActivationResponse\n"); + nrppa_free_ue_context(ue_info); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return -1; + } + + MessageDef *msg = itti_alloc_new_message(TASK_NRPPA, 0, NGAP_UPLINKUEASSOCIATEDNRPPA); + ngap_uplink_ue_associated_nrppa_t *ULNRPPA = &NGAP_UPLINKUEASSOCIATEDNRPPA(msg); + + ULNRPPA->gNB_ue_ngap_id = ue_info->gNB_ue_ngap_id; + ULNRPPA->amf_ue_ngap_id = ue_info->amf_ue_ngap_id; + + // Routing ID + ULNRPPA->routing_id = create_byte_array(ue_info->routing_id.len, ue_info->routing_id.buf); + + // NRPPA PDU + ULNRPPA->nrppa_pdu = create_byte_array(length, buffer); + + // Forward the NRPPA PDU to NGAP + itti_send_msg_to_task(TASK_NGAP, instance, msg); + nrppa_free_ue_context(ue_info); + free(buffer); + return length; +} diff --git a/openair3/NRPPA/nrppa_gNB_location_information_transfer.h b/openair3/NRPPA/nrppa_gNB_location_information_transfer.h new file mode 100644 index 0000000000..29d73c0059 --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB_location_information_transfer.h @@ -0,0 +1,41 @@ +/* + * 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 NRPPA_GNB_POSITIONING_PROCEDURES_H_ +#define NRPPA_GNB_POSITIONING_PROCEDURES_H_ + +int nrppa_gNB_handle_trp_information_request(nrppa_gnb_ue_info_t *nrppa_msg_info, const NRPPA_NRPPA_PDU_t *pdu); +void free_trp_information_request(nrppa_trp_information_req_t *msg); +int nrppa_gNB_trp_information_response(instance_t instance, MessageDef *msg_p); +void free_trp_information_request(nrppa_trp_information_req_t *msg); +NRPPA_TRPInformationItem_t encode_trp_info_type_response_item_nrppa(nrppa_trp_information_type_response_item_t *in); +void free_trp_information_response(nrppa_trp_information_resp_t *msg); +int nrppa_gNB_handle_positioning_information_request(nrppa_gnb_ue_info_t *nrppa_msg_info, const NRPPA_NRPPA_PDU_t *pdu); +int nrppa_gNB_positioning_information_response(instance_t instance, MessageDef *msg_p); +NRPPA_SRSCarrier_List_t encode_srs_carrier_list_nrppa(const nrppa_srs_carrier_list_t *in_list); +void free_srs_carrier_list(nrppa_srs_carrier_list_t *srs_carrier_list); +void free_positioning_information_response(nrppa_positioning_information_resp_t *msg); +int nrppa_gNB_handle_positioning_activation_request(nrppa_gnb_ue_info_t *nrppa_msg_info, const NRPPA_NRPPA_PDU_t *pdu); +void decode_nrppa_srstype(NRPPA_SRSType_t *srs_type, nrppa_srs_type_t *out); +void free_positioning_activation_request(nrppa_positioning_activation_req_t *msg); +int nrppa_gNB_positioning_activation_response(instance_t instance, MessageDef *msg_p); + +#endif /* NRPPA_GNB_POSITIONING_PROCEDURES_H_ */ diff --git a/openair3/NRPPA/nrppa_gNB_measurement_information_transfer.c b/openair3/NRPPA/nrppa_gNB_measurement_information_transfer.c new file mode 100644 index 0000000000..afeacae4c7 --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB_measurement_information_transfer.c @@ -0,0 +1,1143 @@ +/* + * 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 "intertask_interface.h" +#include "nrppa_common.h" +#include "nrppa_gNB_ue_context.h" +#include "nrppa_messages_types.h" +#include "nrppa_gNB_encoder.h" +#include "openair3/UTILS/conversions.h" +#include "nrppa_gNB_measurement_information_transfer.h" +#include "nrppa_gNB_location_information_transfer.h" + +static void decode_srs_config(const NRPPA_SRSConfig_t *in_config, nrppa_srs_config_t *out_config) +{ + // optional: sRSResource_List + if (in_config->sRSResource_List) { + out_config->srs_resource_list = calloc_or_fail(1, sizeof(*out_config->srs_resource_list)); + nrppa_srs_resource_list_t *srs_resource_list = out_config->srs_resource_list; + uint32_t srs_resource_list_length = in_config->sRSResource_List->list.count; + srs_resource_list->srs_resource_list_length = srs_resource_list_length; + srs_resource_list->srs_resource = calloc_or_fail(srs_resource_list_length, sizeof(*srs_resource_list->srs_resource)); + for (int i = 0; i < srs_resource_list_length; i++) { + nrppa_srs_resource_t *srs_resource = &srs_resource_list->srs_resource[i]; + NRPPA_SRSResource_t *nrppa_srs_resource = in_config->sRSResource_List->list.array[i]; + srs_resource->srs_resource_id = nrppa_srs_resource->sRSResourceID; + switch (nrppa_srs_resource->nrofSRS_Ports) { + case NRPPA_SRSResource__nrofSRS_Ports_port1: + srs_resource->nr_of_srs_ports = NRPPA_SRS_NUMBER_OF_PORTS_N1; + break; + case NRPPA_SRSResource__nrofSRS_Ports_ports2: + srs_resource->nr_of_srs_ports = NRPPA_SRS_NUMBER_OF_PORTS_N2; + break; + case NRPPA_SRSResource__nrofSRS_Ports_ports4: + srs_resource->nr_of_srs_ports = NRPPA_SRS_NUMBER_OF_PORTS_N4; + break; + default: + AssertFatal(false, "illegal number of srs ports %ld\n", nrppa_srs_resource->nrofSRS_Ports); + break; + } + + nrppa_transmission_comb_t *srs_tx_comb = &srs_resource->transmission_comb; + NRPPA_TransmissionComb_t *nrppa_srs_tx_comb = &nrppa_srs_resource->transmissionComb; + switch (nrppa_srs_tx_comb->present) { + case NRPPA_TransmissionComb_PR_NOTHING: + srs_tx_comb->present = NRPPA_TRANSMISSION_COMB_PR_NOTHING; + break; + case NRPPA_TransmissionComb_PR_n2: + srs_tx_comb->present = NRPPA_TRANSMISSION_COMB_PR_N2; + srs_tx_comb->choice.n2.comb_offset_n2 = nrppa_srs_tx_comb->choice.n2->combOffset_n2; + srs_tx_comb->choice.n2.cyclic_shift_n2 = nrppa_srs_tx_comb->choice.n2->cyclicShift_n2; + break; + case NRPPA_TransmissionComb_PR_n4: + srs_tx_comb->present = NRPPA_TRANSMISSION_COMB_PR_N4; + srs_tx_comb->choice.n4.comb_offset_n4 = nrppa_srs_tx_comb->choice.n4->combOffset_n4; + srs_tx_comb->choice.n4.cyclic_shift_n4 = nrppa_srs_tx_comb->choice.n4->cyclicShift_n4; + break; + default: + AssertFatal(false, "illegal transmissionComb %d\n", nrppa_srs_tx_comb->present); + break; + } + + srs_resource->start_position = nrppa_srs_resource->startPosition; + + switch (nrppa_srs_resource->nrofSymbols) { + case NRPPA_SRSResource__nrofSymbols_n1: + srs_resource->nr_of_symbols = NRPPA_SRS_NUMBER_OF_SYMBOLS_N1; + break; + case NRPPA_SRSResource__nrofSymbols_n2: + srs_resource->nr_of_symbols = NRPPA_SRS_NUMBER_OF_SYMBOLS_N2; + break; + case NRPPA_SRSResource__nrofSymbols_n4: + srs_resource->nr_of_symbols = NRPPA_SRS_NUMBER_OF_SYMBOLS_N4; + break; + default: + AssertFatal(false, "illegal number of symbols %ld\n", nrppa_srs_resource->nrofSymbols); + break; + } + + switch (nrppa_srs_resource->repetitionFactor) { + case NRPPA_SRSResource__repetitionFactor_n1: + srs_resource->repetition_factor = NRPPA_SRS_REPETITION_FACTOR_RF1; + break; + case NRPPA_SRSResource__repetitionFactor_n2: + srs_resource->repetition_factor = NRPPA_SRS_REPETITION_FACTOR_RF2; + break; + case NRPPA_SRSResource__repetitionFactor_n4: + srs_resource->repetition_factor = NRPPA_SRS_REPETITION_FACTOR_RF4; + break; + default: + AssertFatal(false, "illegal repetition factor %ld\n", nrppa_srs_resource->repetitionFactor); + break; + } + + srs_resource->freq_domain_position = nrppa_srs_resource->freqDomainPosition; + srs_resource->freq_domain_shift = nrppa_srs_resource->freqDomainShift; + srs_resource->c_srs = nrppa_srs_resource->c_SRS; + srs_resource->b_srs = nrppa_srs_resource->b_SRS; + srs_resource->b_hop = nrppa_srs_resource->b_hop; + + switch (nrppa_srs_resource->groupOrSequenceHopping) { + case NRPPA_SRSResource__groupOrSequenceHopping_neither: + srs_resource->group_or_sequence_hopping = NRPPA_GROUPORSEQUENCEHOPPING_NOTHING; + break; + case NRPPA_SRSResource__groupOrSequenceHopping_groupHopping: + srs_resource->group_or_sequence_hopping = NRPPA_GROUPORSEQUENCEHOPPING_GROUPHOPPING; + break; + case NRPPA_SRSResource__groupOrSequenceHopping_sequenceHopping: + srs_resource->group_or_sequence_hopping = NRPPA_GROUPORSEQUENCEHOPPING_SEQUENCEHOPPING; + break; + default: + AssertFatal(false, "illegal groupOrSequenceHopping %ld\n", nrppa_srs_resource->groupOrSequenceHopping); + break; + } + + NRPPA_ResourceType_t *nrppa_resourceType = &nrppa_srs_resource->resourceType; + nrppa_resource_type_t *resource_type = &srs_resource->resource_type; + if (nrppa_resourceType->present == NRPPA_ResourceType_PR_NOTHING) { + resource_type->present = NRPPA_RESOURCE_TYPE_PR_NOTHING; + } else if (nrppa_resourceType->present == NRPPA_ResourceType_PR_periodic) { + resource_type->present = NRPPA_RESOURCE_TYPE_PR_PERIODIC; + nrppa_resource_type_periodic_t *periodic = &resource_type->choice.periodic; + switch (nrppa_resourceType->choice.periodic->periodicity) { + case NRPPA_ResourceTypePeriodic__periodicity_slot1: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT1; + break; + case NRPPA_ResourceTypePeriodic__periodicity_slot2: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT2; + break; + case NRPPA_ResourceTypePeriodic__periodicity_slot4: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT4; + break; + case NRPPA_ResourceTypePeriodic__periodicity_slot5: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT5; + break; + case NRPPA_ResourceTypePeriodic__periodicity_slot8: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT8; + break; + case NRPPA_ResourceTypePeriodic__periodicity_slot10: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT10; + break; + case NRPPA_ResourceTypePeriodic__periodicity_slot16: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT16; + break; + case NRPPA_ResourceTypePeriodic__periodicity_slot20: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT20; + break; + case NRPPA_ResourceTypePeriodic__periodicity_slot32: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT32; + break; + case NRPPA_ResourceTypePeriodic__periodicity_slot40: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT40; + break; + case NRPPA_ResourceTypePeriodic__periodicity_slot64: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT64; + break; + case NRPPA_ResourceTypePeriodic__periodicity_slot80: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT80; + break; + case NRPPA_ResourceTypePeriodic__periodicity_slot160: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT160; + break; + case NRPPA_ResourceTypePeriodic__periodicity_slot320: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT320; + break; + case NRPPA_ResourceTypePeriodic__periodicity_slot640: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT640; + break; + case NRPPA_ResourceTypePeriodic__periodicity_slot1280: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT1280; + break; + case NRPPA_ResourceTypePeriodic__periodicity_slot2560: + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT2560; + break; + default: + AssertFatal(false, "illegal periodicity %ld\n", nrppa_resourceType->choice.periodic->periodicity); + break; + } + periodic->offset = nrppa_resourceType->choice.periodic->offset; + } else if (nrppa_resourceType->present == NRPPA_ResourceType_PR_semi_persistent) { + resource_type->present = NRPPA_RESOURCE_TYPE_PR_SEMI_PERSISTENT; + nrppa_resource_type_semi_persistent_t *semi_persistent = &resource_type->choice.semi_persistent; + switch (nrppa_resourceType->choice.semi_persistent->periodicity) { + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot1: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT1; + break; + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot2: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT2; + break; + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot4: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT4; + break; + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot5: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT5; + break; + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot8: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT8; + break; + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot10: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT10; + break; + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot16: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT16; + break; + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot20: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT20; + break; + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot32: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT32; + break; + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot40: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT40; + break; + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot64: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT64; + break; + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot80: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT80; + break; + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot160: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT160; + break; + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot320: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT320; + break; + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot640: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT640; + break; + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot1280: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT1280; + break; + case NRPPA_ResourceTypeSemi_persistent__periodicity_slot2560: + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT2560; + break; + default: + AssertFatal(false, "illegal periodicity %ld\n", nrppa_resourceType->choice.semi_persistent->periodicity); + break; + } + semi_persistent->offset = nrppa_resourceType->choice.semi_persistent->offset; + } else if (nrppa_resourceType->present == NRPPA_ResourceType_PR_aperiodic) { + resource_type->present = NRPPA_RESOURCE_TYPE_PR_APERIODIC; + resource_type->choice.aperiodic = nrppa_resourceType->choice.aperiodic->aperiodicResourceType; + } else { + AssertFatal(false, "illegal resourceType %d\n", nrppa_resourceType->present); + } + + srs_resource->sequence_id = nrppa_srs_resource->sequenceId; + } + } + + // optional: posSRSResource_List + if (in_config->posSRSResource_List) { + out_config->pos_srs_resource_list = calloc_or_fail(1, sizeof(*out_config->pos_srs_resource_list)); + nrppa_pos_srs_resource_list_t *pos_srs_resource_list = out_config->pos_srs_resource_list; + uint32_t pos_srs_resource_list_length = in_config->posSRSResource_List->list.count; + pos_srs_resource_list->pos_srs_resource_list_length = pos_srs_resource_list_length; + pos_srs_resource_list->pos_srs_resource_item = + calloc_or_fail(pos_srs_resource_list_length, sizeof(*pos_srs_resource_list->pos_srs_resource_item)); + for (int i = 0; i < pos_srs_resource_list_length; i++) { + NRPPA_PosSRSResource_Item_t *nrppa_pos_srs_resource = in_config->posSRSResource_List->list.array[i]; + nrppa_pos_srs_resource_item_t *pos_srs_resource = &pos_srs_resource_list->pos_srs_resource_item[i]; + pos_srs_resource->srs_pos_resource_id = nrppa_pos_srs_resource->srs_PosResourceId; + + NRPPA_TransmissionCombPos_t *nrppa_tx_comb_pos = &nrppa_pos_srs_resource->transmissionCombPos; + nrppa_transmission_comb_pos_t *tx_comb_pos = &pos_srs_resource->transmission_comb_pos; + switch (nrppa_tx_comb_pos->present) { + case NRPPA_TransmissionCombPos_PR_NOTHING: + tx_comb_pos->present = NRPPA_TRANSMISSION_COMB_POS_PR_NOTHING; + break; + case NRPPA_TransmissionCombPos_PR_n2: + tx_comb_pos->present = NRPPA_TRANSMISSION_COMB_POS_PR_N2; + tx_comb_pos->choice.n2.comb_offset_n2 = nrppa_tx_comb_pos->choice.n2->combOffset_n2; + tx_comb_pos->choice.n2.cyclic_shift_n2 = nrppa_tx_comb_pos->choice.n2->cyclicShift_n2; + break; + case NRPPA_TransmissionCombPos_PR_n4: + tx_comb_pos->present = NRPPA_TRANSMISSION_COMB_POS_PR_N4; + tx_comb_pos->choice.n4.comb_offset_n4 = nrppa_tx_comb_pos->choice.n4->combOffset_n4; + tx_comb_pos->choice.n4.cyclic_shift_n4 = nrppa_tx_comb_pos->choice.n4->cyclicShift_n4; + break; + case NRPPA_TransmissionCombPos_PR_n8: + tx_comb_pos->present = NRPPA_TRANSMISSION_COMB_POS_PR_N8; + tx_comb_pos->choice.n8.comb_offset_n8 = nrppa_tx_comb_pos->choice.n8->combOffset_n8; + tx_comb_pos->choice.n8.cyclic_shift_n8 = nrppa_tx_comb_pos->choice.n8->cyclicShift_n8; + break; + default: + AssertFatal(false, "illegal transmissionComb %d\n", nrppa_tx_comb_pos->present); + break; + } + + pos_srs_resource->start_position = nrppa_pos_srs_resource->startPosition; + + switch (nrppa_pos_srs_resource->nrofSymbols) { + case NRPPA_PosSRSResource_Item__nrofSymbols_n1: + pos_srs_resource->nr_of_symbols = NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N1; + break; + case NRPPA_PosSRSResource_Item__nrofSymbols_n2: + pos_srs_resource->nr_of_symbols = NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N2; + break; + case NRPPA_PosSRSResource_Item__nrofSymbols_n4: + pos_srs_resource->nr_of_symbols = NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N4; + break; + case NRPPA_PosSRSResource_Item__nrofSymbols_n8: + pos_srs_resource->nr_of_symbols = NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N8; + break; + case NRPPA_PosSRSResource_Item__nrofSymbols_n12: + pos_srs_resource->nr_of_symbols = NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N12; + break; + default: + AssertFatal(false, "illegal number of symbols %ld\n", nrppa_pos_srs_resource->nrofSymbols); + break; + } + + pos_srs_resource->freq_domain_shift = nrppa_pos_srs_resource->freqDomainShift; + pos_srs_resource->c_srs = nrppa_pos_srs_resource->c_SRS; + + switch (nrppa_pos_srs_resource->groupOrSequenceHopping) { + case NRPPA_PosSRSResource_Item__groupOrSequenceHopping_neither: + pos_srs_resource->group_or_sequence_hopping = NRPPA_GROUPORSEQUENCEHOPPING_NOTHING; + break; + case NRPPA_PosSRSResource_Item__groupOrSequenceHopping_groupHopping: + pos_srs_resource->group_or_sequence_hopping = NRPPA_GROUPORSEQUENCEHOPPING_GROUPHOPPING; + break; + case NRPPA_PosSRSResource_Item__groupOrSequenceHopping_sequenceHopping: + pos_srs_resource->group_or_sequence_hopping = NRPPA_GROUPORSEQUENCEHOPPING_SEQUENCEHOPPING; + break; + default: + AssertFatal(false, "illegal groupOrSequenceHopping %ld\n", nrppa_pos_srs_resource->groupOrSequenceHopping); + break; + } + + NRPPA_ResourceTypePos_t *nrppa_res_type_pos = &nrppa_pos_srs_resource->resourceTypePos; + nrppa_resource_type_pos_t *res_type_pos = &pos_srs_resource->resource_type_pos; + if (nrppa_res_type_pos->present == NRPPA_ResourceTypePos_PR_NOTHING) { + res_type_pos->present = NRPPA_RESOURCE_TYPE_POS_PR_NOTHING; + } else if (nrppa_res_type_pos->present == NRPPA_ResourceTypePos_PR_periodic) { + res_type_pos->present = NRPPA_RESOURCE_TYPE_POS_PR_PERIODIC; + nrppa_resource_type_periodic_pos_t *pos_periodic = &res_type_pos->choice.periodic; + switch (nrppa_res_type_pos->choice.periodic->periodicity) { + case NRPPA_ResourceTypePeriodicPos__periodicity_slot1: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT1; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot2: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT2; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot4: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT4; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot5: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT5; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot8: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT8; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot10: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT10; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot16: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT16; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot20: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT20; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot32: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT32; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot40: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT40; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot64: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT64; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot80: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT80; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot160: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT160; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot320: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT320; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot640: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT640; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot1280: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT1280; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot2560: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT2560; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot5120: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT5120; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot10240: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT10240; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot20480: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT20480; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot40960: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT40960; + break; + case NRPPA_ResourceTypePeriodicPos__periodicity_slot81920: + pos_periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT81920; + break; + default: + AssertFatal(false, "illegal periodicity %ld\n", nrppa_res_type_pos->choice.periodic->periodicity); + break; + } + pos_periodic->offset = nrppa_res_type_pos->choice.periodic->offset; + } else if (nrppa_res_type_pos->present == NRPPA_ResourceTypePos_PR_semi_persistent) { + res_type_pos->present = NRPPA_RESOURCE_TYPE_POS_PR_SEMI_PERSISTENT; + nrppa_resource_type_semi_persistent_pos_t *pos_semi_persistent = &res_type_pos->choice.semi_persistent; + switch (nrppa_res_type_pos->choice.semi_persistent->periodicity) { + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot1: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT1; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot2: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT2; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot4: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT4; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot5: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT5; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot8: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT8; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot10: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT10; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot16: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT16; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot20: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT20; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot32: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT32; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot40: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT40; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot64: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT64; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot80: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT80; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot160: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT160; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot320: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT320; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot640: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT640; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot1280: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT1280; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot2560: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT2560; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot5120: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT5120; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot10240: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT10240; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot20480: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT20480; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot40960: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT40960; + break; + case NRPPA_ResourceTypeSemi_persistentPos__periodicity_slot81920: + pos_semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT81920; + break; + default: + AssertFatal(false, "illegal periodicity %ld\n", nrppa_res_type_pos->choice.semi_persistent->periodicity); + break; + } + pos_semi_persistent->offset = nrppa_res_type_pos->choice.semi_persistent->offset; + } else if (nrppa_res_type_pos->present == NRPPA_ResourceTypePos_PR_aperiodic) { + res_type_pos->present = NRPPA_RESOURCE_TYPE_POS_PR_APERIODIC; + res_type_pos->choice.aperiodic.slot_offset = nrppa_res_type_pos->choice.aperiodic->slotOffset; + } else { + AssertFatal(false, "illegal resourceType %d\n", nrppa_res_type_pos->present); + } + + pos_srs_resource->sequence_id = nrppa_pos_srs_resource->sequenceId; + } + } + + // optional: sRSResourceSet_List + if (in_config->sRSResourceSet_List) { + out_config->srs_resource_set_list = calloc_or_fail(1, sizeof(*out_config->srs_resource_set_list)); + nrppa_srs_resource_set_list_t *srs_resource_set_list = out_config->srs_resource_set_list; + uint32_t srs_resource_set_list_length = in_config->sRSResourceSet_List->list.count; + srs_resource_set_list->srs_resource_set_list_length = srs_resource_set_list_length; + srs_resource_set_list->srs_resource_set = + calloc_or_fail(srs_resource_set_list_length, sizeof(*srs_resource_set_list->srs_resource_set)); + for (int i = 0; i < srs_resource_set_list_length; i++) { + NRPPA_SRSResourceSet_t *nrppa_srs_resource_set = in_config->sRSResourceSet_List->list.array[i]; + nrppa_srs_resource_set_t *srs_resource_set = &srs_resource_set_list->srs_resource_set[i]; + srs_resource_set->srs_resource_set_id = nrppa_srs_resource_set->sRSResourceSetID; + uint8_t srs_resource_id_list_length = nrppa_srs_resource_set->sRSResourceID_List.list.count; + srs_resource_set->srs_resource_id_list.srs_resource_id_list_length = srs_resource_id_list_length; + srs_resource_set->srs_resource_id_list.srs_resource_id = + calloc_or_fail(srs_resource_id_list_length, sizeof(*srs_resource_set->srs_resource_id_list.srs_resource_id)); + for (int j = 0; j < srs_resource_id_list_length; j++) { + NRPPA_SRSResourceID_t *nrppa_srs_resource_id = nrppa_srs_resource_set->sRSResourceID_List.list.array[j]; + srs_resource_set->srs_resource_id_list.srs_resource_id[j] = *nrppa_srs_resource_id; + } + + NRPPA_ResourceSetType_t *nrppa_res_set_type = &nrppa_srs_resource_set->resourceSetType; + nrppa_resource_set_type_t *res_set_type = &srs_resource_set->resource_set_type; + switch (nrppa_res_set_type->present) { + case NRPPA_ResourceSetType_PR_NOTHING: + res_set_type->present = NRPPA_RESOURCE_SET_TYPE_PR_NOTHING; + break; + case NRPPA_ResourceSetType_PR_periodic: + res_set_type->present = NRPPA_RESOURCE_SET_TYPE_PR_PERIODIC; + res_set_type->choice.periodic = nrppa_res_set_type->choice.periodic->periodicSet; + break; + case NRPPA_ResourceSetType_PR_semi_persistent: + res_set_type->present = NRPPA_RESOURCE_SET_TYPE_PR_SEMI_PERSISTENT; + res_set_type->choice.semi_persistent = nrppa_res_set_type->choice.semi_persistent->semi_persistentSet; + break; + case NRPPA_ResourceSetType_PR_aperiodic: + res_set_type->present = NRPPA_RESOURCE_SET_TYPE_PR_APERIODIC; + res_set_type->choice.aperiodic.srs_resource_trigger = nrppa_res_set_type->choice.aperiodic->sRSResourceTrigger; + res_set_type->choice.aperiodic.slot_offset = nrppa_res_set_type->choice.aperiodic->slotoffset; + break; + default: + AssertFatal(false, "illegal resource set type %d\n", nrppa_res_set_type->present); + break; + } + } + } + + // optional: posSRSResourceSet_List + if (in_config->posSRSResourceSet_List) { + out_config->pos_srs_resource_set_list = calloc_or_fail(1, sizeof(*out_config->pos_srs_resource_set_list)); + nrppa_pos_srs_resource_set_list_t *pos_srs_resource_set_list = out_config->pos_srs_resource_set_list; + uint32_t pos_srs_resource_set_list_length = in_config->posSRSResourceSet_List->list.count; + pos_srs_resource_set_list->pos_srs_resource_set_list_length = pos_srs_resource_set_list_length; + pos_srs_resource_set_list->pos_srs_resource_set_item = + calloc_or_fail(pos_srs_resource_set_list_length, sizeof(*pos_srs_resource_set_list->pos_srs_resource_set_item)); + for (int i = 0; i < pos_srs_resource_set_list_length; i++) { + NRPPA_PosSRSResourceSet_Item_t *nrppa_pos_srs_resource_set = in_config->posSRSResourceSet_List->list.array[i]; + nrppa_pos_srs_resource_set_item_t *pos_srs_resource_set = &pos_srs_resource_set_list->pos_srs_resource_set_item[i]; + pos_srs_resource_set->pos_srs_resource_set_id = nrppa_pos_srs_resource_set->possrsResourceSetID; + uint8_t pos_srs_resource_id_list_length = nrppa_pos_srs_resource_set->possRSResourceID_List.list.count; + pos_srs_resource_set->pos_srs_resource_id_list.pos_srs_resource_id_list_length = pos_srs_resource_id_list_length; + pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id = + calloc_or_fail(pos_srs_resource_id_list_length, + sizeof(*pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id)); + for (int j = 0; j < pos_srs_resource_id_list_length; j++) { + NRPPA_SRSPosResourceID_t *nrppa_pos_srs_resource_id = nrppa_pos_srs_resource_set->possRSResourceID_List.list.array[j]; + pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id[j] = *nrppa_pos_srs_resource_id; + } + + NRPPA_PosResourceSetType_t *nrppa_pos_res_set_type = &nrppa_pos_srs_resource_set->posresourceSetType; + nrppa_pos_resource_set_type_t *pos_res_set_type = &pos_srs_resource_set->pos_resource_set_type; + switch (nrppa_pos_res_set_type->present) { + case NRPPA_PosResourceSetType_PR_NOTHING: + pos_res_set_type->present = NRPPA_POS_RESOURCE_SET_TYPE_PR_NOTHING; + break; + case NRPPA_PosResourceSetType_PR_periodic: + pos_res_set_type->present = NRPPA_POS_RESOURCE_SET_TYPE_PR_PERIODIC; + pos_res_set_type->choice.periodic = nrppa_pos_res_set_type->choice.periodic->posperiodicSet; + break; + case NRPPA_PosResourceSetType_PR_semi_persistent: + pos_res_set_type->present = NRPPA_POS_RESOURCE_SET_TYPE_PR_SEMI_PERSISTENT; + pos_res_set_type->choice.semi_persistent = nrppa_pos_res_set_type->choice.semi_persistent->possemi_persistentSet; + break; + case NRPPA_PosResourceSetType_PR_aperiodic: + pos_res_set_type->present = NRPPA_POS_RESOURCE_SET_TYPE_PR_APERIODIC; + pos_res_set_type->choice.srs_resource = nrppa_pos_res_set_type->choice.aperiodic->sRSResourceTrigger; + break; + default: + AssertFatal(false, "illegal resource set type pos %d\n", nrppa_pos_res_set_type->present); + break; + } + } + } +} + +static void decode_srs_carrier_list_item(const NRPPA_SRSCarrier_List_Item_t *in_item, nrppa_srs_carrier_list_item_t *out_item) +{ + // pointA + out_item->pointA = in_item->pointA; + + // Uplink Channel BW-PerSCS-List + nrppa_uplink_channel_bw_per_scs_list_t *uplink_channel_bw_per_scs_list = &out_item->uplink_channel_bw_per_scs_list; + const NRPPA_UplinkChannelBW_PerSCS_List_t *nrppa_uplink_channel_bw_per_scs_list = &in_item->uplinkChannelBW_PerSCS_List; + + uint32_t scs_specific_carrier_list_length = nrppa_uplink_channel_bw_per_scs_list->list.count; + AssertFatal(scs_specific_carrier_list_length > 0, "Atleast 1 uplink channel bw per scs list should be present\n"); + uplink_channel_bw_per_scs_list->scs_specific_carrier_list_length = scs_specific_carrier_list_length; + uplink_channel_bw_per_scs_list->scs_specific_carrier = + calloc_or_fail(scs_specific_carrier_list_length, sizeof(*uplink_channel_bw_per_scs_list->scs_specific_carrier)); + for (int i = 0; i < scs_specific_carrier_list_length; i++) { + NRPPA_SCS_SpecificCarrier_t *nrppa_scs_specific_carrier = nrppa_uplink_channel_bw_per_scs_list->list.array[i]; + nrppa_scs_specific_carrier_t *scs_specific_carrier = &uplink_channel_bw_per_scs_list->scs_specific_carrier[i]; + // offset to carrier + scs_specific_carrier->offset_to_carrier = nrppa_scs_specific_carrier->offsetToCarrier; + // subcarrier spacing + switch (nrppa_scs_specific_carrier->subcarrierSpacing) { + case NRPPA_SCS_SpecificCarrier__subcarrierSpacing_kHz15: + scs_specific_carrier->subcarrier_spacing = NRPPA_SUBCARRIER_SPACING_15KHZ; + break; + case NRPPA_SCS_SpecificCarrier__subcarrierSpacing_kHz30: + scs_specific_carrier->subcarrier_spacing = NRPPA_SUBCARRIER_SPACING_30KHZ; + break; + case NRPPA_SCS_SpecificCarrier__subcarrierSpacing_kHz60: + scs_specific_carrier->subcarrier_spacing = NRPPA_SUBCARRIER_SPACING_60KHZ; + break; + case NRPPA_SCS_SpecificCarrier__subcarrierSpacing_kHz120: + scs_specific_carrier->subcarrier_spacing = NRPPA_SUBCARRIER_SPACING_120KHZ; + break; + default: + AssertFatal(false, "illegal subcarrier spacing %ld\n", nrppa_scs_specific_carrier->subcarrierSpacing); + break; + } + // carrier bandwidth + scs_specific_carrier->carrier_bandwidth = nrppa_scs_specific_carrier->carrierBandwidth; + } + + // Active UL BWP + const NRPPA_ActiveULBWP_t *nrppa_active_ul_bwp = &in_item->activeULBWP; + nrppa_active_ul_bwp_t *active_ul_bwp = &out_item->active_ul_bwp; + + // location and bandwidth + active_ul_bwp->location_and_bandwidth = nrppa_active_ul_bwp->locationAndBandwidth; + // subcarrier spacing + switch (nrppa_active_ul_bwp->subcarrierSpacing) { + case NRPPA_ActiveULBWP__subcarrierSpacing_kHz15: + active_ul_bwp->subcarrier_spacing = NRPPA_SUBCARRIER_SPACING_15KHZ; + break; + case NRPPA_ActiveULBWP__subcarrierSpacing_kHz30: + active_ul_bwp->subcarrier_spacing = NRPPA_SUBCARRIER_SPACING_30KHZ; + break; + case NRPPA_ActiveULBWP__subcarrierSpacing_kHz60: + active_ul_bwp->subcarrier_spacing = NRPPA_SUBCARRIER_SPACING_60KHZ; + break; + case NRPPA_ActiveULBWP__subcarrierSpacing_kHz120: + active_ul_bwp->subcarrier_spacing = NRPPA_SUBCARRIER_SPACING_120KHZ; + break; + default: + AssertFatal(false, "illegal subcarrier spacing %ld\n", nrppa_active_ul_bwp->subcarrierSpacing); + break; + } + + // cyclic prefix + if (nrppa_active_ul_bwp->cyclicPrefix == NRPPA_ActiveULBWP__cyclicPrefix_normal) + active_ul_bwp->cyclic_prefix = NRPPA_CP_TYPE_NORMAL; + else + active_ul_bwp->cyclic_prefix = NRPPA_CP_TYPE_EXTENDED; + + // Tx Direct Current Location + active_ul_bwp->tx_direct_current_location = nrppa_active_ul_bwp->txDirectCurrentLocation; + + // SRS Config + const NRPPA_SRSConfig_t *nrppa_sRSConfig = &nrppa_active_ul_bwp->sRSConfig; + nrppa_srs_config_t *sRSConfig = &active_ul_bwp->srs_config; + decode_srs_config(nrppa_sRSConfig, sRSConfig); +} + +void decode_srs_carrier_list(nrppa_srs_carrier_list_t *out_list, const NRPPA_SRSCarrier_List_t *in_list) +{ + uint32_t list_len = in_list->list.count; + AssertFatal(list_len > 0, "atleast 1 SRS carrier list must be present"); + out_list->srs_carrier_list_length = list_len; + out_list->srs_carrier_list_item = calloc_or_fail(list_len, sizeof(*out_list->srs_carrier_list_item)); + for (int i = 0; i < list_len; i++) { + NRPPA_SRSCarrier_List_Item_t *in_item = in_list->list.array[i]; + nrppa_srs_carrier_list_item_t *out_item = &out_list->srs_carrier_list_item[i]; + decode_srs_carrier_list_item(in_item, out_item); + } +} + +void free_measurement_request(nrppa_measurement_req_t *msg) +{ + free(msg->trp_measurement_request_list.trp_measurement_request_item); + if (msg->measurement_quantities.measurement_quantities_item) { + free(msg->measurement_quantities.measurement_quantities_item); + } + + /* SRS Configuration (O) */ + if (msg->srs_configuration) { + nrppa_srs_carrier_list_t *srs_carrier_list = &msg->srs_configuration->srs_carrier_list; + free_srs_carrier_list(srs_carrier_list); + free(msg->srs_configuration); + } +} + +static NRPPA_TrpMeasurementResult_t encode_measurement_results(nrppa_measurement_result_t *in_result) +{ + NRPPA_TrpMeasurementResult_t out_result = {0}; + for (int i = 0; i < in_result->measurement_result_item_length; i++) { + asn1cSequenceAdd(out_result.list, NRPPA_TrpMeasurementResultItem_t, out_item); + nrppa_measurement_result_item_t *in_item = &in_result->measurement_result_item[i]; + NRPPA_TrpMeasuredResultsValue_t *out_meas_res_val = &out_item->measuredResultsValue; + nrppa_measured_results_value_t *in_meas_res_val = &in_item->measured_results_value; + switch (in_meas_res_val->present) { + case NRPPA_MEASURED_RESULTS_VALUE_PR_NOTHING: + out_meas_res_val->present = NRPPA_TrpMeasuredResultsValue_PR_NOTHING; + break; + case NRPPA_MEASURED_RESULTS_VALUE_PR_UL_ANGLEOFARRIVAL: + out_meas_res_val->present = NRPPA_TrpMeasuredResultsValue_PR_uL_AngleOfArrival; + asn1cCalloc(out_meas_res_val->choice.uL_AngleOfArrival, out_ul_aoa); + nrppa_ul_aoa_t *in_ul_aoa = &in_meas_res_val->choice.ul_angle_of_arrival; + out_ul_aoa->azimuthAoA = in_ul_aoa->azimuth_aoa; + if (in_ul_aoa->zenith_aoa) { + asn1cCalloc(out_ul_aoa->zenithAoA, out_z_aoa); + *out_z_aoa = *in_ul_aoa->zenith_aoa; + } + break; + case NRPPA_MEASURED_RESULTS_VALUE_PR_UL_SRS_RSRP: + out_meas_res_val->present = NRPPA_TrpMeasuredResultsValue_PR_uL_SRS_RSRP; + out_meas_res_val->choice.uL_SRS_RSRP = in_meas_res_val->choice.ul_srs_rsrp; + break; + case NRPPA_MEASURED_RESULTS_VALUE_PR_UL_RTOA: + out_meas_res_val->present = NRPPA_TrpMeasuredResultsValue_PR_uL_RTOA; + asn1cCalloc(out_meas_res_val->choice.uL_RTOA, out_ul_rtoa); + nrppa_ul_rtoa_measurement_t *in_ul_rtoa = &in_meas_res_val->choice.ul_rtoa; + switch (in_ul_rtoa->present) { + case NRPPA_ULRTOAMEAS_PR_NOTHING: + out_ul_rtoa->uLRTOAmeas.present = NRPPA_ULRTOAMeas_PR_NOTHING; + break; + case NRPPA_ULRTOAMEAS_PR_K0: + out_ul_rtoa->uLRTOAmeas.present = NRPPA_ULRTOAMeas_PR_k0; + out_ul_rtoa->uLRTOAmeas.choice.k0 = in_ul_rtoa->choice.k0; + break; + case NRPPA_ULRTOAMEAS_PR_K1: + out_ul_rtoa->uLRTOAmeas.present = NRPPA_ULRTOAMeas_PR_k1; + out_ul_rtoa->uLRTOAmeas.choice.k1 = in_ul_rtoa->choice.k1; + break; + case NRPPA_ULRTOAMEAS_PR_K2: + out_ul_rtoa->uLRTOAmeas.present = NRPPA_ULRTOAMeas_PR_k2; + out_ul_rtoa->uLRTOAmeas.choice.k2 = in_ul_rtoa->choice.k2; + break; + case NRPPA_ULRTOAMEAS_PR_K3: + out_ul_rtoa->uLRTOAmeas.present = NRPPA_ULRTOAMeas_PR_k3; + out_ul_rtoa->uLRTOAmeas.choice.k3 = in_ul_rtoa->choice.k3; + break; + case NRPPA_ULRTOAMEAS_PR_K4: + out_ul_rtoa->uLRTOAmeas.present = NRPPA_ULRTOAMeas_PR_k4; + out_ul_rtoa->uLRTOAmeas.choice.k4 = in_ul_rtoa->choice.k4; + break; + case NRPPA_ULRTOAMEAS_PR_K5: + out_ul_rtoa->uLRTOAmeas.present = NRPPA_ULRTOAMeas_PR_k5; + out_ul_rtoa->uLRTOAmeas.choice.k5 = in_ul_rtoa->choice.k5; + break; + default: + AssertFatal(false, "illegal ul rtoa measure type\n"); + break; + } + break; + case NRPPA_MEASURED_RESULTS_VALUE_PR_GNB_RXTXTIMEDIFF: + out_meas_res_val->present = NRPPA_TrpMeasuredResultsValue_PR_gNB_RxTxTimeDiff; + asn1cCalloc(out_meas_res_val->choice.gNB_RxTxTimeDiff, out_rxtx_time_diff); + nrppa_gnb_rx_tx_time_diff_t *in_rxtx_time_diff = &in_meas_res_val->choice.gnb_rx_tx_time_diff; + switch (in_rxtx_time_diff->present) { + case NRPPA_GNBRXTXTIMEDIFFMEAS_PR_NOTHING: + out_rxtx_time_diff->rxTxTimeDiff.present = NRPPA_GNBRxTxTimeDiffMeas_PR_NOTHING; + break; + case NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K0: + out_rxtx_time_diff->rxTxTimeDiff.present = NRPPA_GNBRxTxTimeDiffMeas_PR_k0; + out_rxtx_time_diff->rxTxTimeDiff.choice.k0 = in_rxtx_time_diff->choice.k0; + break; + case NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K1: + out_rxtx_time_diff->rxTxTimeDiff.present = NRPPA_GNBRxTxTimeDiffMeas_PR_k1; + out_rxtx_time_diff->rxTxTimeDiff.choice.k1 = in_rxtx_time_diff->choice.k1; + break; + case NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K2: + out_rxtx_time_diff->rxTxTimeDiff.present = NRPPA_GNBRxTxTimeDiffMeas_PR_k2; + out_rxtx_time_diff->rxTxTimeDiff.choice.k2 = in_rxtx_time_diff->choice.k2; + break; + case NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K3: + out_rxtx_time_diff->rxTxTimeDiff.present = NRPPA_GNBRxTxTimeDiffMeas_PR_k3; + out_rxtx_time_diff->rxTxTimeDiff.choice.k3 = in_rxtx_time_diff->choice.k3; + break; + case NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K4: + out_rxtx_time_diff->rxTxTimeDiff.present = NRPPA_GNBRxTxTimeDiffMeas_PR_k4; + out_rxtx_time_diff->rxTxTimeDiff.choice.k4 = in_rxtx_time_diff->choice.k4; + break; + case NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K5: + out_rxtx_time_diff->rxTxTimeDiff.present = NRPPA_GNBRxTxTimeDiffMeas_PR_k5; + out_rxtx_time_diff->rxTxTimeDiff.choice.k5 = in_rxtx_time_diff->choice.k5; + break; + default: + AssertFatal(false, "illegal ul rtoa measure type\n"); + break; + } + break; + default: + AssertFatal(false, "illegal measured results type\n"); + break; + } + + NRPPA_TimeStamp_t *out_time_stamp = &out_item->timeStamp; + nrppa_time_stamp_t *in_time_stamp = &in_item->time_stamp; + out_time_stamp->systemFrameNumber = in_time_stamp->system_frame_number; + switch (in_time_stamp->slot_index.present) { + case NRPPA_TIME_STAMP_SLOT_INDEX_PR_NOTHING: + out_time_stamp->slotIndex.present = NRPPA_TimeStampSlotIndex_PR_NOTHING; + break; + case NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_15: + out_time_stamp->slotIndex.present = NRPPA_TimeStampSlotIndex_PR_sCS_15; + out_time_stamp->slotIndex.choice.sCS_15 = in_time_stamp->slot_index.choice.scs_15; + break; + case NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_30: + out_time_stamp->slotIndex.present = NRPPA_TimeStampSlotIndex_PR_sCS_30; + out_time_stamp->slotIndex.choice.sCS_30 = in_time_stamp->slot_index.choice.scs_30; + break; + case NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_60: + out_time_stamp->slotIndex.present = NRPPA_TimeStampSlotIndex_PR_sCS_60; + out_time_stamp->slotIndex.choice.sCS_60 = in_time_stamp->slot_index.choice.scs_60; + break; + case NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_120: + out_time_stamp->slotIndex.present = NRPPA_TimeStampSlotIndex_PR_sCS_120; + out_time_stamp->slotIndex.choice.sCS_120 = in_time_stamp->slot_index.choice.scs_120; + break; + default: + AssertFatal(false, "illegal slot index\n"); + break; + } + } + return out_result; +} + +NRPPA_TRP_MeasurementResponseList_t encode_trp_measurement_reponse_list(nrppa_measurement_response_list_t *in_list) +{ + NRPPA_TRP_MeasurementResponseList_t out_list = {0}; + for (int i = 0; i < in_list->measurement_response_list_length; i++) { + asn1cSequenceAdd(out_list.list, NRPPA_TRP_MeasurementResponseItem_t, out_item); + nrppa_measurement_response_item_t *in_item = &in_list->measurement_response_item[i]; + out_item->tRP_ID = in_item->trp_id; + out_item->measurementResult = encode_measurement_results(&in_item->measurement_result); + } + + return out_list; +} + +void free_measurement_resp(nrppa_measurement_resp_t *msg) +{ + if (msg->measurement_response_list) { + nrppa_measurement_response_list_t *list = msg->measurement_response_list; + uint32_t meas_resp_list_len = list->measurement_response_list_length; + for (int i = 0; i < meas_resp_list_len; i++) { + nrppa_measurement_response_item_t *meas_response_item = &list->measurement_response_item[i]; + nrppa_measurement_result_t *MeasurementResult = &meas_response_item->measurement_result; + uint32_t meas_result_length = MeasurementResult->measurement_result_item_length; + for (int j = 0; j < meas_result_length; j++) { + nrppa_measurement_result_item_t *item = &MeasurementResult->measurement_result_item[j]; + nrppa_measured_results_value_t *measuredResultsValue = &item->measured_results_value; + if (measuredResultsValue->present == NRPPA_MEASURED_RESULTS_VALUE_PR_UL_ANGLEOFARRIVAL) { + if (measuredResultsValue->choice.ul_angle_of_arrival.zenith_aoa) { + free(measuredResultsValue->choice.ul_angle_of_arrival.zenith_aoa); + } + } + } + free(MeasurementResult->measurement_result_item); + } + free(msg->measurement_response_list->measurement_response_item); + free(msg->measurement_response_list); + } +} + +int nrppa_gNB_handle_measurement_request(nrppa_gnb_ue_info_t *nrppa_msg_info, const NRPPA_NRPPA_PDU_t *pdu) +{ + DevAssert(pdu != NULL); + DevAssert(nrppa_msg_info != NULL); + + LOG_I(NRPPA, "Processing Received Measurement Request \n"); + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + xer_fprint(stdout, &asn_DEF_NRPPA_NRPPA_PDU, pdu); + } + + // Forward request to RRC + MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, NRPPA_MEASUREMENT_REQ); + nrppa_measurement_req_t *req = &NRPPA_MEASUREMENT_REQ(msg); + + // Processing Received TRPInformationRequest + NRPPA_MeasurementRequest_t *container = NULL; + NRPPA_MeasurementRequest_IEs_t *ie = NULL; + + // IE 9.2.3 Message type : mandatory + container = &pdu->choice.initiatingMessage->value.choice.MeasurementRequest; + + // IE 9.2.4 nrppatransactionID : mandatory + req->transaction_id = pdu->choice.initiatingMessage->nrppatransactionID; + + NRPPA_FIND_PROTOCOLIE_BY_ID(NRPPA_MeasurementRequest_IEs_t, ie, container, NRPPA_ProtocolIE_ID_id_LMF_Measurement_ID, true); + + // LMF Measurement ID : mandatory + req->lmf_measurement_id = ie->value.choice.Measurement_ID; + + // IE TRP Measurement Request List : mandatory + NRPPA_FIND_PROTOCOLIE_BY_ID(NRPPA_MeasurementRequest_IEs_t, + ie, + container, + NRPPA_ProtocolIE_ID_id_TRP_MeasurementRequestList, + true); + NRPPA_TRP_MeasurementRequestList_t *nrppa_trp_meas_list = &ie->value.choice.TRP_MeasurementRequestList; + uint8_t meas_req_item_len = nrppa_trp_meas_list->list.count; + AssertError(meas_req_item_len > 0, return false, "at least 1 TRP Measurement Request Item must be present"); + nrppa_trp_measurement_request_list_t *trp_meas_list = &req->trp_measurement_request_list; + trp_meas_list->trp_measurement_request_list_length = meas_req_item_len; + trp_meas_list->trp_measurement_request_item = + calloc_or_fail(meas_req_item_len, sizeof(*trp_meas_list->trp_measurement_request_item)); + for (int i = 0; i < meas_req_item_len; i++) { + trp_meas_list->trp_measurement_request_item[i].trp_id = nrppa_trp_meas_list->list.array[i]->tRP_ID; + } + + // IE Report Characteristics : mandatory + NRPPA_FIND_PROTOCOLIE_BY_ID(NRPPA_MeasurementRequest_IEs_t, ie, container, NRPPA_ProtocolIE_ID_id_ReportCharacteristics, true); + switch (ie->value.choice.ReportCharacteristics) { + case NRPPA_ReportCharacteristics_onDemand: + req->report_characteristics = NRPPA_POSREPORTCHARACTERISTICS_ONDEMAND; + break; + case NRPPA_ReportCharacteristics_periodic: + req->report_characteristics = NRPPA_POSREPORTCHARACTERISTICS_PERIODIC; + break; + default: + AssertError(false, return false, "illegal report characteristics\n"); + break; + } + + // IE Measurement Periodicity : C-if Report Charateristics periodic + if (req->report_characteristics == NRPPA_POSREPORTCHARACTERISTICS_PERIODIC) { + NRPPA_FIND_PROTOCOLIE_BY_ID(NRPPA_MeasurementRequest_IEs_t, ie, container, NRPPA_ProtocolIE_ID_id_MeasurementPeriodicity, true); + switch (ie->value.choice.MeasurementPeriodicity) { + case NRPPA_MeasurementPeriodicity_ms120: + req->measurement_periodicity = NRPPA_POSMEASUREMENTPERIODICITY_MS120; + break; + case NRPPA_MeasurementPeriodicity_ms240: + req->measurement_periodicity = NRPPA_POSMEASUREMENTPERIODICITY_MS240; + break; + case NRPPA_MeasurementPeriodicity_ms480: + req->measurement_periodicity = NRPPA_POSMEASUREMENTPERIODICITY_MS480; + break; + case NRPPA_MeasurementPeriodicity_ms640: + req->measurement_periodicity = NRPPA_POSMEASUREMENTPERIODICITY_MS640; + break; + case NRPPA_MeasurementPeriodicity_ms1024: + req->measurement_periodicity = NRPPA_POSMEASUREMENTPERIODICITY_MS1024; + break; + case NRPPA_MeasurementPeriodicity_ms2048: + req->measurement_periodicity = NRPPA_POSMEASUREMENTPERIODICITY_MS2048; + break; + case NRPPA_MeasurementPeriodicity_ms5120: + req->measurement_periodicity = NRPPA_POSMEASUREMENTPERIODICITY_MS5120; + break; + case NRPPA_MeasurementPeriodicity_ms10240: + req->measurement_periodicity = NRPPA_POSMEASUREMENTPERIODICITY_MS10240; + break; + case NRPPA_MeasurementPeriodicity_min1: + req->measurement_periodicity = NRPPA_POSMEASUREMENTPERIODICITY_MIN1; + break; + case NRPPA_MeasurementPeriodicity_min6: + req->measurement_periodicity = NRPPA_POSMEASUREMENTPERIODICITY_MIN6; + break; + case NRPPA_MeasurementPeriodicity_min12: + req->measurement_periodicity = NRPPA_POSMEASUREMENTPERIODICITY_MIN12; + break; + case NRPPA_MeasurementPeriodicity_min30: + req->measurement_periodicity = NRPPA_POSMEASUREMENTPERIODICITY_MIN30; + break; + case NRPPA_MeasurementPeriodicity_min60: + req->measurement_periodicity = NRPPA_POSMEASUREMENTPERIODICITY_MIN60; + break; + default: + AssertError(false, return false, "illegal measurement periodicity\n"); + break; + } + } + + // IE Measurement Quantity : mandatory (but not handled in OAI-LMF) + NRPPA_FIND_PROTOCOLIE_BY_ID(NRPPA_MeasurementRequest_IEs_t, ie, container, NRPPA_ProtocolIE_ID_id_MeasurementQuantities, false); + if (ie == NULL) { + LOG_W(NRPPA, "MeasurementQuantities is madatory but not handled in OAI LMF\n"); + } else { + NRPPA_TRPMeasurementQuantities_t *nrppa_meas_q = &ie->value.choice.TRPMeasurementQuantities; + uint32_t q_len = nrppa_meas_q->list.count; + AssertError(q_len > 0, return false, "at least 1 TRP Measurement Quantity must be present"); + nrppa_measurement_quantities_t *meas_q = &req->measurement_quantities; + meas_q->measurement_quantities_length = q_len; + meas_q->measurement_quantities_item = calloc_or_fail(q_len, sizeof(*meas_q->measurement_quantities_item)); + nrppa_measurement_quantities_item_t *q_item = meas_q->measurement_quantities_item; + for (int i = 0; i < meas_req_item_len; i++) { + switch (nrppa_meas_q->list.array[i]->tRPMeasurementQuantities_Item) { + case NRPPA_TRPMeasurementQuantities_Item_gNB_RxTxTimeDiff: + q_item[i].measurement_type = NRPPA_POSMEASUREMENTTYPE_GNB_RX_TX; + break; + case NRPPA_TRPMeasurementQuantities_Item_uL_SRS_RSRP: + q_item[i].measurement_type = NRPPA_POSMEASUREMENTTYPE_UL_SRS_RSRP; + break; + case NRPPA_TRPMeasurementQuantities_Item_uL_AoA: + q_item[i].measurement_type = NRPPA_POSMEASUREMENTTYPE_UL_AOA; + break; + case NRPPA_TRPMeasurementQuantities_Item_uL_RTOA: + q_item[i].measurement_type = NRPPA_POSMEASUREMENTTYPE_UL_RTOA; + break; + default: + AssertError(false, return false, "illegal measurement quantity\n"); + break; + } + } + } + + // IE SRS Configuration : optional + NRPPA_FIND_PROTOCOLIE_BY_ID(NRPPA_MeasurementRequest_IEs_t, ie, container, NRPPA_ProtocolIE_ID_id_SRSConfiguration, false); + if (ie != NULL) { + NRPPA_SRSCarrier_List_t *nrppa_srs_carrier_list = &ie->value.choice.SRSConfiguration.sRSCarrier_List; + req->srs_configuration = calloc_or_fail(1, sizeof(*req->srs_configuration)); + nrppa_srs_carrier_list_t *srs_carrier_list = &req->srs_configuration->srs_carrier_list; + decode_srs_carrier_list(srs_carrier_list, nrppa_srs_carrier_list); + } + + nrppa_store_ue_context(nrppa_msg_info, req->transaction_id); + + LOG_I(NRPPA, "Forwarding to RRC Measurement Request transaction_id %d\n", req->transaction_id); + itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return 0; +} + +int nrppa_gNB_measurement_response(instance_t instance, MessageDef *msg_p) +{ + DevAssert(msg_p); + nrppa_measurement_resp_t *resp = &NRPPA_MEASUREMENT_RESP(msg_p); + nrppa_gNB_ue_context_t *ue_info = nrppa_detach_ue_context(resp->transaction_id); + + if (ue_info->gNB_ue_ngap_id != 0 && ue_info->amf_ue_ngap_id != 0) { + LOG_E(NRPPA, "Illegal gNB_ue_ngap_id %d and amf_ue_ngap_id %ld\n", ue_info->gNB_ue_ngap_id, ue_info->amf_ue_ngap_id); + free_measurement_resp(resp); + nrppa_free_ue_context(ue_info); + return -1; + } + + LOG_I(NRPPA, + "Received measurement response info from RRC with transaction_id %u and gNB_ue_ngap_id %u\n", + ue_info->transaction_id, + ue_info->gNB_ue_ngap_id); + + // Prepare NRPPA TRP Information transfer Response + NRPPA_NRPPA_PDU_t pdu = {0}; + + // IE: 9.2.3 Message Type : mandatory + pdu.present = NRPPA_NRPPA_PDU_PR_successfulOutcome; + asn1cCalloc(pdu.choice.successfulOutcome, head); + head->procedureCode = NRPPA_ProcedureCode_id_Measurement; + head->criticality = NRPPA_Criticality_reject; + head->value.present = NRPPA_SuccessfulOutcome__value_PR_MeasurementResponse; + + // IE 9.2.4 nrppatransactionID : mandatory + head->nrppatransactionID = resp->transaction_id; + NRPPA_MeasurementResponse_t *out = &head->value.choice.MeasurementResponse; + + // IE LMF Measurement ID : mandatory + { + asn1cSequenceAdd(out->protocolIEs.list, NRPPA_MeasurementResponse_IEs_t, ie); + ie->id = NRPPA_ProtocolIE_ID_id_LMF_Measurement_ID; + ie->criticality = NRPPA_Criticality_reject; + ie->value.present = NRPPA_MeasurementResponse_IEs__value_PR_Measurement_ID; + ie->value.choice.Measurement_ID = resp->lmf_measurement_id; + } + + // IE RAN Measurement ID : mandatory + { + asn1cSequenceAdd(out->protocolIEs.list, NRPPA_MeasurementResponse_IEs_t, ie); + ie->id = NRPPA_ProtocolIE_ID_id_RAN_Measurement_ID; + ie->criticality = NRPPA_Criticality_reject; + ie->value.present = NRPPA_MeasurementResponse_IEs__value_PR_Measurement_ID_1; + ie->value.choice.Measurement_ID_1 = resp->ran_measurement_id; + } + + // IE TRP Measurement Response List : mandatory + { + if (resp->measurement_response_list) { + asn1cSequenceAdd(out->protocolIEs.list, NRPPA_MeasurementResponse_IEs_t, ie); + ie->id = NRPPA_ProtocolIE_ID_id_TRP_MeasurementResponseList; + ie->criticality = NRPPA_Criticality_reject; + ie->value.present = NRPPA_MeasurementResponse_IEs__value_PR_TRP_MeasurementResponseList; + ie->value.choice.TRP_MeasurementResponseList = encode_trp_measurement_reponse_list(resp->measurement_response_list); + } + } + + free_measurement_resp(resp); + + LOG_I(NRPPA, "Calling encoder for Measurement Response \n"); + + if (LOG_DEBUGFLAG(DEBUG_ASN1)) { + xer_fprint(stdout, &asn_DEF_NRPPA_NRPPA_PDU, &pdu); + } + + // Encode NRPPA message + uint8_t *buffer = NULL; + uint32_t length = 0; + if (nrppa_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { + LOG_E(NRPPA, "Failed to encode Uplink NRPPa Measurement Response\n"); + nrppa_free_ue_context(ue_info); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NRPPA_NRPPA_PDU, &pdu); + return -1; + } + + MessageDef *msg = itti_alloc_new_message(TASK_NRPPA, 0, NGAP_UPLINKNONUEASSOCIATEDNRPPA); + ngap_uplink_non_ue_associated_nrppa_t *ULNRPPA = &NGAP_UPLINKNONUEASSOCIATEDNRPPA(msg); + + // Routing ID + ULNRPPA->routing_id = create_byte_array(ue_info->routing_id.len, ue_info->routing_id.buf); + + // NRPPa PDU + ULNRPPA->nrppa_pdu = create_byte_array(length, buffer); + + // Forward the NRPPA PDU to NGAP + itti_send_msg_to_task(TASK_NGAP, instance, msg); + nrppa_free_ue_context(ue_info); + free(buffer); + return length; +} diff --git a/openair3/NRPPA/nrppa_gNB_measurement_information_transfer.h b/openair3/NRPPA/nrppa_gNB_measurement_information_transfer.h new file mode 100644 index 0000000000..da03403f4d --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB_measurement_information_transfer.h @@ -0,0 +1,32 @@ +/* + * 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 NRPPA_GNB_MEASUREMENT_INFORMATION_TRANSFER_H_ +#define NRPPA_GNB_MEASUREMENT_INFORMATION_TRANSFER_H_ + +int nrppa_gNB_handle_measurement_request(nrppa_gnb_ue_info_t *nrppa_msg_info, const NRPPA_NRPPA_PDU_t *pdu); +void decode_srs_carrier_list(nrppa_srs_carrier_list_t *out_list, const NRPPA_SRSCarrier_List_t *in_list); +void free_measurement_request(nrppa_measurement_req_t *msg); +int nrppa_gNB_measurement_response(instance_t instance, MessageDef *msg_p); +NRPPA_TRP_MeasurementResponseList_t encode_trp_measurement_reponse_list(nrppa_measurement_response_list_t *in_list); +void free_measurement_resp(nrppa_measurement_resp_t *msg); + +#endif /* NRPPA_GNB_MEASUREMENT_INFORMATION_TRANSFER_H_ */ diff --git a/openair3/NRPPA/nrppa_gNB_ue_context.c b/openair3/NRPPA/nrppa_gNB_ue_context.c new file mode 100644 index 0000000000..b5da194205 --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB_ue_context.c @@ -0,0 +1,96 @@ +/* + * 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 "nrppa_gNB_ue_context.h" +#include "tree.h" +#include "T.h" +#include "common/utils/T/T.h" +#include "common/utils/utils.h" +#include "common/utils/LOG/log.h" + +static RB_HEAD(nrppa_ue_map, nrppa_gNB_ue_context_s) nrppa_ue_head = RB_INITIALIZER(&nrppa_ue_head); + +/* Generate the tree management functions prototypes */ +RB_PROTOTYPE(nrppa_ue_map, nrppa_gNB_ue_context_s, entries, nrppa_gNB_compare_transaction_id); + +static int nrppa_gNB_compare_transaction_id(struct nrppa_gNB_ue_context_s *p1, struct nrppa_gNB_ue_context_s *p2) +{ + if (p1->transaction_id > p2->transaction_id) { + return 1; + } + + if (p1->transaction_id < p2->transaction_id) { + return -1; + } + + return 0; +} + +/* Generate the tree management functions */ +RB_GENERATE(nrppa_ue_map, nrppa_gNB_ue_context_s, entries, nrppa_gNB_compare_transaction_id); + +void nrppa_store_ue_context(const nrppa_gnb_ue_info_t *info, const uint16_t transaction_id) +{ + LOG_I(NRPPA, "Create NRPPa UE context (gNB UE ID %u) for transaction ID : %u\n", info->gNB_ue_ngap_id, transaction_id); + nrppa_gNB_ue_context_t *ue_info_p = calloc_or_fail(1, sizeof(*ue_info_p)); + ue_info_p->transaction_id = transaction_id; + ue_info_p->gNB_ue_ngap_id = info->gNB_ue_ngap_id; + ue_info_p->amf_ue_ngap_id = info->amf_ue_ngap_id; + if (info->routing_id.len > 0 && info->routing_id.buf != NULL) { + ue_info_p->routing_id.len = info->routing_id.len; + ue_info_p->routing_id.buf = calloc_or_fail(1, info->routing_id.len); + memcpy(ue_info_p->routing_id.buf, info->routing_id.buf, info->routing_id.len); + } else { + ue_info_p->routing_id.len = 0; + ue_info_p->routing_id.buf = NULL; + } + if (RB_INSERT(nrppa_ue_map, &nrppa_ue_head, ue_info_p)) + LOG_E(NRPPA, "Bug in UE uniq number allocation %u, we try to add a existing UE\n", ue_info_p->gNB_ue_ngap_id); + return; +} + +struct nrppa_gNB_ue_context_s *nrppa_get_ue_context(uint16_t transaction_id) +{ + nrppa_gNB_ue_context_t temp = {.transaction_id = transaction_id}; + return RB_FIND(nrppa_ue_map, &nrppa_ue_head, &temp); +} + +struct nrppa_gNB_ue_context_s *nrppa_detach_ue_context(uint16_t transaction_id) +{ + struct nrppa_gNB_ue_context_s *tmp = nrppa_get_ue_context(transaction_id); + if (tmp == NULL) { + LOG_E(NRPPA, "Trying to free a NULL UE context, %u\n", transaction_id); + return NULL; + } + RB_REMOVE(nrppa_ue_map, &nrppa_ue_head, tmp); + return tmp; +} + +void nrppa_free_ue_context(nrppa_gNB_ue_context_t *ue_info) +{ + if (!ue_info) + return; + + if (ue_info->routing_id.buf) { + free(ue_info->routing_id.buf); + } + free(ue_info); +} diff --git a/openair3/NRPPA/nrppa_gNB_ue_context.h b/openair3/NRPPA/nrppa_gNB_ue_context.h new file mode 100644 index 0000000000..fc976c611d --- /dev/null +++ b/openair3/NRPPA/nrppa_gNB_ue_context.h @@ -0,0 +1,44 @@ +/* + * 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 "tree.h" +#include "ds/byte_array.h" +#include "nrppa_common.h" + +#ifndef NRPPA_GNB_UE_CONTEXT_H_ +#define NRPPA_GNB_UE_CONTEXT_H_ + +typedef struct nrppa_gNB_ue_context_s { + /* Tree related data */ + RB_ENTRY(nrppa_gNB_ue_context_s) entries; + uint16_t transaction_id; + uint32_t gNB_ue_ngap_id; + uint64_t amf_ue_ngap_id; + byte_array_t routing_id; +} nrppa_gNB_ue_context_t; + +void nrppa_store_ue_context(const nrppa_gnb_ue_info_t *info, const uint16_t transaction_id); +nrppa_gNB_ue_context_t *nrppa_get_ue_context(uint16_t transaction_id); +nrppa_gNB_ue_context_t *nrppa_detach_ue_context(uint16_t transaction_id); +void nrppa_free_ue_context(nrppa_gNB_ue_context_t *ue_info); + +#endif /* NRPPA_GNB_UE_CONTEXT_H_ */ diff --git a/openair3/NRPPA/nrppa_includes.h b/openair3/NRPPA/nrppa_includes.h new file mode 100644 index 0000000000..98e447d379 --- /dev/null +++ b/openair3/NRPPA/nrppa_includes.h @@ -0,0 +1,83 @@ +/* + * 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 NRPPA_INCLUDE_H_ +#define NRPPA_INCLUDE_H_ + +#include "NRPPA_NRPPA-PDU.h" +#include "NRPPA_InitiatingMessage.h" +#include "NRPPA_SuccessfulOutcome.h" +#include "NRPPA_UnsuccessfulOutcome.h" +#include "NRPPA_ProtocolIE-ID.h" +#include "NRPPA_ProtocolIE-Field.h" +#include "NRPPA_ProtocolIE-Container.h" +#include "NRPPA_ProtocolExtensionField.h" +#include "NRPPA_ProtocolIE-ContainerList.h" +#include "NRPPA_ProtocolExtensionContainer.h" +#include "NRPPA_ProtocolIE-Single-Container.h" +#include "NRPPA_asn_constant.h" +#include "NRPPA_TRPInformationRequest.h" +#include "NRPPA_TRPInformationItem.h" +#include "NRPPA_TRPPositionDirect.h" +#include "NRPPA_NG-RANAccessPointPosition.h" +#include "NRPPA_NGRANHighAccuracyAccessPointPosition.h" +#include "NRPPA_TRPPositionReferenced.h" +#include "NRPPA_RelativeGeodeticLocation.h" +#include "NRPPA_RelativeCartesianLocation.h" +#include "NRPPA_SRSCarrier-List-Item.h" +#include "NRPPA_SCS-SpecificCarrier.h" +#include "NRPPA_SRSConfig.h" +#include "NRPPA_SRSResource-List.h" +#include "NRPPA_SRSResource.h" +#include "NRPPA_ResourceType.h" +#include "NRPPA_ResourceTypePeriodic.h" +#include "NRPPA_ResourceTypeSemi-persistent.h" +#include "NRPPA_ResourceTypeAperiodic.h" +#include "NRPPA_PosSRSResource-List.h" +#include "NRPPA_ResourceTypePos.h" +#include "NRPPA_ResourceTypePeriodicPos.h" +#include "NRPPA_ResourceTypeSemi-persistentPos.h" +#include "NRPPA_ResourceTypeAperiodicPos.h" +#include "NRPPA_SRSResourceSet-List.h" +#include "NRPPA_SRSResourceSet.h" +#include "NRPPA_PosSRSResource-List.h" +#include "NRPPA_PosSRSResourceSet-Item.h" +#include "NRPPA_PosSRSResource-List.h" +#include "NRPPA_PosSRSResource-Item.h" +#include "NRPPA_ResourceSetTypePeriodic.h" +#include "NRPPA_ResourceSetTypeSemi-persistent.h" +#include "NRPPA_ResourceSetTypeAperiodic.h" +#include "NRPPA_PosSRSResourceSet-List.h" +#include "NRPPA_PosResourceSetTypePeriodic.h" +#include "NRPPA_PosResourceSetTypeSemi-persistent.h" +#include "NRPPA_PosResourceSetTypeAperiodic.h" +#include "NRPPA_SemipersistentSRS.h" +#include "NRPPA_AperiodicSRS.h" +#include "NRPPA_TRP-MeasurementRequestItem.h" +#include "NRPPA_TRPMeasurementQuantities-Item.h" +#include "NRPPA_TRPMeasurementQuantitiesList-Item.h" +#include "NRPPA_TRP-MeasurementResponseList.h" +#include "NRPPA_TRP-MeasurementResponseItem.h" +#include "NRPPA_TrpMeasurementResultItem.h" +#include "NRPPA_UL-RTOAMeasurement.h" +#include "NRPPA_GNB-RxTxTimeDiff.h" + +#endif /* NRPPA_INCLUDE_H_ */ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index cefa52d456..63d036a83c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1 +1,2 @@ add_subdirectory(nr-cuup) +add_subdirectory(nr-cu-nrppa) diff --git a/tests/nr-cu-nrppa/CMakeLists.txt b/tests/nr-cu-nrppa/CMakeLists.txt new file mode 100644 index 0000000000..b61b0dd920 --- /dev/null +++ b/tests/nr-cu-nrppa/CMakeLists.txt @@ -0,0 +1,11 @@ +add_executable(nr-cu-nrppa-test nr-cu-nrppa.c + ${OPENAIR2_DIR}/GNB_APP/gnb_config_common.c + ${OPENAIR2_DIR}/GNB_APP/gnb_config_ng.c) + +target_link_libraries(nr-cu-nrppa-test PRIVATE nr_nas nr_common lib_uicc usim_lib) +target_link_libraries(nr-cu-nrppa-test PRIVATE + CONFIG_LIB ITTI SCTP_CLIENT + f1ap ngap SECURITY + UTIL softmodem_common nrppa) +target_link_libraries(nr-cu-nrppa-test PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs) +add_dependencies(nr-cu-nrppa-test params_libconfig) diff --git a/tests/nr-cu-nrppa/README.md b/tests/nr-cu-nrppa/README.md new file mode 100644 index 0000000000..4ea780a20e --- /dev/null +++ b/tests/nr-cu-nrppa/README.md @@ -0,0 +1,81 @@ +This is a simple standalone tester for NRPPA and NGAP positioning messages. It connects to the AMF to perform NGAP and NRPPA encoding/decoding and validates the exchange of positioning data. + +[[_TOC_]] + +# Overview +From a schematic point of view, the tester and Core Network interaction looks like this: +``` + +-------+ +-------+ + | LMF |<--- HTTP POST---| User | + +-------+ +-------+ + | + | Nlmf + | + +-------+ + | AMF | + +-------+ + | + NGAP/NRPPA | + | + +-------+ + |tester | (nr-cu-nrppa-test) + +-------+ +``` +The tester is designed to validate the integration of NRPPA and NGAP messages required for 5G positioning (*3GPP 38.413 V16.0.0* and *3GPP 38.455 V16.7.1*). It acts as a simulated RAN node (like a CU) connecting to the 5G Core Network's AMF. + +The following messages are integrated and tested: +* **NGAP:** Uplink/Downlink UE Associated NRPPA Transport, Uplink/Downlink Non-UE Associated NRPPA Transport. +* **NRPPA:** TRP Information Request/Response, Positioning Information Request/Response, Positioning Activation Request/Response, Measurement Request/Response. + +A test scenario is fixed to these steps: +1. The 5G Core Network, specifically including the Location Management Function (LMF), is deployed via Docker. +2. The tester connects to the AMF and establishes the NGAP connection. +3. The user initiates a positioning procedure via a API call to the LMF. +4. The AMF and the tester exchange the required NGAP and NRPPA messages to determine location. + +# Usage +To run this test, you need to set up the Core Network and build the tester. + +**1. Core Network Deployment** + +Pull the required Docker images for the OAI 5G Core: + + docker pull oaisoftwarealliance/ims:latest + docker pull oaisoftwarealliance/oai-amf:develop + docker pull oaisoftwarealliance/oai-nrf:develop + docker pull oaisoftwarealliance/oai-smf:develop + docker pull oaisoftwarealliance/oai-udr:develop + docker pull oaisoftwarealliance/oai-upf:develop + docker pull oaisoftwarealliance/oai-udm:develop + docker pull oaisoftwarealliance/oai-ausf:develop + docker pull oaisoftwarealliance/oai-lmf:develop + +Deploy the network using the positioning compose file: + + cd doc/tutorial_resources/oai-cn5g + docker compose -f docker-compose-positioning.yaml up -d + +*(To undeploy later, run `docker compose -f docker-compose-positioning.yaml down -t 0`)* + +**2. Building the Tester** + +You can build the NRPPA tester like so: + + cd ~/openairinterface5g + mkdir build && cd build && cmake .. -GNinja && ninja nr-cu-nrppa-test + +**3. Running the Tester** + +Start the tester with the dedicated configuration file: + + LD_LIBRARY_PATH=. ./tests/nr-cu-nrppa/nr-cu-nrppa-test -O ../tests/nr-cu-nrppa/nr-nrppa-test.conf + +**4. Initiating the Procedure** + +Trigger the location determination by sending an HTTP POST request to the LMF: + + cd ~/openairinterface5g/doc/tutorial_resources/positioning/ + curl --http2-prior-knowledge -H "Content-Type: application/json" -d "@InputData.json" -X POST http://192.168.70.141:8080/nlmf-loc/v1/determine-location + +# Limitations +- The tester is a standalone validation tool (`nr-cu-nrppa-test`) and does not represent a fully integrated, end-to-end gNB positioning setup. diff --git a/tests/nr-cu-nrppa/nr-cu-nrppa.c b/tests/nr-cu-nrppa/nr-cu-nrppa.c new file mode 100644 index 0000000000..de784a3a16 --- /dev/null +++ b/tests/nr-cu-nrppa/nr-cu-nrppa.c @@ -0,0 +1,733 @@ +/* + * 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 "executables/softmodem-common.h" +#include "common/utils/ocp_itti/intertask_interface.h" +#include "common/ran_context.h" +#include "nfapi/oai_integration/vendor_ext.h" +#include "openair2/GNB_APP/gnb_config_common.h" +#include "openair2/GNB_APP/gnb_config_ng.h" +#include "openair2/GNB_APP/gnb_paramdef.h" +#include "openair3/SCTP/sctp_default_values.h" +#include "openair3/NRPPA/nrppa_gNB_config.h" +#include "openair3/NRPPA/nrppa_gNB.h" +#include "openair3/NAS/NR_UE/nr_nas_msg.h" +#include "executables/nr-uesoftmodem.h" +#include "openair3/NRPPA/nrppa_gNB_location_information_transfer.c" +#include "openair3/NRPPA/nrppa_gNB_measurement_information_transfer.h" + +RAN_CONTEXT_t RC; +THREAD_STRUCT thread_struct; +uint64_t downlink_frequency[MAX_NUM_CCs][4]; +int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; +int oai_exit = 0; +int gnb_id; +int NB_UE_INST = 1; + +void exit_function(const char *file, const char *function, const int line, const char *s, const int assert) +{ + if (assert) { + abort(); + } else { + sleep(1); // allow other threads to exit first + exit(EXIT_SUCCESS); + } +} + +nfapi_mode_t nfapi_mod = -1; +void nfapi_setmode(nfapi_mode_t nfapi_mode) +{ + nfapi_mod = nfapi_mode; +} +nfapi_mode_t nfapi_getmode(void) +{ + return nfapi_mod; +} + +ngran_node_t get_node_type() +{ + return ngran_gNB_CUUP; +} + +nrUE_params_t *get_nrUE_params(void) +{ + static nrUE_params_t params = {0}; + params.extra_pdu_id = -1; + return ¶ms; +} + +void create_ue_ip_if(void) +{ +} + +void create_ue_eth_if(void) +{ +} + +void set_qfi(void) +{ +} + +configmodule_interface_t *uniqCfg = NULL; + +static nrppa_trp_information_resp_t fill_trp_resp(uint8_t transaction_id) +{ + positioning_config_t positioning_config = RCconfig_nr_positioning(); + dump_positioning_config(&positioning_config); + nrppa_trp_information_resp_t resp = {0}; + resp.transaction_id = transaction_id; + + nrppa_trp_information_list_t *list = &resp.trp_information_list; + uint32_t trp_info_item_len = positioning_config.num_trp; + list->trp_information_item_length = trp_info_item_len; + list->trp_information_item = calloc_or_fail(trp_info_item_len, sizeof(*list->trp_information_item)); + + uint8_t resp_item_len = 3; + for (int i = 0; i < trp_info_item_len; i++) { + nrppa_trp_information_t *tRPInformation = &list->trp_information_item[i]; + tRPInformation->trp_id = positioning_config.trps[i].id; + nrppa_trp_information_type_response_list_t *resp_list = &tRPInformation->trp_information_type_response_list; + resp_list->trp_information_type_response_item_length = resp_item_len; + nrppa_trp_information_type_response_item_t *resp_item = calloc_or_fail(resp_item_len, sizeof(*resp_item)); + resp_list->trp_information_type_response_item = resp_item; + + // nrPCI + resp_item[0].present = NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_PCI_NR; + resp_item[0].choice.pci_nr = 123 + i; + + // nG_RAN_CGI + resp_item[1].present = NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_NG_RAN_CGI; + resp_item[1].choice.ng_ran_cgi.plmn.mcc = 001; + resp_item[1].choice.ng_ran_cgi.plmn.mnc = 01; + resp_item[1].choice.ng_ran_cgi.plmn.mnc_digit_length = 2; + resp_item[1].choice.ng_ran_cgi.nr_cellid = gnb_id << 8; // HACK: Made to work with lmf + + // geographicalCoordinates + resp_item[2].present = NRPPA_TRP_INFORMATION_TYPE_RESPONSE_ITEM_PR_GEOGRAPHICALCOORDINATES; + nrppa_geographical_coordinates_t *geographicalCoordinates = &resp_item[2].choice.geographical_coordinates; + nrppa_trp_position_definition_type_t *tRPPositionDefinitionType = &geographicalCoordinates->trp_position_definition_type; + // referenced + tRPPositionDefinitionType->present = NRPPA_TRP_POSITION_DEFINITION_TYPE_PR_REFERENCED; + nrppa_trp_position_referenced_t *referenced = &tRPPositionDefinitionType->choice.referenced; + // coordinate ID + referenced->reference_point.present = NRPPA_REFERENCE_POINT_PR_COORDINATEID; + referenced->reference_point.choice.coordinate_id = 2; + nrppa_trp_reference_point_type_t *referencePointType = &referenced->reference_point_type; + // relative cartesian + referencePointType->present = NRPPA_TRP_REFERENCE_POINT_TYPE_PR_TRPPOSITION_RELATIVE_CARTESIAN; + nrppa_relative_cartesian_location_t *trp_pos_cart = &referencePointType->choice.trp_position_relative_cartesian; + // 0 = millimeter + trp_pos_cart->xyz_unit = positioning_config.trps[i].unit; + + // random reference cartesian coordinates in millimeter + trp_pos_cart->xvalue = positioning_config.trps[i].x_axis; + trp_pos_cart->yvalue = positioning_config.trps[i].y_axis; + trp_pos_cart->zvalue = positioning_config.trps[i].z_axis; + // testing random values for uncertainity and confidence + trp_pos_cart->location_uncertainty.horizontal_uncertainty = i + 1; + trp_pos_cart->location_uncertainty.horizontal_confidence = i + 2; + trp_pos_cart->location_uncertainty.vertical_uncertainty = i + 3; + trp_pos_cart->location_uncertainty.vertical_confidence = i + 4; + } + return resp; +} + +static nrppa_positioning_information_resp_t fill_position_information_resp(uint16_t transaction_id) +{ + nrppa_positioning_information_resp_t resp = {0}; + resp.transaction_id = transaction_id; + resp.srs_configuration = calloc_or_fail(1, sizeof(*resp.srs_configuration)); + nrppa_srs_carrier_list_t *srs_carrier_list = &resp.srs_configuration->srs_carrier_list; + uint32_t srs_carrier_list_len = 2; + srs_carrier_list->srs_carrier_list_length = srs_carrier_list_len; + srs_carrier_list->srs_carrier_list_item = calloc_or_fail(srs_carrier_list_len, sizeof(*srs_carrier_list->srs_carrier_list_item)); + for (int i = 0; i < srs_carrier_list_len; i++) { + nrppa_srs_carrier_list_item_t *srs_carrier_list_item = &srs_carrier_list->srs_carrier_list_item[i]; + // pointA + srs_carrier_list_item->pointA = 87641 + i; + + // Uplink Channel BW-PerSCS-List + nrppa_uplink_channel_bw_per_scs_list_t *uplink_channel_bw_per_scs_list = &srs_carrier_list_item->uplink_channel_bw_per_scs_list; + + uint32_t scs_specific_carrier_list_length = 3; + uplink_channel_bw_per_scs_list->scs_specific_carrier_list_length = scs_specific_carrier_list_length; + uplink_channel_bw_per_scs_list->scs_specific_carrier = + calloc_or_fail(scs_specific_carrier_list_length, sizeof(*uplink_channel_bw_per_scs_list->scs_specific_carrier)); + for (int j = 0; j < scs_specific_carrier_list_length; j++) { + nrppa_scs_specific_carrier_t *scs_specific_carrier = &uplink_channel_bw_per_scs_list->scs_specific_carrier[j]; + // offset to carrier + scs_specific_carrier->offset_to_carrier = 100 + i + j; + // subcarrier spacing + scs_specific_carrier->subcarrier_spacing = NRPPA_SUBCARRIER_SPACING_30KHZ; + // carrier bandwidth + scs_specific_carrier->carrier_bandwidth = 106 + i + j; + } + + // Active UL BWP + nrppa_active_ul_bwp_t *active_ul_bwp = &srs_carrier_list_item->active_ul_bwp; + + // location and bandwidth + active_ul_bwp->location_and_bandwidth = 2775 + i; + // subcarrier spacing + active_ul_bwp->subcarrier_spacing = NRPPA_SUBCARRIER_SPACING_30KHZ; + // cyclic prefix + active_ul_bwp->cyclic_prefix = NRPPA_CP_TYPE_NORMAL; + // Tx Direct Current Location + active_ul_bwp->tx_direct_current_location = 10 + i; + + // SRS Config + nrppa_srs_config_t *sRSConfig = &active_ul_bwp->srs_config; + + // srs_resource_list + sRSConfig->srs_resource_list = calloc_or_fail(1, sizeof(*sRSConfig->srs_resource_list)); + nrppa_srs_resource_list_t *srs_resource_list = sRSConfig->srs_resource_list; + uint32_t srs_resource_list_length = 3; + srs_resource_list->srs_resource_list_length = srs_resource_list_length; + srs_resource_list->srs_resource = calloc_or_fail(srs_resource_list_length, sizeof(*srs_resource_list->srs_resource)); + + // SRS resource config 1 : periodic + nrppa_srs_resource_t *srs_resource = &srs_resource_list->srs_resource[0]; + srs_resource->srs_resource_id = 22; + srs_resource->nr_of_srs_ports = NRPPA_SRS_NUMBER_OF_PORTS_N2; + srs_resource->transmission_comb.present = NRPPA_TRANSMISSION_COMB_PR_N2; + srs_resource->transmission_comb.choice.n2.comb_offset_n2 = 1; + srs_resource->transmission_comb.choice.n2.cyclic_shift_n2 = 3; + srs_resource->start_position = 8; + srs_resource->nr_of_symbols = NRPPA_SRS_NUMBER_OF_SYMBOLS_N4; + srs_resource->repetition_factor = NRPPA_SRS_REPETITION_FACTOR_RF2; + srs_resource->freq_domain_position = 32; + srs_resource->freq_domain_shift = 108; + srs_resource->c_srs = 31; + srs_resource->b_srs = 1; + srs_resource->b_hop = 3; + srs_resource->group_or_sequence_hopping = NRPPA_GROUPORSEQUENCEHOPPING_GROUPHOPPING; + srs_resource->resource_type.present = NRPPA_RESOURCE_TYPE_PR_PERIODIC; + + nrppa_resource_type_periodic_t *periodic = &srs_resource->resource_type.choice.periodic; + periodic->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT16; + periodic->offset = 1000; + srs_resource->sequence_id = 18; + + // SRS resource config 2 : semi-persistent + srs_resource = &srs_resource_list->srs_resource[1]; + srs_resource->srs_resource_id = 24; + srs_resource->nr_of_srs_ports = NRPPA_SRS_NUMBER_OF_PORTS_N4; + srs_resource->transmission_comb.present = NRPPA_TRANSMISSION_COMB_PR_N4; + srs_resource->transmission_comb.choice.n2.comb_offset_n2 = 3; + srs_resource->transmission_comb.choice.n2.cyclic_shift_n2 = 5; + srs_resource->start_position = 8; + srs_resource->nr_of_symbols = NRPPA_SRS_NUMBER_OF_SYMBOLS_N2; + srs_resource->repetition_factor = NRPPA_SRS_REPETITION_FACTOR_RF2; + srs_resource->freq_domain_position = 32; + srs_resource->freq_domain_shift = 108; + srs_resource->c_srs = 31; + srs_resource->b_srs = 1; + srs_resource->b_hop = 3; + srs_resource->group_or_sequence_hopping = NRPPA_GROUPORSEQUENCEHOPPING_GROUPHOPPING; + srs_resource->resource_type.present = NRPPA_RESOURCE_TYPE_PR_SEMI_PERSISTENT; + + srs_resource->resource_type.present = NRPPA_RESOURCE_TYPE_PR_SEMI_PERSISTENT; + nrppa_resource_type_semi_persistent_t *semi_persistent = &srs_resource->resource_type.choice.semi_persistent; + semi_persistent->periodicity = NRPPA_SRS_RESOURCE_TYPE_PERIODICITY_SLOT40; + semi_persistent->offset = 1000; + srs_resource->sequence_id = 12; + + // SRS resource config 2 : aperiodic + srs_resource = &srs_resource_list->srs_resource[2]; + srs_resource->srs_resource_id = 26; + srs_resource->nr_of_srs_ports = NRPPA_SRS_NUMBER_OF_PORTS_N2; + srs_resource->transmission_comb.present = NRPPA_TRANSMISSION_COMB_PR_N2; + srs_resource->transmission_comb.choice.n2.comb_offset_n2 = 1; + srs_resource->transmission_comb.choice.n2.cyclic_shift_n2 = 3; + srs_resource->start_position = 8; + srs_resource->nr_of_symbols = NRPPA_SRS_NUMBER_OF_SYMBOLS_N4; + srs_resource->repetition_factor = NRPPA_SRS_REPETITION_FACTOR_RF2; + srs_resource->freq_domain_position = 32; + srs_resource->freq_domain_shift = 108; + srs_resource->c_srs = 31; + srs_resource->b_srs = 1; + srs_resource->b_hop = 3; + srs_resource->group_or_sequence_hopping = NRPPA_GROUPORSEQUENCEHOPPING_SEQUENCEHOPPING; + srs_resource->resource_type.present = NRPPA_RESOURCE_TYPE_PR_APERIODIC; + // set aperiodic = 0 to enable + srs_resource->resource_type.choice.aperiodic = 0; + srs_resource->sequence_id = 10; + + // optional: pos_srs_resource_list + sRSConfig->pos_srs_resource_list = calloc_or_fail(1, sizeof(*sRSConfig->pos_srs_resource_list)); + nrppa_pos_srs_resource_list_t *pos_srs_resource_list = sRSConfig->pos_srs_resource_list; + uint32_t pos_srs_resource_list_length = 3; + pos_srs_resource_list->pos_srs_resource_list_length = pos_srs_resource_list_length; + pos_srs_resource_list->pos_srs_resource_item = + calloc_or_fail(pos_srs_resource_list_length, sizeof(*pos_srs_resource_list->pos_srs_resource_item)); + + // periodic + nrppa_pos_srs_resource_item_t *pos_srs_resource = &pos_srs_resource_list->pos_srs_resource_item[0]; + pos_srs_resource->srs_pos_resource_id = 12; + pos_srs_resource->transmission_comb_pos.present = NRPPA_TRANSMISSION_COMB_POS_PR_N2; + pos_srs_resource->transmission_comb_pos.choice.n2.comb_offset_n2 = 1; + pos_srs_resource->transmission_comb_pos.choice.n2.cyclic_shift_n2 = 4; + pos_srs_resource->start_position = 9; + pos_srs_resource->nr_of_symbols = NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N8; + pos_srs_resource->freq_domain_shift = 100; + pos_srs_resource->c_srs = 20; + pos_srs_resource->group_or_sequence_hopping = NRPPA_GROUPORSEQUENCEHOPPING_GROUPHOPPING; + pos_srs_resource->resource_type_pos.present = NRPPA_RESOURCE_TYPE_POS_PR_PERIODIC; + pos_srs_resource->resource_type_pos.choice.periodic.periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT5; + pos_srs_resource->resource_type_pos.choice.periodic.offset = 10; + pos_srs_resource->sequence_id = 1; + + // semi-persistent + pos_srs_resource = &pos_srs_resource_list->pos_srs_resource_item[1]; + pos_srs_resource->srs_pos_resource_id = 13; + pos_srs_resource->transmission_comb_pos.present = NRPPA_TRANSMISSION_COMB_POS_PR_N4; + pos_srs_resource->transmission_comb_pos.choice.n4.comb_offset_n4 = 3; + pos_srs_resource->transmission_comb_pos.choice.n4.cyclic_shift_n4 = 5; + pos_srs_resource->start_position = 12; + pos_srs_resource->nr_of_symbols = NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N12; + pos_srs_resource->freq_domain_shift = 100; + pos_srs_resource->c_srs = 20; + pos_srs_resource->group_or_sequence_hopping = NRPPA_GROUPORSEQUENCEHOPPING_GROUPHOPPING; + pos_srs_resource->resource_type_pos.present = NRPPA_RESOURCE_TYPE_POS_PR_SEMI_PERSISTENT; + pos_srs_resource->resource_type_pos.choice.semi_persistent.periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT32; + pos_srs_resource->resource_type_pos.choice.semi_persistent.offset = 5; + pos_srs_resource->sequence_id = 2; + + // aperiodic + pos_srs_resource = &pos_srs_resource_list->pos_srs_resource_item[2]; + pos_srs_resource->srs_pos_resource_id = 14; + pos_srs_resource->transmission_comb_pos.present = NRPPA_TRANSMISSION_COMB_POS_PR_N8; + pos_srs_resource->transmission_comb_pos.choice.n8.comb_offset_n8 = 5; + pos_srs_resource->transmission_comb_pos.choice.n8.cyclic_shift_n8 = 2; + pos_srs_resource->start_position = 9; + pos_srs_resource->nr_of_symbols = NRPPA_SRS_RESOURCE_ITEM_NUMBER_OF_SYMBOLS_N4; + pos_srs_resource->freq_domain_shift = 100; + pos_srs_resource->c_srs = 20; + pos_srs_resource->group_or_sequence_hopping = NRPPA_GROUPORSEQUENCEHOPPING_SEQUENCEHOPPING; + pos_srs_resource->resource_type_pos.present = NRPPA_RESOURCE_TYPE_POS_PR_APERIODIC; + pos_srs_resource->resource_type_pos.choice.periodic.periodicity = NRPPA_SRS_RESOURCE_TYPE_POS_PERIODICITY_SLOT5; + pos_srs_resource->resource_type_pos.choice.aperiodic.slot_offset = 31; + pos_srs_resource->sequence_id = 3; + + // optional: srs_resource_set_list + sRSConfig->srs_resource_set_list = calloc_or_fail(1, sizeof(*sRSConfig->srs_resource_set_list)); + nrppa_srs_resource_set_list_t *srs_resource_set_list = sRSConfig->srs_resource_set_list; + uint32_t srs_resource_set_list_length = 3; + srs_resource_set_list->srs_resource_set_list_length = srs_resource_set_list_length; + srs_resource_set_list->srs_resource_set = + calloc_or_fail(srs_resource_set_list_length, sizeof(*srs_resource_set_list->srs_resource_set)); + + // periodic + nrppa_srs_resource_set_t *srs_resource_set = &srs_resource_set_list->srs_resource_set[0]; + srs_resource_set->srs_resource_set_id = 0; + uint8_t srs_resource_id_list_length = 5; + srs_resource_set->srs_resource_id_list.srs_resource_id_list_length = srs_resource_id_list_length; + srs_resource_set->srs_resource_id_list.srs_resource_id = + calloc_or_fail(srs_resource_id_list_length, sizeof(*srs_resource_set->srs_resource_id_list.srs_resource_id)); + for (int k = 0; k < srs_resource_id_list_length; k++) { + srs_resource_set->srs_resource_id_list.srs_resource_id[k] = k; + } + srs_resource_set->resource_set_type.present = NRPPA_RESOURCE_SET_TYPE_PR_PERIODIC; + // set periodic = 0 to enable + srs_resource_set->resource_set_type.choice.periodic = 0; + + // semi-persistent + srs_resource_set = &srs_resource_set_list->srs_resource_set[1]; + srs_resource_set->srs_resource_set_id = 1; + srs_resource_id_list_length = 5; + srs_resource_set->srs_resource_id_list.srs_resource_id_list_length = srs_resource_id_list_length; + srs_resource_set->srs_resource_id_list.srs_resource_id = + calloc_or_fail(srs_resource_id_list_length, sizeof(srs_resource_set->srs_resource_id_list.srs_resource_id)); + for (int k = 0; k < srs_resource_id_list_length; k++) { + srs_resource_set->srs_resource_id_list.srs_resource_id[k] = k; + } + srs_resource_set->resource_set_type.present = NRPPA_RESOURCE_SET_TYPE_PR_SEMI_PERSISTENT; + // set semi_persistent = 0 to enable + srs_resource_set->resource_set_type.choice.semi_persistent = 0; + + // aperiodic + srs_resource_set = &srs_resource_set_list->srs_resource_set[2]; + srs_resource_set->srs_resource_set_id = 2; + srs_resource_id_list_length = 5; + srs_resource_set->srs_resource_id_list.srs_resource_id_list_length = srs_resource_id_list_length; + srs_resource_set->srs_resource_id_list.srs_resource_id = + calloc_or_fail(srs_resource_id_list_length, sizeof(*srs_resource_set->srs_resource_id_list.srs_resource_id)); + for (int k = 0; k < srs_resource_id_list_length; k++) { + srs_resource_set->srs_resource_id_list.srs_resource_id[k] = k; + } + + srs_resource_set->resource_set_type.present = NRPPA_RESOURCE_SET_TYPE_PR_APERIODIC; + srs_resource_set->resource_set_type.choice.aperiodic.srs_resource_trigger = 2; + srs_resource_set->resource_set_type.choice.aperiodic.slot_offset = 20; + + // optional: pos_srs_resource_set_list + sRSConfig->pos_srs_resource_set_list = calloc_or_fail(1, sizeof(*sRSConfig->pos_srs_resource_set_list)); + nrppa_pos_srs_resource_set_list_t *pos_srs_resource_set_list = sRSConfig->pos_srs_resource_set_list; + uint32_t pos_srs_resource_set_list_length = 3; + pos_srs_resource_set_list->pos_srs_resource_set_list_length = pos_srs_resource_set_list_length; + pos_srs_resource_set_list->pos_srs_resource_set_item = + calloc_or_fail(pos_srs_resource_set_list_length, sizeof(*pos_srs_resource_set_list->pos_srs_resource_set_item)); + + // periodic + nrppa_pos_srs_resource_set_item_t *pos_srs_resource_set = &pos_srs_resource_set_list->pos_srs_resource_set_item[0]; + pos_srs_resource_set->pos_srs_resource_set_id = 0; + uint8_t pos_srs_resource_id_list_length = 5; + pos_srs_resource_set->pos_srs_resource_id_list.pos_srs_resource_id_list_length = pos_srs_resource_id_list_length; + pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id = + calloc_or_fail(pos_srs_resource_id_list_length, + sizeof(*pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id)); + for (int k = 0; k < pos_srs_resource_id_list_length; k++) { + pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id[k] = k; + } + pos_srs_resource_set->pos_resource_set_type.present = NRPPA_POS_RESOURCE_SET_TYPE_PR_PERIODIC; + // set periodic = 0 to enable + pos_srs_resource_set->pos_resource_set_type.choice.periodic = 0; + + // semi-persistent + pos_srs_resource_set = &pos_srs_resource_set_list->pos_srs_resource_set_item[1]; + pos_srs_resource_set->pos_srs_resource_set_id = 1; + pos_srs_resource_id_list_length = 5; + pos_srs_resource_set->pos_srs_resource_id_list.pos_srs_resource_id_list_length = pos_srs_resource_id_list_length; + pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id = + calloc_or_fail(pos_srs_resource_id_list_length, + sizeof(*pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id)); + for (int k = 0; k < pos_srs_resource_id_list_length; k++) { + pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id[k] = k; + } + pos_srs_resource_set->pos_resource_set_type.present = NRPPA_POS_RESOURCE_SET_TYPE_PR_SEMI_PERSISTENT; + // set semi_persistent = 0 to enable + pos_srs_resource_set->pos_resource_set_type.choice.semi_persistent = 0; + + // aperiodic + pos_srs_resource_set = &pos_srs_resource_set_list->pos_srs_resource_set_item[2]; + pos_srs_resource_set->pos_srs_resource_set_id = 2; + pos_srs_resource_id_list_length = 5; + pos_srs_resource_set->pos_srs_resource_id_list.pos_srs_resource_id_list_length = pos_srs_resource_id_list_length; + pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id = + calloc_or_fail(pos_srs_resource_id_list_length, + sizeof(*pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id)); + for (int k = 0; k < pos_srs_resource_id_list_length; k++) { + pos_srs_resource_set->pos_srs_resource_id_list.srs_pos_resource_id[k] = k; + } + pos_srs_resource_set->pos_resource_set_type.present = NRPPA_POS_RESOURCE_SET_TYPE_PR_APERIODIC; + pos_srs_resource_set->pos_resource_set_type.choice.srs_resource = 3; + } + return resp; +} + +static nrppa_measurement_resp_t fill_measurement_response(uint16_t transaction_id, uint32_t lmf_measurement_id) +{ + positioning_config_t positioning_config = RCconfig_nr_positioning(); + nrppa_measurement_resp_t resp = {0}; + resp.transaction_id = transaction_id; + resp.lmf_measurement_id = lmf_measurement_id; + resp.ran_measurement_id = 1; + resp.measurement_response_list = calloc_or_fail(1, sizeof(*resp.measurement_response_list)); + uint32_t meas_response_list_len = positioning_config.num_trp; + resp.measurement_response_list->measurement_response_list_length = meas_response_list_len; + resp.measurement_response_list->measurement_response_item = + calloc_or_fail(meas_response_list_len, sizeof(*resp.measurement_response_list->measurement_response_item)); + for (int i = 0; i < meas_response_list_len; i++) { + nrppa_measurement_response_item_t *meas_response_item = &resp.measurement_response_list->measurement_response_item[i]; + meas_response_item->trp_id = positioning_config.trps[i].id; + + nrppa_measurement_result_t *MeasurementResult = &meas_response_item->measurement_result; + uint32_t meas_result_length = 4; + MeasurementResult->measurement_result_item_length = meas_result_length; + MeasurementResult->measurement_result_item = + calloc_or_fail(meas_result_length, sizeof(*MeasurementResult->measurement_result_item)); + + // Angle of arrival + nrppa_measurement_result_item_t *measurement_result_item = &MeasurementResult->measurement_result_item[0]; + nrppa_measured_results_value_t *measuredResultsValue = &measurement_result_item->measured_results_value; + measuredResultsValue->present = NRPPA_MEASURED_RESULTS_VALUE_PR_UL_ANGLEOFARRIVAL; + nrppa_ul_aoa_t *uL_AngleOfArrival = &measuredResultsValue->choice.ul_angle_of_arrival; + uL_AngleOfArrival->azimuth_aoa = 700 + i; + uL_AngleOfArrival->zenith_aoa = calloc_or_fail(1, sizeof(*uL_AngleOfArrival->zenith_aoa)); + *uL_AngleOfArrival->zenith_aoa = 450 + i; + + nrppa_time_stamp_t *timeStamp = &measurement_result_item->time_stamp; + timeStamp->system_frame_number = 100; + timeStamp->slot_index.present = NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_30; + timeStamp->slot_index.choice.scs_30 = 15; + + // UL SRS RSRP + measurement_result_item = &MeasurementResult->measurement_result_item[1]; + measuredResultsValue = &measurement_result_item->measured_results_value; + measuredResultsValue->present = NRPPA_MEASURED_RESULTS_VALUE_PR_UL_SRS_RSRP; + measuredResultsValue->choice.ul_srs_rsrp = 100 + i; + + timeStamp = &measurement_result_item->time_stamp; + timeStamp->system_frame_number = 101; + timeStamp->slot_index.present = NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_15; + timeStamp->slot_index.choice.scs_15 = 8; + + // UL RToA + measurement_result_item = &MeasurementResult->measurement_result_item[2]; + measuredResultsValue = &measurement_result_item->measured_results_value; + measuredResultsValue->present = NRPPA_MEASURED_RESULTS_VALUE_PR_UL_RTOA; + nrppa_ul_rtoa_measurement_t *uL_RTOA = &measuredResultsValue->choice.ul_rtoa; + uL_RTOA->present = NRPPA_ULRTOAMEAS_PR_K1; + uL_RTOA->choice.k1 = 98500 + i; + + timeStamp = &measurement_result_item->time_stamp; + timeStamp->system_frame_number = 102; + timeStamp->slot_index.present = NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_60; + timeStamp->slot_index.choice.scs_60 = 31; + + // gNB RX-TX Time Diff + measurement_result_item = &MeasurementResult->measurement_result_item[3]; + measuredResultsValue = &measurement_result_item->measured_results_value; + measuredResultsValue->present = NRPPA_MEASURED_RESULTS_VALUE_PR_GNB_RXTXTIMEDIFF; + nrppa_gnb_rx_tx_time_diff_t *gNB_RxTxTimeDiff = &measuredResultsValue->choice.gnb_rx_tx_time_diff; + gNB_RxTxTimeDiff->present = NRPPA_GNBRXTXTIMEDIFFMEAS_PR_K3; + gNB_RxTxTimeDiff->choice.k3 = 98412 + i; + + timeStamp = &measurement_result_item->time_stamp; + timeStamp->system_frame_number = 103; + timeStamp->slot_index.present = NRPPA_TIME_STAMP_SLOT_INDEX_PR_SCS_120; + timeStamp->slot_index.choice.scs_120 = 70; + } + return resp; +} + +// Initializing UE NAS Context with simulated SIM data +nr_ue_nas_t *simulated_ue_nas = NULL; +void init_ue_nas_context(void) +{ + simulated_ue_nas = calloc_or_fail(1, sizeof(nr_ue_nas_t)); + simulated_ue_nas->UE_id = 1; + simulated_ue_nas->security_container = calloc_or_fail(1, sizeof(stream_security_container_t)); + // Allocation and simulation of UICC data + simulated_ue_nas->uicc = calloc_or_fail(1, sizeof(uicc_t)); + // IMSI : 001010000000001 + simulated_ue_nas->uicc->imsiStr = calloc_or_fail(1, 16 * sizeof(char)); + strcpy(simulated_ue_nas->uicc->imsiStr, "001010000000001"); + simulated_ue_nas->uicc->nmc_size = 2; + // DNN : oai + simulated_ue_nas->uicc->dnnStr = calloc_or_fail(1, 32 * sizeof(char)); + strcpy(simulated_ue_nas->uicc->dnnStr, "oai"); + // IMEISV : 6754567890123413 + simulated_ue_nas->uicc->imeisvStr = calloc_or_fail(1, 17 * sizeof(char)); + strcpy(simulated_ue_nas->uicc->imeisvStr, "6754567890123413"); + // NSSAI: sst = 1, sd = 0xffffff + simulated_ue_nas->uicc->nssai_sst = 1; + simulated_ue_nas->uicc->nssai_sd = 0xffffff; + // Ki: fec86ba6eb707ed08905757b1bb44b8f + static const uint8_t TEST_K[16] = + {0xfe, 0xc8, 0x6b, 0xa6, 0xeb, 0x70, 0x7e, 0xd0, 0x89, 0x05, 0x75, 0x7b, 0x1b, 0xb4, 0x4b, 0x8f}; + memcpy(simulated_ue_nas->uicc->key, TEST_K, 16); + // OPc: c42449363bbad02b66d16bc975d77cc1 + static const uint8_t TEST_OPC[16] = + {0xc4, 0x24, 0x49, 0x36, 0x3b, 0xba, 0xd0, 0x2b, 0x66, 0xd1, 0x6b, 0xc9, 0x75, 0xd7, 0x7c, 0xc1}; + memcpy(simulated_ue_nas->uicc->opc, TEST_OPC, 16); + simulated_ue_nas->security.nas_count_ul = 0; + simulated_ue_nas->security.nas_count_dl = 0; + simulated_ue_nas->fiveGMM_state = FGS_DEREGISTERED; +} + +// Emulate registration request to register UE in the AMF (required for positioning) +void send_initial_ue_message(instance_t instance) +{ + MessageDef *msg_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_NAS_FIRST_REQ); + + NGAP_NAS_FIRST_REQ(msg_p).gNB_ue_ngap_id = 1; // Simulated UE ID + + NGAP_NAS_FIRST_REQ(msg_p).plmn.mcc = 1; + NGAP_NAS_FIRST_REQ(msg_p).plmn.mnc = 1; + NGAP_NAS_FIRST_REQ(msg_p).plmn.mnc_digit_length = 2; + + NGAP_NAS_FIRST_REQ(msg_p).nr_cell_id = gnb_id; + + NGAP_NAS_FIRST_REQ(msg_p).establishment_cause = NGAP_RRC_CAUSE_MO_SIGNALLING; + + as_nas_info_t initialNasMsg = {0}; + generateRegistrationRequest(&initialNasMsg, simulated_ue_nas, false); + + NGAP_NAS_FIRST_REQ(msg_p).nas_pdu.buf = initialNasMsg.nas_data; + NGAP_NAS_FIRST_REQ(msg_p).nas_pdu.len = initialNasMsg.length; + + NGAP_NAS_FIRST_REQ(msg_p).ue_identity.presenceMask = 0; + + itti_send_msg_to_task(TASK_NGAP, instance, msg_p); +} + +void *gNB_app_task(void *args_p) +{ + MessageDef *msg_p = NULL; + const char *msg_name = NULL; + instance_t instance; + int result; + /* for no gcc warnings */ + (void)instance; + + itti_mark_task_ready(TASK_GNB_APP); + do { + // Wait for a message + itti_receive_msg(TASK_GNB_APP, &msg_p); + + msg_name = ITTI_MSG_NAME(msg_p); + instance = ITTI_MSG_DESTINATION_INSTANCE(msg_p); + + switch (ITTI_MSG_ID(msg_p)) { + case TERMINATE_MESSAGE: + LOG_W(GNB_APP, " *** Exiting GNB_APP thread\n"); + itti_exit_task(); + break; + + case NGAP_REGISTER_GNB_CNF: + LOG_I(GNB_APP, "[gNB %ld] Received %s: associated AMF %d\n", instance, msg_name, NGAP_REGISTER_GNB_CNF(msg_p).nb_amf); + send_initial_ue_message(instance); + break; + + default: + LOG_E(GNB_APP, "Received unexpected message %s\n", msg_name); + break; + } + result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), msg_p); + AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + } while (1); + + return NULL; +} + +void *rrc_gnb_task(void *args_p) +{ + MessageDef *msg_p; + MessageDef *msg_p_resp; + instance_t instance; + int result; + + itti_mark_task_ready(TASK_RRC_GNB); + LOG_I(NR_RRC, "Entering main loop of NR_RRC message task\n"); + + while (1) { + // Wait for a message + itti_receive_msg(TASK_RRC_GNB, &msg_p); + const char *msg_name_p = ITTI_MSG_NAME(msg_p); + instance = ITTI_MSG_DESTINATION_INSTANCE(msg_p); + LOG_D(NR_RRC, + "RRC GNB Task Received %s for instance %ld from task %s\n", + ITTI_MSG_NAME(msg_p), + ITTI_MSG_DESTINATION_INSTANCE(msg_p), + ITTI_MSG_ORIGIN_NAME(msg_p)); + switch (ITTI_MSG_ID(msg_p)) { + case TERMINATE_MESSAGE: + LOG_W(NR_RRC, " *** Exiting NR_RRC thread\n"); + itti_exit_task(); + break; + case NGAP_DOWNLINK_NAS: + LOG_I(NR_RRC, "Ignore NGAP_DOWNLINK_NAS: dont have to handle"); + ngap_downlink_nas_t *nas = &NGAP_DOWNLINK_NAS(msg_p); + if (nas->nas_pdu.buf) { + free(nas->nas_pdu.buf); + } + break; + case NRPPA_TRP_INFORMATION_REQ: + nrppa_trp_information_req_t *trp_req = &NRPPA_TRP_INFORMATION_REQ(msg_p); + LOG_I(NR_RRC, "Received NRPPA_TRP_INFORMATION_REQ transaction_id %d\n", trp_req->transaction_id); + msg_p_resp = itti_alloc_new_message(TASK_RRC_GNB, 0, NRPPA_TRP_INFORMATION_RESP); + NRPPA_TRP_INFORMATION_RESP(msg_p_resp) = fill_trp_resp(trp_req->transaction_id); + LOG_I(NR_RRC, "Sending NRPPA_TRP_INFORMATION_RESP to TASK_NRPPA\n"); + itti_send_msg_to_task(TASK_NRPPA, 0, msg_p_resp); + break; + case NRPPA_POSITIONING_INFORMATION_REQ: + nrppa_positioning_information_req_t *pos_req = &NRPPA_POSITIONING_INFORMATION_REQ(msg_p); + LOG_I(NR_RRC, "Received NRPPA_POSITIONING_INFORMATION_REQ transaction_id %d\n", pos_req->transaction_id); + msg_p_resp = itti_alloc_new_message(TASK_RRC_GNB, 0, NRPPA_POSITIONING_INFORMATION_RESP); + NRPPA_POSITIONING_INFORMATION_RESP(msg_p_resp) = fill_position_information_resp(pos_req->transaction_id); + LOG_I(NR_RRC, "Sending NRPPA_POSITIONING_INFORMATION_RESP to TASK_NRPPA\n"); + itti_send_msg_to_task(TASK_NRPPA, 0, msg_p_resp); + break; + case NRPPA_POSITIONING_ACTIVATION_REQ: + nrppa_positioning_activation_req_t *req = &NRPPA_POSITIONING_ACTIVATION_REQ(msg_p); + LOG_I(NR_RRC, "Received NRPPA_POSITIONING_ACTIVATION_REQ transaction_id %d\n", req->transaction_id); + msg_p_resp = itti_alloc_new_message(TASK_RRC_GNB, 0, NRPPA_POSITIONING_ACTIVATION_RESP); + NRPPA_POSITIONING_ACTIVATION_RESP(msg_p_resp).transaction_id = req->transaction_id; + LOG_I(NR_RRC, "Sending NRPPA_POSITIONING_ACTIVATION_RESP to TASK_NRPPA\n"); + itti_send_msg_to_task(TASK_NRPPA, 0, msg_p_resp); + free_positioning_activation_request(req); + break; + case NRPPA_MEASUREMENT_REQ: + nrppa_measurement_req_t *m_req = &NRPPA_MEASUREMENT_REQ(msg_p); + LOG_I(NR_RRC, "Received NRPPA_MEASUREMENT_REQ transaction_id %d\n", m_req->transaction_id); + msg_p_resp = itti_alloc_new_message(TASK_RRC_GNB, 0, NRPPA_MEASUREMENT_RESP); + NRPPA_MEASUREMENT_RESP(msg_p_resp) = fill_measurement_response(m_req->transaction_id, m_req->lmf_measurement_id); + LOG_I(NR_RRC, "Sending NRPPA_MEASUREMENT_RESP to TASK_NRPPA\n"); + itti_send_msg_to_task(TASK_NRPPA, 0, msg_p_resp); + free_measurement_request(m_req); + break; + default: + LOG_E(NR_RRC, "[gNB %ld] Received unexpected message %s\n", instance, msg_name_p); + break; + } + result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), msg_p); + AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + msg_p = NULL; + } +} + +int main(int argc, char **argv) +{ + // load the config file + if ((uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY)) == NULL) { + exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); + } + logInit(); + + init_ue_nas_context(); + + set_softmodem_sighandler(); + + // Initialize ITTI tasks + itti_init(TASK_MAX, tasks_info); + + int rc; + rc = itti_create_task(TASK_SCTP, sctp_eNB_task, NULL); + AssertFatal(rc >= 0, "Create task for SCTP failed\n"); + + rc = itti_create_task(TASK_NGAP, ngap_gNB_task, NULL); + AssertFatal(rc >= 0, "Create task for NGAP failed\n"); + + rc = itti_create_task(TASK_NRPPA, nrppa_gNB_task, NULL); + AssertFatal(rc >= 0, "Create task for NRPPA failed\n"); + + rc = itti_create_task(TASK_RRC_GNB, rrc_gnb_task, NULL); + AssertFatal(rc >= 0, "Create task for RRC failed\n"); + + rc = itti_create_task(TASK_GNB_APP, gNB_app_task, NULL); + AssertFatal(rc >= 0, "Create task for RRC failed\n"); + + MessageDef *msg_p; + msg_p = itti_alloc_new_message(TASK_GNB_APP, 0, NGAP_REGISTER_GNB_REQ); + RCconfig_NR_NG(msg_p, 0); + gnb_id = NGAP_REGISTER_GNB_REQ(msg_p).gNB_id; + + LOG_I(GNB_APP, "Sending NGAP_REGISTER_GNB_REQ to TASK_NGAP\n"); + itti_send_msg_to_task(TASK_NGAP, 0, msg_p); + + printf("TYPE TO TERMINATE\n"); + itti_wait_tasks_end(NULL); + + logClean(); + printf("Bye.\n"); + return 0; +} diff --git a/tests/nr-cu-nrppa/nr-nrppa-test.conf b/tests/nr-cu-nrppa/nr-nrppa-test.conf new file mode 100644 index 0000000000..aaaa45f176 --- /dev/null +++ b/tests/nr-cu-nrppa/nr-nrppa-test.conf @@ -0,0 +1,73 @@ +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 = 01; mnc_length = 2; snssaiList = ({ sst = 1; }) }); + + nr_cellid = 12345678L; + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// AMF parameters: + amf_ip_address = ({ ipv4 = "192.168.70.132"; }); + + + NETWORK_INTERFACES : + { + GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.70.129/24"; + GNB_IPV4_ADDRESS_FOR_NGU = "192.168.70.129/24"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + } +); + +positioning_config = ( + { + NumTRPs = 4; # number of TRPs + TRPIDs = [1,2,3,4]; # userdefined distinct IDs + TRPxAxis = [71,21,10,45]; # X-axis value of each TRP + TRPyAxis = [11,22,62,14]; # Y-axis value of each TRP + TRPzAxis = [41,22,33,42]; # Z-axis value of each TRP + Units = [0, 0, 0, 0]; # 0 = mm, 1 = cm, 2 = dm + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + prach_dtx_threshold = 120; + pucch0_dtx_threshold = 150; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 + } +); + +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"; +};