diff --git a/.gitignore b/.gitignore index ff947966a2..b2913b82ae 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,8 @@ GPATH GRTAGS GTAGS tags + +# others +nfapi_nr_interface_scf +*.log +*.out diff --git a/.vscode/launch.json b/.vscode/launch.json index 4b563febde..8be6915763 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,14 +8,17 @@ "name": "(gdb) Launch", "type": "cppdbg", "request": "launch", - "program": "enter program name, for example ${workspaceFolder}/a.exe", - "args": [], + "program": "${workspaceFolder}/cmake_targets/ran_build/build/lte-softmodem", + "args": [ + "-O", "../ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf", + "--noS1" + ], "stopAtEntry": false, - "cwd": "${workspaceFolder}", + "cwd": "${workspaceFolder}/cmake_targets", "environment": [], "externalConsole": false, "MIMode": "gdb", - "miDebuggerPath": "/path/to/gdb", + "miDebuggerPath": "${workspaceFolder}/cmake_targets/sudo-gdb", "setupCommands": [ { "description": "Enable pretty-printing for gdb", diff --git a/README.md b/README.md index 62f8576e81..4f38f77e4e 100644 --- a/README.md +++ b/README.md @@ -21,16 +21,28 @@ # OpenAirInterface License # -OpenAirInterface is under OpenAirInterface Software Alliance license. +### Included Fixes: ### +- Ease of use of gprof and address sanitizer for debugging purposes +- Updated json files to allow for GDB, real-time debugging capabilities +- Updated logging features to minimally log only key connection milestones. This imroves scalability of multiple UEs. +- Updated logging to include time stamp for timing analysis +- Updated memory allocation procedures to correct size requirements +- Added debugging features to handle signal terminations +- nfapi.c pullarray8 fix invalid pointer math +- Overlapping destination and source memory in memcpy, so updated to memmove to check for this bug +- Advanced error checking mechanisms in critical pack and unpack functions +- Created option for CPU assignment to UE to improve scalability +- Added EPC integration to allow multiple individual UE entities to each have their USIM information parced by the executables +- Updated random value seeds to minimize probability of error in generation of random values +- Enables capability round robin scheduler if desired +- Enables capability real time scheduler if desired +- Added new standalone functions to the UE phy-layer (phy_stub_ue.c) to incorporate individual UE entities +- Updated sending and packing functions in UE (lte_ue.c) to incorporate new standalone changes +- Incorporated semaphores to control timing of incoming downlink packets +- Implemented new queuing system to handle message exchange from UE to eNB and vice versa +- Updated global value in nFAPI for size of subframe +- Updated global value to increase scalability in system - * [OAI License Model](http://www.openairinterface.org/?page_id=101) - * [OAI License v1.1 on our website](http://www.openairinterface.org/?page_id=698) - -It is distributed under **OAI Public License V1.1**. - -The license information is distributed under [LICENSE](LICENSE) file in the same directory. - -Please see [NOTICE](NOTICE.md) file for third party software that is included in the sources. # Where to Start # diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index a0284edb71..c55fa766cc 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -404,26 +404,6 @@ pipeline { } } } - stage ("Test L2 simulator") { - when { - expression {doFullTestsuite} - } - steps { - lock (vmResource) { - script { - timeout (time: 30, unit: 'MINUTES') { - try { - gitlabCommitStatus(name: "Test L2-sim") { - sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant l2-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}" - } - } catch (Exception e) { - currentBuild.result = 'FAILURE' - } - } - } - } - } - } stage ("Destroy all Virtual Machines") { when { expression {doMandatoryTests} diff --git a/ci-scripts/conf_files/episci/episci_gnb.band78.sa.fr1.106PRB.usrpn310.conf b/ci-scripts/conf_files/episci/episci_gnb.band78.sa.fr1.106PRB.usrpn310.conf new file mode 100644 index 0000000000..01add06e3a --- /dev/null +++ b/ci-scripts/conf_files/episci/episci_gnb.band78.sa.fr1.106PRB.usrpn310.conf @@ -0,0 +1,325 @@ +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 = 40960; + plmn_list = ({ + mcc = 208; + mnc = 95; + mnc_length = 2; + snssaiList = ( + { + sst = 1; + sd = 0x1; // 0 false, else true + }, + { + sst = 1; + sd = 0x112233; // 0 false, else true + } + ); + + }); + + nr_cellid = 12345678L; + + ////////// Physical parameters: + + ssb_SubcarrierOffset = 0; + pdsch_AntennaPorts = 1; + pusch_AntennaPorts = 1; + ul_prbblacklist = "51,52,53,54" + min_rxtxtime_pdsch = 6; + pdcch_ConfigSIB1 = ( + { + controlResourceSetZero = 12; + searchSpaceZero = 0; + } + ); + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 641280; + dl_frequencyBand = 78; + # this is 3600 MHz + dl_absoluteFrequencyPointA = 640008; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 106; + #initialDownlinkBWP + #genericParameters + # this is RBstart=27,L=48 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 12952; # 6366 12925 12956 28875 12952 +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; + #pdsch-ConfigCommon + #pdschTimeDomainAllocationList (up to 16 entries) + initialDLBWPk0_0 = 0; #for DL slot + initialDLBWPmappingType_0 = 0; #0=typeA,1=typeB + initialDLBWPstartSymbolAndLength_0 = 40; #this is SS=1,L=13 + + initialDLBWPk0_1 = 0; #for mixed slot + initialDLBWPmappingType_1 = 0; + initialDLBWPstartSymbolAndLength_1 = 57; #this is SS=1,L=5 + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 106; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 12952; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -96; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + + # pusch-ConfigCommon (up to 16 elements) + initialULBWPk2_0 = 6; # used for UL slot + initialULBWPmappingType_0 = 1 + initialULBWPstartSymbolAndLength_0 = 41; # this is SS=0 L=13 + + initialULBWPk2_1 = 6; # used for mixed slot + initialULBWPmappingType_1 = 1; + initialULBWPstartSymbolAndLength_1 = 52; # this is SS=10 L=4 + + initialULBWPk2_2 = 7; # used for Msg.3 during RA + initialULBWPmappingType_2 = 1; + initialULBWPstartSymbolAndLength_2 = 52; # this is SS=10 L=4 + + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; +# ssb_PositionsInBurs_BitmapPR +# 1=short, 2=medium, 3=long + ssb_PositionsInBurst_PR = 2; + ssb_PositionsInBurst_Bitmap = 1; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 1; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = -25; + } + + ); + + + # ------- 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"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + + NETWORK_INTERFACES : + { + GNB_INTERFACE_NAME_FOR_NG_AMF = "ctrl0"; + GNB_IPV4_ADDRESS_FOR_NG_AMF = "172.16.0.1"; + GNB_INTERFACE_NAME_FOR_NGU = "ctrl0"; + GNB_IPV4_ADDRESS_FOR_NGU = "172.16.0.1"; + GNB_PORT_FOR_NGU = 2152; # Spec 2152 + }; + + } +); + +MACRLCs = ( + { + num_cc = 1; + local_s_if_name = "lo:"; + remote_s_address = "127.0.0.1"; // pnf addr [!] + local_s_address = "127.0.0.2"; // vnf addr + local_s_portc = 50601; // vnf p5 port + remote_s_portc = 50600; // pnf p5 port [!] + local_s_portd = 50611; // vnf p7 port [!] + remote_s_portd = 50610; // pnf p7 port [!] + tr_s_preference = "nfapi"; + tr_n_preference = "local_RRC"; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + pusch_proc_threads = 8; + prach_dtx_threshold = 120; + pucch0_dtx_threshold = 150; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [78]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 75; + eNB_instances = [0]; + #beamforming 1x4 matrix: + bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; + #clock_src = "external"; + sdr_addrs = "mgmt_addr=192.168.18.240,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=internal" + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_SINGLE_THREAD"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + +rfsimulator : +{ + serveraddr = "server"; + serverport = "4043"; + options = (); #("saviq"); or/and "chanmod" + modelname = "AWGN"; + IQfile = "/tmp/rfsimulator.iqs"; +}; + +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"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + ngap_log_level ="debug"; + ngap_log_verbosity ="medium"; + }; + diff --git a/ci-scripts/conf_files/episci/episci_nr-ue.nfapi.conf b/ci-scripts/conf_files/episci/episci_nr-ue.nfapi.conf new file mode 100644 index 0000000000..f5563ecc02 --- /dev/null +++ b/ci-scripts/conf_files/episci/episci_nr-ue.nfapi.conf @@ -0,0 +1,52 @@ +log_config = { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="medium"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="full"; +}; + +uicc0 = { +imsi = "208950000000031"; +key = "0c0a34601d4f07677303652c0462535b"; +opc= "63bfa50ee6523365ff14c1f45f88737d"; +dnn= "oai"; +nssai_sst=222; +nssai_sd=123; +} + +L1s = ( + { + num_cc = 1; + tr_n_preference = "nfapi"; + local_n_if_name = "ens3"; + remote_n_address = "127.0.0.1"; //Proxy IP + local_n_address = "127.0.0.1"; + local_n_portc = 50600; + remote_n_portc = 50601; + local_n_portd = 50610; + remote_n_portd = 50611; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 90 + att_rx = 0; + bands = [7,38,42,43]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 125; + } +); diff --git a/ci-scripts/conf_files/episci/episci_nr-ue0.nfapi.conf b/ci-scripts/conf_files/episci/episci_nr-ue0.nfapi.conf new file mode 100644 index 0000000000..f5563ecc02 --- /dev/null +++ b/ci-scripts/conf_files/episci/episci_nr-ue0.nfapi.conf @@ -0,0 +1,52 @@ +log_config = { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="medium"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="full"; +}; + +uicc0 = { +imsi = "208950000000031"; +key = "0c0a34601d4f07677303652c0462535b"; +opc= "63bfa50ee6523365ff14c1f45f88737d"; +dnn= "oai"; +nssai_sst=222; +nssai_sd=123; +} + +L1s = ( + { + num_cc = 1; + tr_n_preference = "nfapi"; + local_n_if_name = "ens3"; + remote_n_address = "127.0.0.1"; //Proxy IP + local_n_address = "127.0.0.1"; + local_n_portc = 50600; + remote_n_portc = 50601; + local_n_portd = 50610; + remote_n_portd = 50611; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 90 + att_rx = 0; + bands = [7,38,42,43]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 125; + } +); diff --git a/ci-scripts/conf_files/episci/episci_nr-ue1.nfapi.conf b/ci-scripts/conf_files/episci/episci_nr-ue1.nfapi.conf new file mode 100644 index 0000000000..5df3ccf6cc --- /dev/null +++ b/ci-scripts/conf_files/episci/episci_nr-ue1.nfapi.conf @@ -0,0 +1,52 @@ +log_config = { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="medium"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="full"; +}; + +uicc0 = { +imsi = "208950000000032"; +key = "0c0a34601d4f07677303652c0462535b"; +opc= "63bfa50ee6523365ff14c1f45f88737d"; +dnn= "oai"; +nssai_sst=222; +nssai_sd=123; +} + +L1s = ( + { + num_cc = 1; + tr_n_preference = "nfapi"; + local_n_if_name = "ens3"; + remote_n_address = "127.0.0.1"; //Proxy IP + local_n_address = "127.0.0.1"; + local_n_portc = 50600; + remote_n_portc = 50601; + local_n_portd = 50610; + remote_n_portd = 50611; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 90 + att_rx = 0; + bands = [7,38,42,43]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 125; + } +); diff --git a/ci-scripts/conf_files/episci/episci_nr-ue2.nfapi.conf b/ci-scripts/conf_files/episci/episci_nr-ue2.nfapi.conf new file mode 100644 index 0000000000..b1ce5fee8d --- /dev/null +++ b/ci-scripts/conf_files/episci/episci_nr-ue2.nfapi.conf @@ -0,0 +1,52 @@ +log_config = { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="medium"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="full"; +}; + +uicc0 = { +imsi = "208950000000033"; +key = "0c0a34601d4f07677303652c0462535b"; +opc= "63bfa50ee6523365ff14c1f45f88737d"; +dnn= "oai"; +nssai_sst=222; +nssai_sd=123; +} + +L1s = ( + { + num_cc = 1; + tr_n_preference = "nfapi"; + local_n_if_name = "ens3"; + remote_n_address = "127.0.0.1"; //Proxy IP + local_n_address = "127.0.0.1"; + local_n_portc = 50600; + remote_n_portc = 50601; + local_n_portd = 50610; + remote_n_portd = 50611; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 90 + att_rx = 0; + bands = [7,38,42,43]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 125; + } +); diff --git a/ci-scripts/conf_files/episci/episci_nr-ue3.nfapi.conf b/ci-scripts/conf_files/episci/episci_nr-ue3.nfapi.conf new file mode 100644 index 0000000000..aea5104f1c --- /dev/null +++ b/ci-scripts/conf_files/episci/episci_nr-ue3.nfapi.conf @@ -0,0 +1,52 @@ +log_config = { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="medium"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="full"; +}; + +uicc0 = { +imsi = "208950000000034"; +key = "0c0a34601d4f07677303652c0462535b"; +opc= "63bfa50ee6523365ff14c1f45f88737d"; +dnn= "oai"; +nssai_sst=222; +nssai_sd=123; +} + +L1s = ( + { + num_cc = 1; + tr_n_preference = "nfapi"; + local_n_if_name = "ens3"; + remote_n_address = "127.0.0.1"; //Proxy IP + local_n_address = "127.0.0.1"; + local_n_portc = 50600; + remote_n_portc = 50601; + local_n_portd = 50610; + remote_n_portd = 50611; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 90 + att_rx = 0; + bands = [7,38,42,43]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 125; + } +); diff --git a/ci-scripts/conf_files/episci/episci_rcc.band7.tm1.nfapi.conf b/ci-scripts/conf_files/episci/episci_rcc.band7.tm1.nfapi.conf new file mode 100644 index 0000000000..4e596f81b5 --- /dev/null +++ b/ci-scripts/conf_files/episci/episci_rcc.band7.tm1.nfapi.conf @@ -0,0 +1,247 @@ +Active_eNBs = ( "eNB-Eurecom-LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB-Eurecom-LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 5; + + plmn_list = ( { mcc = 320; mnc = 230; mnc_length = 3; } ); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "3GPP_eNODEB"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2685000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 50; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + pbch_repetition = "FALSE"; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 0; + pucch_nCS_AN = 0; + pucch_n1_AN = 0; + pdsch_referenceSignalPower = -27; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + + //Parameters for SIB18 + rxPool_sc_CP_Len = "normal"; + rxPool_sc_Period = "sf40"; + rxPool_data_CP_Len = "normal"; + rxPool_ResourceConfig_prb_Num = 20; + rxPool_ResourceConfig_prb_Start = 5; + rxPool_ResourceConfig_prb_End = 44; + rxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + rxPool_ResourceConfig_offsetIndicator_choice = 0; + rxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; +/* rxPool_dataHoppingConfig_hoppingParameter = 0; + rxPool_dataHoppingConfig_numSubbands = "ns1"; + rxPool_dataHoppingConfig_rbOffset = 0; + rxPool_commTxResourceUC-ReqAllowed = "TRUE"; +*/ + // Parameters for SIB19 + discRxPool_cp_Len = "normal" + discRxPool_discPeriod = "rf32" + discRxPool_numRetx = 1; + discRxPool_numRepetition = 2; + discRxPool_ResourceConfig_prb_Num = 5; + discRxPool_ResourceConfig_prb_Start = 3; + discRxPool_ResourceConfig_prb_End = 21; + discRxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + discRxPool_ResourceConfig_offsetIndicator_choice = 0; + discRxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.61.195"; + ipv6 = "192:168:30::17"; + port = 36412 ; + active = "yes"; + preference = "ipv4"; + } + ); + + enable_measurement_reports = "yes"; + + ///X2 + enable_x2 = "yes"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "ctrl0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "172.16.0.1"; + ENB_INTERFACE_NAME_FOR_S1U = "ctrl0"; + ENB_IPV4_ADDRESS_FOR_S1U = "172.16.0.1"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + ENB_IPV4_ADDRESS_FOR_X2C = "172.16.0.1"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 + + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + local_s_if_name = "lo"; + remote_s_address = "127.0.0.1"; + local_s_address = "127.0.0.1"; + local_s_portc = 50001; + remote_s_portc = 50000; + local_s_portd = 50011; + remote_s_portd = 50010; + tr_s_preference = "nfapi"; + tr_n_preference = "local_RRC"; + scheduler_mode = "fairRR"; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + +log_config = + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; diff --git a/ci-scripts/conf_files/episci/episci_rcc.band78.tm1.106PRB.nfapi.conf b/ci-scripts/conf_files/episci/episci_rcc.band78.tm1.106PRB.nfapi.conf new file mode 100644 index 0000000000..b64b88ddea --- /dev/null +++ b/ci-scripts/conf_files/episci/episci_rcc.band78.tm1.106PRB.nfapi.conf @@ -0,0 +1,265 @@ +Active_gNBs = ( "gNB-Eurecom-5GNRBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + + cell_type = "CELL_MACRO_GNB"; + + gNB_name = "gNB-Eurecom-5GNRBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 5; + + plmn_list = ({mcc = 320; mnc = 230; mnc_length = 3;}); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + ssb_SubcarrierOffset = 31; //0; + pdsch_AntennaPorts = 1; + pusch_AntennaPorts = 1; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3600 MHz + 84 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 641272; //641032; #641968; 641968=start of ssb at 3600MHz + 82 RBs 641032=center of SSB at center of cell + dl_frequencyBand = 78; + # this is 3600 MHz + dl_absoluteFrequencyPointA = 640000; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 106; + #initialDownlinkBWP + #genericParameters + # this is RBstart=84,L=13 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 6368; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 0; + initialDLBWPsearchSpaceZero = 0; + #pdsch-ConfigCommon + #pdschTimeDomainAllocationList (up to 16 entries) + initialDLBWPk0_0 = 0; #for DL slot + initialDLBWPmappingType_0 = 0; #0=typeA,1=typeB + initialDLBWPstartSymbolAndLength_0 = 40; #this is SS=1,L=13 + + initialDLBWPk0_1 = 0; #for mixed slot + initialDLBWPmappingType_1 = 0; + initialDLBWPstartSymbolAndLength_1 = 57; #this is SS=1,L=5 + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 106; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 6368; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -100; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 5; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14; //15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, + +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + # pusch-ConfigCommon (up to 16 elements) + initialULBWPk2_0 = 6; # used for UL slot + initialULBWPmappingType_0 = 1 + initialULBWPstartSymbolAndLength_0 = 41; # this is SS=0 L=13 + + initialULBWPk2_1 = 6; # used for mixed slot + initialULBWPmappingType_1 = 1; + initialULBWPstartSymbolAndLength_1 = 52; # this is SS=10 L=4 + + initialULBWPk2_2 = 7; # used for Msg.3 during RA + initialULBWPmappingType_2 = 1; + initialULBWPstartSymbolAndLength_2 = 52; # this is SS=10 L=4 + + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; +# ssb_PositionsInBurs_BitmapPR +# 1=short, 2=medium, 3=long + ssb_PositionsInBurst_PR = 2; + ssb_PositionsInBurst_Bitmap = 1; #0x80; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 1; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; //8; //7; + nrofDownlinkSymbols = 6; //0; //6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; //0; //4; + + ssPBCH_BlockPower = -25; + } + + ); + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.61.195"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + ///X2 + enable_x2 = "yes"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ + target_enb_x2_ip_address = ( + { ipv4 = "172.16.0.1"; # rrc.band7.tm1.nfapi.conf:line 201 + ipv6 = "192:168:30::17"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { # All of these have to be IP addr of gNB + # if in CORE container, make it 172.16.0.X + # if not launched in CORE, can set to lo (127.0.0.2) + GNB_INTERFACE_NAME_FOR_S1_MME = "ctrl0"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "172.16.0.2"; + GNB_INTERFACE_NAME_FOR_S1U = "ctrl0"; + GNB_IPV4_ADDRESS_FOR_S1U = "172.16.0.2"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + GNB_IPV4_ADDRESS_FOR_X2C = "172.16.0.2"; + GNB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + } +); + + +MACRLCs = ( + { + num_cc = 1; + local_s_if_name = "lo:"; + remote_s_address = "127.0.0.1"; // pnf addr [!] + local_s_address = "127.0.0.2"; // vnf addr + local_s_portc = 50601; // vnf p5 port + remote_s_portc = 50600; // pnf p5 port [!] + local_s_portd = 50611; // vnf p7 port [!] + remote_s_portd = 50610; // pnf p7 port [!] + tr_s_preference = "nfapi"; + tr_n_preference = "local_RRC"; + } +) + + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + +log_config = + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + diff --git a/ci-scripts/conf_files/episci/episci_ue.nfapi.conf b/ci-scripts/conf_files/episci/episci_ue.nfapi.conf new file mode 100644 index 0000000000..0170a46655 --- /dev/null +++ b/ci-scripts/conf_files/episci/episci_ue.nfapi.conf @@ -0,0 +1,44 @@ +log_config = { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="medium"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="full"; +}; + + +L1s = ( + { + num_cc = 1; + tr_n_preference = "nfapi"; + local_n_if_name = "ens3"; + remote_n_address = "127.0.0.1"; //Proxy IP + local_n_address = "127.0.0.1"; + local_n_portc = 50000; + remote_n_portc = 50001; + local_n_portd = 50010; + remote_n_portd = 50011; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 90 + att_rx = 0; + bands = [7,38,42,43]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 125; + } +); diff --git a/ci-scripts/conf_files/episci/episci_ue_test_sfr.conf b/ci-scripts/conf_files/episci/episci_ue_test_sfr.conf new file mode 100644 index 0000000000..e98e1b92f1 --- /dev/null +++ b/ci-scripts/conf_files/episci/episci_ue_test_sfr.conf @@ -0,0 +1,786 @@ +# List of known PLMNS +PLMN: { + PLMN0: { + FULLNAME="Test network"; + SHORTNAME="OAI4G"; + MNC="01"; + MCC="001"; + + }; + PLMN1: { + FULLNAME="SFR France"; + SHORTNAME="SFR"; + MNC="10"; + MCC="208"; + + }; + PLMN2: { + FULLNAME="SFR France"; + SHORTNAME="SFR"; + MNC="11"; + MCC="208"; + }; + PLMN3: { + FULLNAME="SFR France"; + SHORTNAME="SFR"; + MNC="13"; + MCC="208"; + }; + PLMN4: { + FULLNAME="OAI LTEBOX"; + SHORTNAME="OAIALU"; + MNC="95"; + MCC="208"; + }; + PLMN5: { + FULLNAME="T-Mobile USA"; + SHORTNAME="T-Mobile"; + MNC="280"; + MCC="310"; + }; + PLMN6: { + FULLNAME="FICTITIOUS USA"; + SHORTNAME="FICTITIO"; + MNC="028"; + MCC="310"; + }; + PLMN7: { + FULLNAME="Vodafone Italia"; + SHORTNAME="VODAFONE"; + MNC="10"; + MCC="222"; + }; + PLMN8: { + FULLNAME="Vodafone Spain"; + SHORTNAME="VODAFONE"; + MNC="01"; + MCC="214"; + }; + PLMN9: { + FULLNAME="Vodafone Spain"; + SHORTNAME="VODAFONE"; + MNC="06"; + MCC="214"; + }; + PLMN10: { + FULLNAME="Vodafone Germ"; + SHORTNAME="VODAFONE"; + MNC="02"; + MCC="262"; + }; + PLMN11: { + FULLNAME="Vodafone Germ"; + SHORTNAME="VODAFONE"; + MNC="04"; + MCC="262"; + }; + PLMN12: { + FULLNAME="Vodafone Germ"; + SHORTNAME="VODAFONE"; + MNC="230"; + MCC="320"; + }; +}; + +UE0: +{ + USER: { + IMEI="356113022094148"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; + + SIM: { + MSIN="100000025"; + USIM_API_K="0c0a34601d4f07677303652c0462535b"; + OPC="ba05688178e398bedc100674071002cb"; + MSISDN="1011234561024"; + }; + + # Home PLMN Selector with Access Technology + HPLMN= "320230"; + + # User controlled PLMN Selector with Access Technology + UCPLMN_LIST = (); + + # Operator PLMN List + OPLMN_LIST = ("00101", "20810", "20811", "20813", "20895", "310280", "310028", "320230"); + + # Operator controlled PLMN Selector with Access Technology + OCPLMN_LIST = ("22210", "21401", "21406", "26202", "26204"); + + # Forbidden plmns + FPLMN_LIST = (); + + # List of Equivalent HPLMNs +#TODO: UE does not connect if set, to be fixed in the UE +# EHPLMN_LIST= ("20811", "20813"); + EHPLMN_LIST= (); +}; + +UE1: +{ + USER: { + IMEI="356113022094149"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; + + SIM: { + MSIN="100000166"; + USIM_API_K="0c0a34601d4f07677303652c0462535b"; + OPC="ba05688178e398bedc100674071002cb"; + MSISDN="1011234561165"; + }; + + # Home PLMN Selector with Access Technology + HPLMN= "320230"; + + # User controlled PLMN Selector with Access Technology + UCPLMN_LIST = (); + + # Operator PLMN List + OPLMN_LIST = ("00101", "20810", "20811", "20813", "20895", "310280", "310028", "320230"); + + # Operator controlled PLMN Selector with Access Technology + OCPLMN_LIST = ("22210", "21401", "21406", "26202", "26204"); + + # Forbidden plmns + FPLMN_LIST = (); + + # List of Equivalent HPLMNs +#TODO: UE does not connect if set, to be fixed in the UE +# EHPLMN_LIST= ("20811", "20813"); + EHPLMN_LIST= (); +}; + +UE2: +{ + USER: { + IMEI="356113022094150"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; + + SIM: { + MSIN="100000012"; + USIM_API_K="0c0a34601d4f07677303652c0462535b"; + OPC="ba05688178e398bedc100674071002cb"; + MSISDN="1011234561011"; + }; + + # Home PLMN Selector with Access Technology + HPLMN= "320230"; + + # User controlled PLMN Selector with Access Technology + UCPLMN_LIST = (); + + # Operator PLMN List + OPLMN_LIST = ("00101", "20810", "20811", "20813", "20895", "310280", "310028", "320230"); + + # Operator controlled PLMN Selector with Access Technology + OCPLMN_LIST = ("22210", "21401", "21406", "26202", "26204"); + + # Forbidden plmns + FPLMN_LIST = (); + + # List of Equivalent HPLMNs +#TODO: UE does not connect if set, to be fixed in the UE +# EHPLMN_LIST= ("20811", "20813"); + EHPLMN_LIST= (); +}; + +UE3: +{ + USER: { + IMEI="356113022094151"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; + + SIM: { + MSIN="100000064"; + USIM_API_K="0c0a34601d4f07677303652c0462535b"; + OPC="ba05688178e398bedc100674071002cb"; + MSISDN="1011234561063"; + }; + + # Home PLMN Selector with Access Technology + HPLMN= "320230"; + + # User controlled PLMN Selector with Access Technology + UCPLMN_LIST = (); + + # Operator PLMN List + OPLMN_LIST = ("00101", "20810", "20811", "20813", "20895", "310280", "310028", "320230"); + + # Operator controlled PLMN Selector with Access Technology + OCPLMN_LIST = ("22210", "21401", "21406", "26202", "26204"); + + # Forbidden plmns + FPLMN_LIST = (); + + # List of Equivalent HPLMNs +#TODO: UE does not connect if set, to be fixed in the UE +# EHPLMN_LIST= ("20811", "20813"); + EHPLMN_LIST= (); +}; + +UE4: +{ + USER: { + IMEI="356113022094152"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; + + SIM: { + MSIN="100000082"; + USIM_API_K="0c0a34601d4f07677303652c0462535b"; + OPC="ba05688178e398bedc100674071002cb"; + MSISDN="1011234561081"; + }; + + # Home PLMN Selector with Access Technology + HPLMN= "320230"; + + # User controlled PLMN Selector with Access Technology + UCPLMN_LIST = (); + + # Operator PLMN List + OPLMN_LIST = ("00101", "20810", "20811", "20813", "20895", "310280", "310028", "320230"); + + # Operator controlled PLMN Selector with Access Technology + OCPLMN_LIST = ("22210", "21401", "21406", "26202", "26204"); + + # Forbidden plmns + FPLMN_LIST = (); + + # List of Equivalent HPLMNs +#TODO: UE does not connect if set, to be fixed in the UE +# EHPLMN_LIST= ("20811", "20813"); + EHPLMN_LIST= (); +}; + +UE5: +{ + USER: { + IMEI="356113022094153"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; + + SIM: { + MSIN="100000011"; + USIM_API_K="0c0a34601d4f07677303652c0462535b"; + OPC="ba05688178e398bedc100674071002cb"; + MSISDN="1011234561010"; + }; + + # Home PLMN Selector with Access Technology + HPLMN= "320230"; + + # User controlled PLMN Selector with Access Technology + UCPLMN_LIST = (); + + # Operator PLMN List + OPLMN_LIST = ("00101", "20810", "20811", "20813", "20895", "310280", "310028", "320230"); + + # Operator controlled PLMN Selector with Access Technology + OCPLMN_LIST = ("22210", "21401", "21406", "26202", "26204"); + + # Forbidden plmns + FPLMN_LIST = (); + + # List of Equivalent HPLMNs +#TODO: UE does not connect if set, to be fixed in the UE +# EHPLMN_LIST= ("20811", "20813"); + EHPLMN_LIST= (); +}; + +UE6: +{ + USER: { + IMEI="356113022094154"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; + + SIM: { + MSIN="100000093"; + USIM_API_K="0c0a34601d4f07677303652c0462535b"; + OPC="ba05688178e398bedc100674071002cb"; + MSISDN="1011234561092"; + }; + + # Home PLMN Selector with Access Technology + HPLMN= "320230"; + + # User controlled PLMN Selector with Access Technology + UCPLMN_LIST = (); + + # Operator PLMN List + OPLMN_LIST = ("00101", "20810", "20811", "20813", "20895", "310280", "310028", "320230"); + + # Operator controlled PLMN Selector with Access Technology + OCPLMN_LIST = ("22210", "21401", "21406", "26202", "26204"); + + # Forbidden plmns + FPLMN_LIST = (); + + # List of Equivalent HPLMNs +#TODO: UE does not connect if set, to be fixed in the UE +# EHPLMN_LIST= ("20811", "20813"); + EHPLMN_LIST= (); +}; + +UE7: +{ + USER: { + IMEI="356113022094155"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; + + SIM: { + MSIN="100000188"; + USIM_API_K="0c0a34601d4f07677303652c0462535b"; + OPC="ba05688178e398bedc100674071002cb"; + MSISDN="1011234561187"; + }; + + # Home PLMN Selector with Access Technology + HPLMN= "320230"; + + # User controlled PLMN Selector with Access Technology + UCPLMN_LIST = (); + + # Operator PLMN List + OPLMN_LIST = ("00101", "20810", "20811", "20813", "20895", "310280", "310028", "320230"); + + # Operator controlled PLMN Selector with Access Technology + OCPLMN_LIST = ("22210", "21401", "21406", "26202", "26204"); + + # Forbidden plmns + FPLMN_LIST = (); + + # List of Equivalent HPLMNs +#TODO: UE does not connect if set, to be fixed in the UE +# EHPLMN_LIST= ("20811", "20813"); + EHPLMN_LIST= (); +}; + +UE8: +{ + USER: { + IMEI="356113022094158"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; + + SIM: { + MSIN="100000017"; + USIM_API_K="0c0a34601d4f07677303652c0462535b"; + OPC="ba05688178e398bedc100674071002cb"; + MSISDN="1011234561016"; + }; + + # Home PLMN Selector with Access Technology + HPLMN= "320230"; + + # User controlled PLMN Selector with Access Technology + UCPLMN_LIST = (); + + # Operator PLMN List + OPLMN_LIST = ("00101", "20810", "20811", "20813", "20895", "310280", "310028", "320230"); + + # Operator controlled PLMN Selector with Access Technology + OCPLMN_LIST = ("22210", "21401", "21406", "26202", "26204"); + + # Forbidden plmns + FPLMN_LIST = (); + + # List of Equivalent HPLMNs +#TODO: UE does not connect if set, to be fixed in the UE +# EHPLMN_LIST= ("20811", "20813"); + EHPLMN_LIST= (); +}; + +UE9: +{ + USER: { + IMEI="356113022094159"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; + + SIM: { + MSIN="100000071"; + USIM_API_K="0c0a34601d4f07677303652c0462535b"; + OPC="ba05688178e398bedc100674071002cb"; + MSISDN="1011234561070"; + }; + + # Home PLMN Selector with Access Technology + HPLMN= "320230"; + + # User controlled PLMN Selector with Access Technology + UCPLMN_LIST = (); + + # Operator PLMN List + OPLMN_LIST = ("00101", "20810", "20811", "20813", "20895", "310280", "310028", "320230"); + + # Operator controlled PLMN Selector with Access Technology + OCPLMN_LIST = ("22210", "21401", "21406", "26202", "26204"); + + # Forbidden plmns + FPLMN_LIST = (); + + # List of Equivalent HPLMNs +#TODO: UE does not connect if set, to be fixed in the UE +# EHPLMN_LIST= ("20811", "20813"); + EHPLMN_LIST= (); +}; + +UE10: +{ + USER: { + IMEI="356113022094110"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; + + SIM: { + MSIN="100000125"; + USIM_API_K="0c0a34601d4f07677303652c0462535b"; + OPC="ba05688178e398bedc100674071002cb"; + MSISDN="1011234561124"; + }; + + # Home PLMN Selector with Access Technology + HPLMN= "320230"; + + # User controlled PLMN Selector with Access Technology + UCPLMN_LIST = (); + + # Operator PLMN List + OPLMN_LIST = ("00101", "20810", "20811", "20813", "20895", "310280", "310028", "320230"); + + # Operator controlled PLMN Selector with Access Technology + OCPLMN_LIST = ("22210", "21401", "21406", "26202", "26204"); + + # Forbidden plmns + FPLMN_LIST = (); + + # List of Equivalent HPLMNs +#TODO: UE does not connect if set, to be fixed in the UE +# EHPLMN_LIST= ("20811", "20813"); + EHPLMN_LIST= (); +}; + +UE11: +{ + USER: { + IMEI="356113022094111"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; + + SIM: { + MSIN="100000067"; + USIM_API_K="0c0a34601d4f07677303652c0462535b"; + OPC="ba05688178e398bedc100674071002cb"; + MSISDN="1011234561066"; + }; + + # Home PLMN Selector with Access Technology + HPLMN= "320230"; + + # User controlled PLMN Selector with Access Technology + UCPLMN_LIST = (); + + # Operator PLMN List + OPLMN_LIST = ("00101", "20810", "20811", "20813", "20895", "310280", "310028", "320230"); + + # Operator controlled PLMN Selector with Access Technology + OCPLMN_LIST = ("22210", "21401", "21406", "26202", "26204"); + + # Forbidden plmns + FPLMN_LIST = (); + + # List of Equivalent HPLMNs +#TODO: UE does not connect if set, to be fixed in the UE +# EHPLMN_LIST= ("20811", "20813"); + EHPLMN_LIST= (); +}; + +UE12: +{ + USER: { + IMEI="356113022094112"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; + + SIM: { + MSIN="100000152"; + USIM_API_K="0c0a34601d4f07677303652c0462535b"; + OPC="ba05688178e398bedc100674071002cb"; + MSISDN="1011234561151"; + }; + + # Home PLMN Selector with Access Technology + HPLMN= "320230"; + + # User controlled PLMN Selector with Access Technology + UCPLMN_LIST = (); + + # Operator PLMN List + OPLMN_LIST = ("00101", "20810", "20811", "20813", "20895", "310280", "310028", "320230"); + + # Operator controlled PLMN Selector with Access Technology + OCPLMN_LIST = ("22210", "21401", "21406", "26202", "26204"); + + # Forbidden plmns + FPLMN_LIST = (); + + # List of Equivalent HPLMNs +#TODO: UE does not connect if set, to be fixed in the UE +# EHPLMN_LIST= ("20811", "20813"); + EHPLMN_LIST= (); +}; + +UE13: +{ + USER: { + IMEI="356113022094113"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; + + SIM: { + MSIN="100000083"; + USIM_API_K="0c0a34601d4f07677303652c0462535b"; + OPC="ba05688178e398bedc100674071002cb"; + MSISDN="1011234561082"; + }; + + # Home PLMN Selector with Access Technology + HPLMN= "320230"; + + # User controlled PLMN Selector with Access Technology + UCPLMN_LIST = (); + + # Operator PLMN List + OPLMN_LIST = ("00101", "20810", "20811", "20813", "20895", "310280", "310028", "320230"); + + # Operator controlled PLMN Selector with Access Technology + OCPLMN_LIST = ("22210", "21401", "21406", "26202", "26204"); + + # Forbidden plmns + FPLMN_LIST = (); + + # List of Equivalent HPLMNs +#TODO: UE does not connect if set, to be fixed in the UE +# EHPLMN_LIST= ("20811", "20813"); + EHPLMN_LIST= (); +}; + +UE14: +{ + USER: { + IMEI="356113022094114"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; + + SIM: { + MSIN="100000086"; + USIM_API_K="0c0a34601d4f07677303652c0462535b"; + OPC="ba05688178e398bedc100674071002cb"; + MSISDN="1011234561085"; + }; + + # Home PLMN Selector with Access Technology + HPLMN= "320230"; + + # User controlled PLMN Selector with Access Technology + UCPLMN_LIST = (); + + # Operator PLMN List + OPLMN_LIST = ("00101", "20810", "20811", "20813", "20895", "310280", "310028", "320230"); + + # Operator controlled PLMN Selector with Access Technology + OCPLMN_LIST = ("22210", "21401", "21406", "26202", "26204"); + + # Forbidden plmns + FPLMN_LIST = (); + + # List of Equivalent HPLMNs +#TODO: UE does not connect if set, to be fixed in the UE +# EHPLMN_LIST= ("20811", "20813"); + EHPLMN_LIST= (); +}; + +UE15: +{ + USER: { + IMEI="356113022094115"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; + + SIM: { + MSIN="100000026"; + USIM_API_K="0c0a34601d4f07677303652c0462535b"; + OPC="ba05688178e398bedc100674071002cb"; + MSISDN="1011234561025"; + }; + + # Home PLMN Selector with Access Technology + HPLMN= "320230"; + + # User controlled PLMN Selector with Access Technology + UCPLMN_LIST = (); + + # Operator PLMN List + OPLMN_LIST = ("00101", "20810", "20811", "20813", "20895", "310280", "310028", "320230"); + + # Operator controlled PLMN Selector with Access Technology + OCPLMN_LIST = ("22210", "21401", "21406", "26202", "26204"); + + # Forbidden plmns + FPLMN_LIST = (); + + # List of Equivalent HPLMNs +#TODO: UE does not connect if set, to be fixed in the UE +# EHPLMN_LIST= ("20811", "20813"); + EHPLMN_LIST= (); +}; + +UE16: +{ + USER: { + IMEI="356113022094116"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; + + SIM: { + MSIN="100000114"; + USIM_API_K="0c0a34601d4f07677303652c0462535b"; + OPC="ba05688178e398bedc100674071002cb"; + MSISDN="1011234561113"; + }; + + # Home PLMN Selector with Access Technology + HPLMN= "320230"; + + # User controlled PLMN Selector with Access Technology + UCPLMN_LIST = (); + + # Operator PLMN List + OPLMN_LIST = ("00101", "20810", "20811", "20813", "20895", "310280", "310028", "320230"); + + # Operator controlled PLMN Selector with Access Technology + OCPLMN_LIST = ("22210", "21401", "21406", "26202", "26204"); + + # Forbidden plmns + FPLMN_LIST = (); + + # List of Equivalent HPLMNs +#TODO: UE does not connect if set, to be fixed in the UE +# EHPLMN_LIST= ("20811", "20813"); + EHPLMN_LIST= (); +}; + +UE17: +{ + USER: { + IMEI="356113022094117"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; + + SIM: { + MSIN="100000159"; + USIM_API_K="0c0a34601d4f07677303652c0462535b"; + OPC="ba05688178e398bedc100674071002cb"; + MSISDN="1011234561158"; + }; + + # Home PLMN Selector with Access Technology + HPLMN= "320230"; + + # User controlled PLMN Selector with Access Technology + UCPLMN_LIST = (); + + # Operator PLMN List + OPLMN_LIST = ("00101", "20810", "20811", "20813", "20895", "310280", "310028", "320230"); + + # Operator controlled PLMN Selector with Access Technology + OCPLMN_LIST = ("22210", "21401", "21406", "26202", "26204"); + + # Forbidden plmns + FPLMN_LIST = (); + + # List of Equivalent HPLMNs +#TODO: UE does not connect if set, to be fixed in the UE +# EHPLMN_LIST= ("20811", "20813"); + EHPLMN_LIST= (); +}; + +UE18: +{ + USER: { + IMEI="356113022094118"; + MANUFACTURER="EURECOM"; + MODEL="LTE Android PC"; + PIN="0000"; + }; + + SIM: { + MSIN="100000113"; + USIM_API_K="0c0a34601d4f07677303652c0462535b"; + OPC="ba05688178e398bedc100674071002cb"; + MSISDN="1011234561112"; + }; + + # Home PLMN Selector with Access Technology + HPLMN= "320230"; + + # User controlled PLMN Selector with Access Technology + UCPLMN_LIST = (); + + # Operator PLMN List + OPLMN_LIST = ("00101", "20810", "20811", "20813", "20895", "310280", "310028", "320230"); + + # Operator controlled PLMN Selector with Access Technology + OCPLMN_LIST = ("22210", "21401", "21406", "26202", "26204"); + + # Forbidden plmns + FPLMN_LIST = (); + + # List of Equivalent HPLMNs +#TODO: UE does not connect if set, to be fixed in the UE +# EHPLMN_LIST= ("20811", "20813"); + EHPLMN_LIST= (); +}; \ No newline at end of file diff --git a/ci-scripts/conf_files/episci/proxy_gnb.band78.sa.fr1.106PRB.usrpn310.conf b/ci-scripts/conf_files/episci/proxy_gnb.band78.sa.fr1.106PRB.usrpn310.conf new file mode 100644 index 0000000000..ab0cf5f469 --- /dev/null +++ b/ci-scripts/conf_files/episci/proxy_gnb.band78.sa.fr1.106PRB.usrpn310.conf @@ -0,0 +1,326 @@ +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 = 208; + mnc = 99; + mnc_length = 2; + snssaiList = ( + { + sst = 1; + sd = 0x1; // 0 false, else true + }, + { + sst = 1; + sd = 0x112233; // 0 false, else true + } + ); + + }); + + nr_cellid = 12345678L; + + ////////// Physical parameters: + + ssb_SubcarrierOffset = 0; + pdsch_AntennaPorts = 1; + pusch_AntennaPorts = 1; + ul_prbblacklist = "51,52,53,54" + min_rxtxtime_pdsch = 6; + + pdcch_ConfigSIB1 = ( + { + controlResourceSetZero = 12; + searchSpaceZero = 0; + } + ); + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 641280; + dl_frequencyBand = 78; + # this is 3600 MHz + dl_absoluteFrequencyPointA = 640008; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 106; + #initialDownlinkBWP + #genericParameters + # this is RBstart=27,L=48 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 12952; # 6366 12925 12956 28875 12952 +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; + #pdsch-ConfigCommon + #pdschTimeDomainAllocationList (up to 16 entries) + initialDLBWPk0_0 = 0; #for DL slot + initialDLBWPmappingType_0 = 0; #0=typeA,1=typeB + initialDLBWPstartSymbolAndLength_0 = 40; #this is SS=1,L=13 + + initialDLBWPk0_1 = 0; #for mixed slot + initialDLBWPmappingType_1 = 0; + initialDLBWPstartSymbolAndLength_1 = 57; #this is SS=1,L=5 + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 106; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 12952; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -96; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + + # pusch-ConfigCommon (up to 16 elements) + initialULBWPk2_0 = 6; # used for UL slot + initialULBWPmappingType_0 = 1 + initialULBWPstartSymbolAndLength_0 = 41; # this is SS=0 L=13 + + initialULBWPk2_1 = 6; # used for mixed slot + initialULBWPmappingType_1 = 1; + initialULBWPstartSymbolAndLength_1 = 52; # this is SS=10 L=4 + + initialULBWPk2_2 = 7; # used for Msg.3 during RA + initialULBWPmappingType_2 = 1; + initialULBWPstartSymbolAndLength_2 = 52; # this is SS=10 L=4 + + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; +# ssb_PositionsInBurs_BitmapPR +# 1=short, 2=medium, 3=long + ssb_PositionsInBurst_PR = 2; + ssb_PositionsInBurst_Bitmap = 1; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 1; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = -25; + } + + ); + + + # ------- 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.61.195"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + + NETWORK_INTERFACES : + { + GNB_INTERFACE_NAME_FOR_NG_AMF = "lo:"; + GNB_IPV4_ADDRESS_FOR_NG_AMF = "127.0.0.2"; + GNB_INTERFACE_NAME_FOR_NGU = "lo:"; + GNB_IPV4_ADDRESS_FOR_NGU = "127.0.0.2"; + GNB_PORT_FOR_NGU = 2152; # Spec 2152 + }; + + } +); + +MACRLCs = ( + { + num_cc = 1; + local_s_if_name = "lo:"; + remote_s_address = "127.0.0.1"; // pnf addr [!] + local_s_address = "127.0.0.2"; // vnf addr + local_s_portc = 50601; // vnf p5 port + remote_s_portc = 50600; // pnf p5 port [!] + local_s_portd = 50611; // vnf p7 port [!] + remote_s_portd = 50610; // pnf p7 port [!] + tr_s_preference = "nfapi"; + tr_n_preference = "local_RRC"; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + pusch_proc_threads = 8; + prach_dtx_threshold = 120; + pucch0_dtx_threshold = 150; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [78]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 75; + eNB_instances = [0]; + #beamforming 1x4 matrix: + bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; + #clock_src = "external"; + sdr_addrs = "mgmt_addr=192.168.18.240,addr=192.168.10.2,second_addr=192.168.20.2,clock_source=internal,time_source=internal" + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_SINGLE_THREAD"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + +rfsimulator : +{ + serveraddr = "server"; + serverport = "4043"; + options = (); #("saviq"); or/and "chanmod" + modelname = "AWGN"; + IQfile = "/tmp/rfsimulator.iqs"; +}; + +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"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + ngap_log_level ="debug"; + ngap_log_verbosity ="medium"; + }; + diff --git a/ci-scripts/conf_files/episci/proxy_nr-ue.nfapi.conf b/ci-scripts/conf_files/episci/proxy_nr-ue.nfapi.conf new file mode 100644 index 0000000000..8411ed8fc6 --- /dev/null +++ b/ci-scripts/conf_files/episci/proxy_nr-ue.nfapi.conf @@ -0,0 +1,52 @@ +log_config = { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="medium"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="full"; +}; + +uicc0 = { +imsi = "2089900007487"; +key = "fec86ba6eb707ed08905757b1bb44b8f"; +opc= "C42449363BBAD02B66D16BC975D77CC1"; +dnn= "oai"; +nssai_sst=1; +nssai_sd=1; +} + +L1s = ( + { + num_cc = 1; + tr_n_preference = "nfapi"; + local_n_if_name = "lo:"; + remote_n_address = "127.0.0.1"; //Proxy IP + local_n_address = "127.0.0.1"; + local_n_portc = 50600; + remote_n_portc = 50601; + local_n_portd = 50610; + remote_n_portd = 50611; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 90 + att_rx = 0; + bands = [7,38,42,43]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 125; + } +); diff --git a/ci-scripts/conf_files/episci/proxy_rcc.band7.tm1.nfapi.conf b/ci-scripts/conf_files/episci/proxy_rcc.band7.tm1.nfapi.conf new file mode 100644 index 0000000000..d4c72d6c14 --- /dev/null +++ b/ci-scripts/conf_files/episci/proxy_rcc.band7.tm1.nfapi.conf @@ -0,0 +1,247 @@ +Active_eNBs = ( "eNB-Eurecom-LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB-Eurecom-LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 5; + + plmn_list = ( { mcc = 320; mnc = 230; mnc_length = 3; } ); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "3GPP_eNODEB"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2685000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 50; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + pbch_repetition = "FALSE"; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 0; + pucch_nCS_AN = 0; + pucch_n1_AN = 0; + pdsch_referenceSignalPower = -27; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + + //Parameters for SIB18 + rxPool_sc_CP_Len = "normal"; + rxPool_sc_Period = "sf40"; + rxPool_data_CP_Len = "normal"; + rxPool_ResourceConfig_prb_Num = 20; + rxPool_ResourceConfig_prb_Start = 5; + rxPool_ResourceConfig_prb_End = 44; + rxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + rxPool_ResourceConfig_offsetIndicator_choice = 0; + rxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; +/* rxPool_dataHoppingConfig_hoppingParameter = 0; + rxPool_dataHoppingConfig_numSubbands = "ns1"; + rxPool_dataHoppingConfig_rbOffset = 0; + rxPool_commTxResourceUC-ReqAllowed = "TRUE"; +*/ + // Parameters for SIB19 + discRxPool_cp_Len = "normal" + discRxPool_discPeriod = "rf32" + discRxPool_numRetx = 1; + discRxPool_numRepetition = 2; + discRxPool_ResourceConfig_prb_Num = 5; + discRxPool_ResourceConfig_prb_Start = 3; + discRxPool_ResourceConfig_prb_End = 21; + discRxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + discRxPool_ResourceConfig_offsetIndicator_choice = 0; + discRxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.61.3"; + ipv6 = "192:168:30::17"; + port = 36412 ; + active = "yes"; + preference = "ipv4"; + } + ); + + enable_measurement_reports = "no"; + + ///X2 + enable_x2 = "yes"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "lo"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.1"; + ENB_INTERFACE_NAME_FOR_S1U = "lo"; + ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.1"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + ENB_IPV4_ADDRESS_FOR_X2C = "127.0.0.1"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 + + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + local_s_if_name = "lo"; + remote_s_address = "127.0.0.1"; + local_s_address = "127.0.0.1"; + local_s_portc = 50001; + remote_s_portc = 50000; + local_s_portd = 50011; + remote_s_portd = 50010; + tr_s_preference = "nfapi"; + tr_n_preference = "local_RRC"; + scheduler_mode = "fairRR"; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + +log_config = + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; diff --git a/ci-scripts/conf_files/episci/proxy_rcc.band78.tm1.106PRB.nfapi.conf b/ci-scripts/conf_files/episci/proxy_rcc.band78.tm1.106PRB.nfapi.conf new file mode 100644 index 0000000000..0ef317d63e --- /dev/null +++ b/ci-scripts/conf_files/episci/proxy_rcc.band78.tm1.106PRB.nfapi.conf @@ -0,0 +1,305 @@ +Active_gNBs = ( "gNB-Eurecom-5GNRBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + + cell_type = "CELL_MACRO_GNB"; + + gNB_name = "gNB-Eurecom-5GNRBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 5; + + plmn_list = ({mcc = 320; mnc = 230; mnc_length = 3;}); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + ssb_SubcarrierOffset = 0; + pdsch_AntennaPorts = 1; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 641032; + dl_frequencyBand = 78; + # this is 3600 MHz + dl_absoluteFrequencyPointA = 640000; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 106; + #initialDownlinkBWP + #genericParameters + # this is RBstart=41,L=24 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 6366; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; + #pdsch-ConfigCommon + #pdschTimeDomainAllocationList (up to 16 entries) + initialDLBWPk0_0 = 0; + #initialULBWPmappingType + #0=typeA,1=typeB + initialDLBWPmappingType_0 = 0; + #this is SS=1,L=13 + initialDLBWPstartSymbolAndLength_0 = 40; + + initialDLBWPk0_1 = 0; + initialDLBWPmappingType_1 = 0; + #this is SS=2,L=12 + initialDLBWPstartSymbolAndLength_1 = 53; + + initialDLBWPk0_2 = 0; + initialDLBWPmappingType_2 = 0; + #this is SS=1,L=12 + initialDLBWPstartSymbolAndLength_2 = 54; + + initialDLBWPk0_3 = 0; + initialDLBWPmappingType_3 = 0; + #this is SS=1,L=5 + initialDLBWPstartSymbolAndLength_3 = 57; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 106; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 6366; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -118; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + + # pusch-ConfigCommon (up to 16 elements) + initialULBWPk2_0 = 6; + initialULBWPmappingType_0 = 1 + # this is SS=0 L=11 + initialULBWPstartSymbolAndLength_0 = 55; + + initialULBWPk2_1 = 6; + initialULBWPmappingType_1 = 1; + # this is SS=0 L=12 + initialULBWPstartSymbolAndLength_1 = 69; + + initialULBWPk2_2 = 7; + initialULBWPmappingType_2 = 1; + # this is SS=10 L=4 + initialULBWPstartSymbolAndLength_2 = 52; + + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; +# ssb_PositionsInBurs_BitmapPR +# 1=short, 2=medium, 3=long + ssb_PositionsInBurst_PR = 2; + ssb_PositionsInBurst_Bitmap = 1; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 1; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = 10; + } + + + ); + + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.61.3"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + ///X2 + enable_x2 = "yes"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ + target_enb_x2_ip_address = ( + { ipv4 = "127.0.0.1"; # rrc.band7.tm1.nfapi.conf:line 201 + ipv6 = "192:168:30::17"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { # All of these have to be IP addr of gNB + # if in CORE container, make it 172.16.0.X + # if not launched in CORE, can set to lo (127.0.0.2) + GNB_INTERFACE_NAME_FOR_S1_MME = "lo:"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.2"; + GNB_INTERFACE_NAME_FOR_S1U = "lo:"; + GNB_IPV4_ADDRESS_FOR_S1U = "127.0.0.2"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + GNB_IPV4_ADDRESS_FOR_X2C = "127.0.0.2"; + GNB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + } +); + + +MACRLCs = ( + { + num_cc = 1; + local_s_if_name = "lo:"; + remote_s_address = "127.0.0.1"; // pnf addr [!] + local_s_address = "127.0.0.2"; // vnf addr + local_s_portc = 50601; // vnf p5 port + remote_s_portc = 50600; // pnf p5 port [!] + local_s_portd = 50611; // vnf p7 port [!] + remote_s_portd = 50610; // pnf p7 port [!] + tr_s_preference = "nfapi"; + tr_n_preference = "local_RRC"; + } +) + + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + +log_config = + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + diff --git a/ci-scripts/conf_files/episci/proxy_ue.nfapi.conf b/ci-scripts/conf_files/episci/proxy_ue.nfapi.conf new file mode 100644 index 0000000000..3f227d573c --- /dev/null +++ b/ci-scripts/conf_files/episci/proxy_ue.nfapi.conf @@ -0,0 +1,44 @@ +log_config = { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="medium"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="full"; +}; + + +L1s = ( + { + num_cc = 1; + tr_n_preference = "nfapi"; + local_n_if_name = "lo"; + remote_n_address = "127.0.0.1"; + local_n_address = "127.0.0.1"; + local_n_portc = 50000; + remote_n_portc = 50001; + local_n_portd = 50010; + remote_n_portd = 50011; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 90 + att_rx = 0; + bands = [7,38,42,43]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 125; + } +); diff --git a/ci-scripts/conf_files/nr-ue.nfapi.conf b/ci-scripts/conf_files/nr-ue.nfapi.conf new file mode 100644 index 0000000000..b12e0c8d05 --- /dev/null +++ b/ci-scripts/conf_files/nr-ue.nfapi.conf @@ -0,0 +1,44 @@ +log_config = { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="medium"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="full"; +}; + + +L1s = ( + { + num_cc = 1; + tr_n_preference = "nfapi"; + local_n_if_name = "ens3"; + remote_n_address = "127.0.0.1"; //Proxy IP + local_n_address = "127.0.0.1"; + local_n_portc = 50600; + remote_n_portc = 50601; + local_n_portd = 50610; + remote_n_portd = 50611; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 90 + att_rx = 0; + bands = [7,38,42,43]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 125; + } +); diff --git a/ci-scripts/reportTestLocally.sh b/ci-scripts/reportTestLocally.sh index 19fac7fd78..6ef6b2e254 100755 --- a/ci-scripts/reportTestLocally.sh +++ b/ci-scripts/reportTestLocally.sh @@ -1033,116 +1033,6 @@ function report_test { echo " " >> ./test_simulator_results.html fi - ARCHIVES_LOC=archives/l2_sim/test - if [ -d $ARCHIVES_LOC ] - then - echo "

4G LTE L2-NFAPI Simulator Check

" >> ./test_simulator_results.html - - if [ -f $ARCHIVES_LOC/test_final_status.log ] - then - if [ `grep -c TEST_OK $ARCHIVES_LOC/test_final_status.log` -eq 1 ] - then - echo "
" >> ./test_simulator_results.html - echo " TEST was SUCCESSFUL " >> ./test_simulator_results.html - echo "
" >> ./test_simulator_results.html - else - echo "
" >> ./test_simulator_results.html - echo " TEST was a FAILURE! " >> ./test_simulator_results.html - echo "
" >> ./test_simulator_results.html - fi - else - echo "
" >> ./test_simulator_results.html - echo " COULD NOT DETERMINE TEST FINAL STATUS! " >> ./test_simulator_results.html - echo "
" >> ./test_simulator_results.html - fi - - echo " " >> ./test_simulator_results.html - echo "
" >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - - EPC_CONFIGS=("wS1" "noS1") - TRANS_MODES=("fdd") - BW_CASES=(05) - NB_USERS=(01 04) - for CN_CONFIG in ${EPC_CONFIGS[@]} - do - for TMODE in ${TRANS_MODES[@]} - do - for BW in ${BW_CASES[@]} - do - for UES in ${NB_USERS[@]} - do - echo " " >> ./test_simulator_results.html - if [[ $CN_CONFIG =~ .*wS1.* ]] - then - echo " " >> ./test_simulator_results.html - else - echo " " >> ./test_simulator_results.html - fi - echo " " >> ./test_simulator_results.html - ENB_LOG=$ARCHIVES_LOC/${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_enb.log - UE_LOG=`echo $ENB_LOG | sed -e "s#enb#ue#"` - if [ -f $ENB_LOG ] && [ -f $UE_LOG ] - then - NAME_ENB=`echo $ENB_LOG | sed -e "s#$ARCHIVES_LOC/##"` - NAME_UE=`echo $UE_LOG | sed -e "s#$ARCHIVES_LOC/##"` - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - NB_ENB_GOT_SYNC=`egrep -c "got sync" $ENB_LOG` - NB_UE_GOT_SYNC=`egrep -c "got sync" $UE_LOG` - NB_ENB_SYNCED_WITH_UE=`egrep -c "Sending NFAPI_START_RESPONSE" $UE_LOG` - if [ $NB_ENB_GOT_SYNC -gt 0 ] && [ $NB_UE_GOT_SYNC -gt 2 ] && [ $NB_ENB_SYNCED_WITH_UE -gt 0 ] - then - echo " " >> ./test_simulator_results.html - else - echo " " >> ./test_simulator_results.html - fi - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - fi - PING_LOGS=`ls $ARCHIVES_LOC/${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_ping*.log 2> /dev/null` - analyzePingFiles - - IPERF_TESTS=`ls $ARCHIVES_LOC/${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_iperf_dl*client*txt 2> /dev/null` - analyzeIperfFiles - - IPERF_TESTS=`ls $ARCHIVES_LOC/${TMODE}_${BW}MHz_${UES}users_${CN_CONFIG}_iperf_ul*client*txt 2> /dev/null` - analyzeIperfFiles - done - done - done - done - - echo "
Log File NameCommandStatusStatistics
Test with EPC (aka withS1): ${TMODE} -- ${BW}MHz -- ${UES} user(s)Test without EPC (aka noS1): ${TMODE} -- ${BW}MHz -- ${UES} user(s)
$NAME_ENB --- $NAME_UEN/AOKKO
" >> ./test_simulator_results.html
-                    if [ $NB_ENB_GOT_SYNC -gt 0 ]
-                    then
-                        echo "- eNB --> got sync" >> ./test_simulator_results.html
-                    else
-                        echo "- eNB NEVER got sync" >> ./test_simulator_results.html
-                    fi
-                    if [ $NB_UE_GOT_SYNC -gt 2 ]
-                    then
-                        echo "- UE --> got sync" >> ./test_simulator_results.html
-                    else
-                        echo "- UE NEVER got sync" >> ./test_simulator_results.html
-                    fi
-                    if [ $NB_ENB_SYNCED_WITH_UE -gt 0 ]
-                    then
-                        echo "- UE attached to eNB" >> ./test_simulator_results.html
-                    else
-                        echo "- UE NEVER attached to eNB" >> ./test_simulator_results.html
-                    fi
-                    echo "        
" >> ./test_simulator_results.html - echo "
" >> ./test_simulator_results.html - fi - ARCHIVES_LOC=archives/phy_sim/test if [ -d $ARCHIVES_LOC ] then diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index de696cdc64..be25ab0e1a 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -1472,13 +1472,18 @@ function run_test_on_vm { echo "############################################################" echo "OAI CI VM script" echo "############################################################" - if [[ (( "$RUN_OPTIONS" == "complex" ) && ( $VM_NAME =~ .*-l2-sim.* )) ]] || [[ (( "$RUN_OPTIONS" == "complex" ) && ( $VM_NAME =~ .*-rf-sim.* )) ]] + if [[ (( "$RUN_OPTIONS" == "complex" ) && ( $VM_NAME =~ .*-l2-sim.* )) ]] then - ENB_VM_NAME=`echo $VM_NAME | sed -e "s#l2-sim#enb-ethernet#" -e "s#rf-sim#enb-ethernet#"` + echo "This VM test type is no longer supported in the pipeline framework" + return + fi + if [[ (( "$RUN_OPTIONS" == "complex" ) && ( $VM_NAME =~ .*-rf-sim.* )) ]] + then + ENB_VM_NAME=`echo $VM_NAME | sed -e "s#rf-sim#enb-ethernet#"` ENB_VM_CMDS=${ENB_VM_NAME}_cmds.txt echo "ENB_VM_NAME = $ENB_VM_NAME" echo "ENB_VM_CMD_FILE = $ENB_VM_CMDS" - UE_VM_NAME=`echo $VM_NAME | sed -e "s#l2-sim#ue-ethernet#" -e "s#rf-sim#ue-ethernet#"` + UE_VM_NAME=`echo $VM_NAME | sed -e "s#rf-sim#ue-ethernet#"` UE_VM_CMDS=${UE_VM_NAME}_cmds.txt echo "UE_VM_NAME = $UE_VM_NAME" echo "UE_VM_CMD_FILE = $UE_VM_CMDS" @@ -1499,7 +1504,7 @@ function run_test_on_vm { echo "JENKINS_WKSP = $JENKINS_WKSP" echo "ARCHIVES_LOC = $ARCHIVES_LOC" - if [[ (( "$RUN_OPTIONS" == "complex" ) && ( $VM_NAME =~ .*-l2-sim.* )) ]] || [[ (( "$RUN_OPTIONS" == "complex" ) && ( $VM_NAME =~ .*-rf-sim.* )) ]] + if [[ (( "$RUN_OPTIONS" == "complex" ) && ( $VM_NAME =~ .*-rf-sim.* )) ]] then echo "############################################################" echo "Waiting for ENB VM to be started" diff --git a/cmake_targets/.gitignore b/cmake_targets/.gitignore new file mode 100644 index 0000000000..6d6cdd29a6 --- /dev/null +++ b/cmake_targets/.gitignore @@ -0,0 +1,3 @@ +.usim.* +.ue_emm.nvram* +.ue.nvram* diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 349e9dbee0..bf3bb2b017 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -359,6 +359,10 @@ set(CMAKE_C_FLAGS_DEBUG "${debugOpt} -O0") set(CMAKE_C_FLAGS_RELWITHDEBINFO "${debugOpt} -O2") set(CMAKE_C_FLAGS_RELEASE "-O3") +# Enable assert() for RelWithDebInfo builds +string(REPLACE "-DNDEBUG" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}") +string(REPLACE "-DNDEBUG" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") + set(GIT_BRANCH "UNKNOWN") set(GIT_COMMIT_HASH "UNKNOWN") set(GIT_COMMIT_DATE "UNKNOWN") @@ -1472,6 +1476,7 @@ set(NFAPI_USER_SRC ${NFAPI_USER_DIR}/nfapi.c ${NFAPI_USER_DIR}/nfapi_pnf.c ${NFAPI_USER_DIR}/nfapi_vnf.c + ${NFAPI_USER_DIR}/gnb_ind_vars.c ) add_library(NFAPI_USER_LIB ${NFAPI_USER_SRC}) add_dependencies(NFAPI_USER_LIB rrc_flag) @@ -2025,6 +2030,7 @@ set(NR_L2_SRC_UE ${NR_UE_RRC_DIR}/L2_interface_ue.c ${NR_UE_RRC_DIR}/main_ue.c ${NR_UE_RRC_DIR}/rrc_UE.c + ${NR_UE_RRC_DIR}/rrc_nsa.c ) set (MAC_SRC @@ -2069,6 +2075,7 @@ set (MAC_NR_SRC set (MAC_SRC_UE ${PHY_INTERFACE_DIR}/phy_stub_UE.c + ${PHY_INTERFACE_DIR}/queue_t.c ${MAC_DIR}/main_ue.c ${MAC_DIR}/ue_procedures.c ${MAC_DIR}/ra_procedures.c @@ -2782,6 +2789,7 @@ add_executable(lte-softmodem ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c ${OPENAIR_DIR}/common/utils/utils.c ${OPENAIR_DIR}/common/utils/system.c + ${PHY_INTERFACE_DIR}/queue_t.c ${OPENAIR_DIR}/common/utils/lte/ue_power.c ${OPENAIR_DIR}/common/utils/lte/prach_utils.c ${XFORMSINTERFACE_SOURCE} @@ -2826,6 +2834,7 @@ add_executable(ocp-enb ${OPENAIR_DIR}/common/utils/system.c ${OPENAIR_DIR}/common/utils/lte/ue_power.c ${OPENAIR_DIR}/common/utils/lte/prach_utils.c + ${PHY_INTERFACE_DIR}/queue_t.c ${XFORMSINTERFACE_SOURCE} ${T_SOURCE} ${CONFIG_SOURCES} @@ -2966,6 +2975,7 @@ add_executable(nr-softmodem ${OPENAIR_DIR}/common/utils/lte/ue_power.c ${OPENAIR_DIR}/common/utils/lte/prach_utils.c ${OPENAIR_DIR}/common/utils/nr/nr_common.c + ${PHY_INTERFACE_DIR}/queue_t.c ${XFORMSINTERFACE_SOURCE} ${T_SOURCE} ${CONFIG_SOURCES} @@ -3006,6 +3016,7 @@ add_executable(ocp-gnb ${OPENAIR_DIR}/common/utils/nr/nr_common.c ${OPENAIR_DIR}/common/utils/utils.c ${OPENAIR_DIR}/common/utils/system.c + ${PHY_INTERFACE_DIR}/queue_t.c ${XFORMS_SOURCE_NR} ${T_SOURCE} ${CONFIG_SOURCES} @@ -3209,14 +3220,16 @@ add_executable(nr_dlsim ${OPENAIR_DIR}/executables/softmodem-common.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c + ${NR_UE_RRC_DIR}/rrc_nsa.c ${NFAPI_USER_DIR}/nfapi.c ${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c + ${PHY_INTERFACE_DIR}/queue_t.c ${UTIL_SRC} ${T_SOURCE} ${SHLIB_LOADER_SOURCES} ) target_link_libraries(nr_dlsim - -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE X2AP_ENB X2AP_LIB SECU_CN NGAP_GNB -Wl,--end-group + -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE X2AP_ENB X2AP_LIB SECU_CN NGAP_GNB NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -lz -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ITTI ${OPENSSL_LIBRARIES} dl ) target_compile_definitions(nr_dlsim PUBLIC -DPHYSICAL_SIMULATOR) @@ -3229,13 +3242,15 @@ add_executable(nr_prachsim ${OPENAIR1_DIR}/SCHED_NR/phy_procedures_nr_common.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c + ${NR_UE_RRC_DIR}/rrc_nsa.c ${NFAPI_USER_DIR}/nfapi.c ${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c + ${PHY_INTERFACE_DIR}/queue_t.c ${UTIL_SRC} ${T_SOURCE} ${SHLIB_LOADER_SOURCES}) target_link_libraries(nr_prachsim - -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE X2AP_ENB X2AP_LIB SECU_CN NGAP_GNB -Wl,--end-group + -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE X2AP_ENB X2AP_LIB SECU_CN NGAP_GNB NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -lz -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ITTI ${OPENSSL_LIBRARIES} dl) add_executable(nr_ulschsim @@ -3244,6 +3259,7 @@ add_executable(nr_ulschsim ${OPENAIR_DIR}/common/utils/utils.c ${OPENAIR_DIR}/common/utils/system.c ${OPENAIR_DIR}/common/utils/nr/nr_common.c + ${PHY_INTERFACE_DIR}/queue_t.c ${UTIL_SRC} ${T_SOURCE} ${SHLIB_LOADER_SOURCES} @@ -3262,13 +3278,15 @@ add_executable(nr_ulsim ${OPENAIR_DIR}/executables/softmodem-common.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c + ${NR_UE_RRC_DIR}/rrc_nsa.c ${NFAPI_USER_DIR}/nfapi.c + ${PHY_INTERFACE_DIR}/queue_t.c ${UTIL_SRC} ${T_SOURCE} ${SHLIB_LOADER_SOURCES} ) target_link_libraries(nr_ulsim - -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE X2AP_ENB X2AP_LIB SECU_CN NGAP_GNB -Wl,--end-group + -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE X2AP_ENB X2AP_LIB SECU_CN NGAP_GNB NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -lz -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ITTI ${OPENSSL_LIBRARIES} dl ) target_compile_definitions(nr_ulsim PUBLIC -DPHYSICAL_SIMULATOR) diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c index 7b913e6dc9..42c1996eec 100644 --- a/common/utils/LOG/log.c +++ b/common/utils/LOG/log.c @@ -43,6 +43,8 @@ #include #include #include "common/config/config_userapi.h" +#include +#include // main log variables @@ -508,6 +510,53 @@ char *log_getthreadname(char *threadname, } } +#if LOG_MINIMAL +#include +void logMinimal(int comp, int level, const char *format, ...) +{ + struct timespec ts; + if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1) + abort(); + + char buf[MAX_LOG_TOTAL]; + int n = snprintf(buf, sizeof(buf), "%lu.%06lu %08lx [%s] %c ", + ts.tv_sec, + ts.tv_nsec / 1000, + syscall(__NR_gettid), + g_log->log_component[comp].name, + level); + if (n < 0 || n >= sizeof(buf)) + { + fprintf(stderr, "%s: n=%d\n", __func__, n); + return; + } + + va_list args; + va_start(args, format); + int m = vsnprintf(buf + n, sizeof(buf) - n, format, args); + va_end(args); + + if (m < 0) + { + fprintf(stderr, "%s: n=%d m=%d\n", __func__, n, m); + return; + } + + int len = n + m; + if (len > sizeof(buf) - 1) + { + len = sizeof(buf) - 1; + } + if (buf[len - 1] != '\n') + { + buf[len++] = '\n'; + } + + __attribute__((unused)) + int unused = write(STDOUT_FILENO, buf, len); +} +#endif // LOG_MINIMAL + static int log_header(char *log_buffer, int buffsize, int comp, diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h index 0acfbca9db..8d49bae2cb 100644 --- a/common/utils/LOG/log.h +++ b/common/utils/LOG/log.h @@ -54,6 +54,12 @@ #include "T.h" #include /*----------------------------------------------------------------------------*/ +#include +#ifdef NDEBUG +#warning assert is disabled +#endif +#define NUM_ELEMENTS(ARRAY) (sizeof(ARRAY) / sizeof(ARRAY[0])) +#define CHECK_INDEX(ARRAY, INDEX) assert((INDEX) < NUM_ELEMENTS(ARRAY)) #ifdef __cplusplus extern "C" { @@ -402,10 +408,32 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int #define LOG_DUMP_DOUBLE 1 // debugging macros #define LOG_F LOG_I /* because LOG_F was originaly to dump a message or buffer but is also used as a regular level...., to dump use LOG_DUMPMSG */ + +#define LOG_MINIMAL 1 /* 1 for minimal logging: E, W and A */ + +#if LOG_MINIMAL + + void logMinimal(int component, int level, const char *format, ...) __attribute__((format(printf, 3, 4))); +# define LOG_E(COMPONENT, ...) do if (1) logMinimal(COMPONENT, 'E', __VA_ARGS__); while (0) +# define LOG_W(COMPONENT, ...) do if (1) logMinimal(COMPONENT, 'W', __VA_ARGS__); while (0) +# define LOG_A(COMPONENT, ...) do if (1) logMinimal(COMPONENT, 'A', __VA_ARGS__); while (0) /* logs intended for analysis */ +# define LOG_I(COMPONENT, ...) do if (1) logMinimal(COMPONENT, 'I', __VA_ARGS__); while (0) +# define LOG_D(COMPONENT, ...) do if (0) logMinimal(COMPONENT, 'D', __VA_ARGS__); while (0) +# define LOG_T(COMPONENT, ...) do if (0) logMinimal(COMPONENT, 'T', __VA_ARGS__); while (0) + +# define LOG_M(FILE, VECTOR, DATA, LEN, DEC, FORMAT) ((void) 0) +# define LOG_DUMPFLAG(D) 0 +# define LOG_DEBUGFLAG(D) 0 +# define LOG_DUMPMSG(C, B, S, X...) ((void) 0) +# define VLOG(C, L, F, ARGS) ((void) 0) + +#else // LOG_MINIMAL + # if T_TRACER /* per component, level dependent macros */ # define LOG_E(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_ERR ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_ERR, x) ;} else { T(T_LEGACY_ ## c ## _ERROR, T_PRINTF(x)) ;}} while (0) # define LOG_W(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_WARNING) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_WARNING, x) ;} else { T(T_LEGACY_ ## c ## _WARNING, T_PRINTF(x)) ;}} while (0) +# define LOG_A LOG_I # define LOG_I(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_INFO ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_INFO, x) ;} else { T(T_LEGACY_ ## c ## _INFO, T_PRINTF(x)) ;}} while (0) # define LOG_D(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_DEBUG ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_DEBUG, x) ;} else { T(T_LEGACY_ ## c ## _DEBUG, T_PRINTF(x)) ;}} while (0) # define LOG_T(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_TRACE ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_TRACE, x) ;} else { T(T_LEGACY_ ## c ## _TRACE, T_PRINTF(x)) ;}} while (0) @@ -425,6 +453,7 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int # define LOG_E(c, x...) do { if( g_log->log_component[c].level >= OAILOG_ERR ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_ERR, x) ;} while (0) # define LOG_W(c, x...) do { if( g_log->log_component[c].level >= OAILOG_WARNING) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_WARNING, x) ;} while (0) # define LOG_I(c, x...) do { if( g_log->log_component[c].level >= OAILOG_INFO ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_INFO, x) ;} while (0) +# define LOG_A LOG_I # define LOG_D(c, x...) do { if( g_log->log_component[c].level >= OAILOG_DEBUG ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_DEBUG, x) ;} while (0) # define LOG_T(c, x...) do { if( g_log->log_component[c].level >= OAILOG_TRACE ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_TRACE, x) ;} while (0) # define VLOG(c,l, f, args) do { if( g_log->log_component[c].level >= l ) vlogRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, l, f, args) ; } while (0) @@ -438,6 +467,8 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int # define LOG_VAR(A,B) A B # define T_ACTIVE(a) (0) # endif /* T_TRACER */ +#endif // LOG_MINIMAL + /* avoid warnings for variables only used in LOG macro's but set outside debug section */ #define GCC_NOTUSED __attribute__((unused)) #define LOG_USEDINLOG_VAR(A,B) GCC_NOTUSED A B diff --git a/common/utils/ocp_itti/intertask_interface.cpp b/common/utils/ocp_itti/intertask_interface.cpp index 1c9b50d2f2..44fae9f788 100644 --- a/common/utils/ocp_itti/intertask_interface.cpp +++ b/common/utils/ocp_itti/intertask_interface.cpp @@ -438,9 +438,22 @@ extern "C" { void itti_send_terminate_message(task_id_t task_id) { } + static volatile bool shutting_down; + + static void catch_sigterm(int) { + static const char msg[] = "\n** Caught SIGTERM, shutting down\n"; + __attribute__((unused)) + int unused = write(STDOUT_FILENO, msg, sizeof(msg) - 1); + shutting_down = true; + } + void itti_wait_tasks_end(void) { - while(1) - sleep(24*3600); + shutting_down = false; + signal(SIGTERM, catch_sigterm); + while (! shutting_down) + { + sleep(24 * 3600); + } } void itti_update_lte_time(uint32_t frame, uint8_t slot) {} @@ -455,4 +468,42 @@ extern "C" { int signal_mask(void) { return 0; } + +void log_scheduler(const char* label) +{ + int policy = sched_getscheduler(0); + struct sched_param param; + if (sched_getparam(0, ¶m) == -1) + { + LOG_E(HW, "sched_getparam: %s\n", strerror(errno)); + abort(); + } + + cpu_set_t cpu_set; + if (sched_getaffinity(0, sizeof(cpu_set), &cpu_set) == -1) + { + LOG_E(HW, "sched_getaffinity: %s\n", strerror(errno)); + abort(); + } + int num_cpus = sysconf(_SC_NPROCESSORS_ONLN); + if (num_cpus < 1) + { + LOG_E(HW, "sysconf(_SC_NPROCESSORS_ONLN): %s\n", strerror(errno)); + abort(); + } + char buffer[num_cpus]; + for (int i = 0; i < num_cpus; i++) + { + buffer[i] = CPU_ISSET(i, &cpu_set) ? 'Y' : '-'; + } + + LOG_A(HW, "Scheduler policy=%d priority=%d affinity=[%d]%.*s label=%s\n", + policy, + param.sched_priority, + num_cpus, + num_cpus, + buffer, + label); } +} // extern "C" + diff --git a/common/utils/ocp_itti/intertask_interface.h b/common/utils/ocp_itti/intertask_interface.h index 7c17a6f3b1..3188e5889f 100644 --- a/common/utils/ocp_itti/intertask_interface.h +++ b/common/utils/ocp_itti/intertask_interface.h @@ -346,6 +346,8 @@ void *rrc_enb_process_msg(void *); TASK_DEF(TASK_DU_F1, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_RRC_UE_SIM, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_RRC_GNB_SIM, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_RRC_NSA_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_RRC_NSA_NRUE, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_NAS_NRUE, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_MAX, TASK_PRIORITY_MED, 200, NULL, NULL) @@ -362,6 +364,8 @@ typedef enum { FOREACH_TASK(TASK_ENUM) } task_id_t; +extern uint16_t ue_idx_standalone; +extern uint16_t node_number; typedef task_id_t thread_id_t; @@ -586,6 +590,7 @@ int timer_remove(long timer_id); int signal_handle(int *end); int signal_mask(void); +void log_scheduler(const char *label); #ifdef __cplusplus } #endif diff --git a/common/utils/utils.c b/common/utils/utils.c index 7f7aafc94a..f0f3ddf8a7 100644 --- a/common/utils/utils.c +++ b/common/utils/utils.c @@ -2,6 +2,9 @@ #include #include #include +#include +#include +#include #include "utils.h" void *calloc_or_fail(size_t size) { @@ -22,6 +25,32 @@ void *malloc_or_fail(size_t size) { return ptr; } +const char *hexdump(const void *data, size_t data_len, char *out, size_t out_len) +{ + char *p = out; + char *endp = out + out_len; + const uint8_t *q = data; + snprintf(p, endp - p, "[%zu]", data_len); + p += strlen(p); + for (size_t i = 0; i < data_len; ++i) + { + if (p >= endp) + { + static const char ellipses[] = "..."; + char *s = endp - sizeof(ellipses); + if (s >= p) + { + strcpy(s, ellipses); + } + break; + } + snprintf(p, endp - p, " %02X", *q++); + p += strlen(p); + } + return out; +} + + /**************************************************************************** ** ** ** Name: hex_char_to_hex_value() ** @@ -111,3 +140,32 @@ void *memcpy1(void *dst,const void *src,size_t n) { asm volatile("rep movsb" : "+D" (dst) : "c"(n), "S"(src) : "cc","memory"); return(ret); } + +void set_priority(int priority) +{ + /* When running with a realtime scheduler, a buggy run-away process can take + down the host requiring a reboot to recover. To avoid this scenario, we + use alarm(2) to set a maximum running time */ + unsigned max_runtime_seconds = 10 * 60; /* default */ + const char *env = getenv("MAX_RUNTIME_SECONDS"); + if (env != NULL) + { + max_runtime_seconds = atoi(env); + } + unsigned was_alarm = alarm(max_runtime_seconds); + /* Normally, was_alarm should be 0 indicating there was no previous alarm set. + A non-zero value could indicate a mistake */ + fprintf(stderr, "Set alarm for %u seconds, was %u (see $MAX_RUNTIME_SECONDS)\n", + max_runtime_seconds, was_alarm); + + struct sched_param param = + { + .sched_priority = priority, + }; + fprintf(stderr, "Calling sched_setscheduler(%d)\n", priority); + if (sched_setscheduler(0, SCHED_RR, ¶m) == -1) + { + fprintf(stderr, "sched_setscheduler: %s\n", strerror(errno)); + abort(); + } +} diff --git a/common/utils/utils.h b/common/utils/utils.h index 16631586c4..d4337e71a6 100644 --- a/common/utils/utils.h +++ b/common/utils/utils.h @@ -10,6 +10,7 @@ extern "C" { #define sizeofArray(a) (sizeof(a)/sizeof(*(a))) void *calloc_or_fail(size_t size); void *malloc_or_fail(size_t size); +const char *hexdump(const void *data, size_t data_len, char *out, size_t out_len); // Converts an hexadecimal ASCII coded digit into its value. ** int hex_char_to_hex_value (char c); @@ -18,6 +19,7 @@ int hex_string_to_hex_value (uint8_t *hex_value, const char *hex_string, int siz void *memcpy1(void *dst,const void *src,size_t n); +void set_priority(int priority); char *itoa(int i); diff --git a/doc/episys/Channel_Abstraction_UE_Handling_LTE.PNG b/doc/episys/Channel_Abstraction_UE_Handling_LTE.PNG new file mode 100644 index 0000000000..5e40d6ac17 Binary files /dev/null and b/doc/episys/Channel_Abstraction_UE_Handling_LTE.PNG differ diff --git a/doc/episys/Proxy_Interface_Diagram.PNG b/doc/episys/Proxy_Interface_Diagram.PNG new file mode 100644 index 0000000000..a734f3d4b0 Binary files /dev/null and b/doc/episys/Proxy_Interface_Diagram.PNG differ diff --git a/doc/episys/functional_diagram_proxy_lte.png b/doc/episys/functional_diagram_proxy_lte.png new file mode 100644 index 0000000000..e2a3a2c868 Binary files /dev/null and b/doc/episys/functional_diagram_proxy_lte.png differ diff --git a/doc/episys/functional_diagram_proxy_nsa.png b/doc/episys/functional_diagram_proxy_nsa.png new file mode 100644 index 0000000000..4a555d12ea Binary files /dev/null and b/doc/episys/functional_diagram_proxy_nsa.png differ diff --git a/doc/episys/lte_mode_l2_emulator/README.txt b/doc/episys/lte_mode_l2_emulator/README.txt new file mode 100644 index 0000000000..7b555b8442 --- /dev/null +++ b/doc/episys/lte_mode_l2_emulator/README.txt @@ -0,0 +1,49 @@ +There are fundamental changes to the L2 emulation mechanism; these changes allow the +user to run multiple UEs in separate Linux processes/machines/VMs/etc. They use a separate +entity between the UE(s) and eNB. The UEs use nFAPI to communicate with the eNB. The +nFAPI interface allows us to run in an emulated layer 2 mode, meaning that we are bypassing +the layer 1 (PHY) functionality. Because we are bypassing the PHY layer, +channel modeling capabilties have been added in the LTE UE phy_stub_ue.c file. To understand +the interfaces between the different components associated with LTE mode, the image +functional_diagram_proxy_lte.png has been provided. + +This functionality allows the user to plug in their own channel model and emulate the packet dropping procedure +in real time. The channel modeling has not been provided by EpiSci, but the OAI code +base already has some BLER curves available for use. The channel modeling functionality +that is included in the phy_stub_ue.c file only includes the downlink channel modeling. +Any uplink channel modeling must be conducted in some sort of proxy, which would sit +between the UEs and eNB. (A description of the downlink channel modeling is shown in the +Channel_Abstraction_UE_Handling_LTE.PNG image). + +The updates to the OAI code base removed some latent bugs, added multi-UE scalability, +and were tested with a standard bypass proxy between the UE(s) and eNB. The bypass proxy is +publicly available on GitHub (https://github.com/EpiSci/oai-lte-multi-ue-proxy). With this package, +various multi-UE scenarios can be tested without the overhead of PHY-layer features +of underlying radios. The features added in the L2 Emulator Mode for LTE are: + + - Ease of use of gprof and address sanitizer for debugging purposes + - Updated json files to allow for GDB, real-time debugging capabilities + - Updated logging features to minimally log only key connection milestones. This improves scalability of multiple UEs. +The logging mechanism described here is located in the log.c and log.h files. The LOG_MINIMAL +function allows us to remove most OAI logging and includes LOG_A(...) logs and above. The LOG_A +logs were chosen as analysis logs to meet EpiSci's internal testing procedure. The LOG_As +only include logs that are considered to be milestones in a given test. For example, a +log indicating that the RACH procedure has been completed for LTE. To select full logging, +set LOG_MINIMAL = 0 in the log.h file. + - Updated logging to include time stamp for timing analysis + - Updated memory allocation procedures to correct size requirements + - Added debugging features to handle signal terminations + - nfapi.c pullarray8 fix invalid pointer math + - Overlapping destination and source memory in memcpy, so updated to memmove to check for this bug + - Advanced error checking mechanisms in critical pack and unpack functions + - Created option for CPU assignment to UE to improve scalability + - Added EPC integration to allow multiple individual UE entities to each have their USIM information parsed by the executables + - Updated random value seeds to minimize probability of error in generation of random values + - Enables capability round robin scheduler if desired + - Enables capability real time scheduler if desired + - Added new standalone functions to the UE phy-layer (phy_stub_ue.c) to incorporate individual UE entities + - Updated sending and packing functions in UE (lte_ue.c) to incorporate new standalone changes + - Incorporated semaphores to control timing of incoming downlink packets + - Implemented new queuing system to handle message exchange from UE to eNB and vice versa + - Updated global value in nFAPI for size of subframe + - Updated global value to increase scalability in system diff --git a/doc/episys/nsa_mode_l2_emulator/README.txt b/doc/episys/nsa_mode_l2_emulator/README.txt new file mode 100644 index 0000000000..fefaf63f44 --- /dev/null +++ b/doc/episys/nsa_mode_l2_emulator/README.txt @@ -0,0 +1,94 @@ +There are fundamental changes to the L2 emulation mechanism; these changes allow the +user to run multiple UEs in separate Linux processes/machines/VMs/etc. They use a separate +entity between the UE(s) and eNB/gNB. The UEs use nFAPI to communicate with the eNB/gNB. The +nFAPI interface allows us to run in an emulated L2 mode, meaning that we are bypassing +the layer 1 (PHY) layer functionality. Becasue we are bypassing the PHY layer, special +channel modeling capabilty has been added in the LTE UE phy_stub_ue.c file. To understand +the interfaces between the different components associated with NSA mode, the image +functional_diagram_proxy_nsa.png has been provided. + +This functionality allows the user to plug in their own channel model and emulate the packet dropping procedure +in real time. The channel modeling has not been provided by EpiSci, but the OAI code +base already has some BLER curves available for use. The chanel modeling functionality +that is included in the phy_stub_ue.c file only includes the downlink channel modeling. +Any uplink channel modeling must be conducted in some sort of proxy, which would sit +between the UEs and eNB/gNB. (A description of the downlink channel modeling is shown in the +Channel_Abstraction_UE_Handling_LTE.PNG image). + +The updates to the OAI code base removed some latent bugs, added multi-UE scalability, +and were tested with a standard bypass proxy between the UE(s) and eNB/gNB. The bypass proxy is +publicly available on GitHub (https://github.com/EpiSci/oai-lte-multi-ue-proxy). With this package, +various multi-UE scenarios can be tested without the overhead of PHY-layer features +of underlying radios. The added features to the OAI code base are listed below. + + - Ease of use of gprof and address sanitizer for debugging purposes + - Updated json files to allow for GDB, real-time debugging capabilities + - Updated logging features to minimally log only key connection milestones. This improves scalability of multiple UEs. +The logging mechanism described here is located in the log.c and log.h files. The LOG_MINIMAL +function allows us to remove most logs and include LOG_A(...) logs and above. The LOG_A +logs were chosen as analysis logs to meet EpiSci's internal testing procedure. The LOG_As +only include logs that are considered to be milestones in a given test. For example, a +log indicating that the CFRA procedure has been completed for NSA mode. To revert to full logging, +set LOG_MINIMAL = 0 in the log.h file. + - Updated logging to include time stamp for timing analysis + - Updated memory allocation procedures to correct size requirements + - Added debugging features to handle signal terminations + - nfapi.c pullarray8 fix invalid pointer math + - Overlapping destination and source memory in memcpy, so updated to memmove to check for this bug + - Advanced error checking mechanisms in critical pack and unpack functions + - Created option for CPU assignment to UE to improve scalability + - Added EPC integration to allow multiple individual UE entities to each have their USIM information parsed by the executables + - Updated random value seeds to minimize probability of error in generation of random values + - Enables capability round robin scheduler if desired + - Enables capability real time scheduler if desired + - Added new standalone functions to the UE phy-layer (phy_stub_ue.c) to incorporate individual UE entities + - Updated sending and packing functions in UE (lte_ue.c) to incorporate new standalone changes + - Incorporated semaphores to control timing of incoming downlink packets + - Implemented new queuing system to handle message exchange from UE to eNB and vice versa + - Updated global value in nFAPI for size of subframe + - Updated global value to increase scalability in system + + +Additionally, NSA mode includes the establishment between an NR UE and the gNB via the LTE UE and eNB +connection. For NSA mode, the downlink channel abstraction has not been added to the feature set yet. +NSA mode has been tested and is fully functional with EpiSci's public version of the nFAPI proxy +located at https://github.com/EpiSci/oai-lte-multi-ue-proxy +NSA mode establishment includes the following steps: + + - First UE capability enquiry is sent to NR UE + - NR UE updates and fills first capability enquiry + - eNB request for a measurement report + - Measurement request is sent to NR UE + - Measurement report is filled in NR UE + - Measurement report is received in eNB + - Request for second UE capability enquiry + - Send second enquiry to NR UE + - Second capability information is filled by NR UE + - Second capability information is sent to eNB + - NR UE capability information is received in gNB + - Periodic measurement report received in gNB + - RRCReconfigurationRequest is sent to NR UE + - RRCReconfigurationComplete is sent from NR UE + - RACH is received in the gNB + - RAR is received in NR UE + - Msg 3 is generated and sent to gNB + - CFRA procedure is complete + +Please note, the current status is: + - A single NSA UE is able to ping an external source + - Up to 4 NSA UEs can complete the CFRA procedure with a single gNB + - UE-to-UE traffic is still in work (incomplete due to gNB crashing) + - The gNB is crashing regularly and is still in work + +Test Setup: +For launching the multi-UE for NSA mode, there is a provided test script in the +public EpiSci GitHub multi-ue-proxy repository. However, a brief outline of the +test set up is included below. + + If running multiple NSA UEs in a single machine, you will need to launch + multiple LTE and NR UE processes. For example, to launch a 2 NSA UE scenario + there will be a total of 7 processes running for this particular scenario. + These processes are LTE UE #1, LTE UE #2, NR UE #1, NR UE #2, eNB, gNB and the + proxy. A detailed description of the launch processes can be found at + https://github.com/EpiSci/oai-lte-multi-ue-proxy/blob/master/README.md + diff --git a/executables/main-fs6.c b/executables/main-fs6.c index 438edb4044..9e92f2e41a 100644 --- a/executables/main-fs6.c +++ b/executables/main-fs6.c @@ -553,7 +553,11 @@ void fill_rx_indication_from_split(uint8_t *bufferZone, PHY_VARS_eNB *eNB,int UE pdu->rx_indication_rel8.tl.tag = NFAPI_RX_INDICATION_REL8_TAG; pdu->rx_indication_rel8.length = eNB->ulsch[UE_id]->harq_processes[harq_pid]->TBS>>3; pdu->rx_indication_rel8.offset = 1; // DJP - I dont understand - but broken unless 1 ???? 0; // filled in at the end of the UL_INFO formation - pdu->data = eNB->ulsch[UE_id]->harq_processes[harq_pid]->decodedBytes; + AssertFatal(pdu->rx_indication_rel8.length <= NFAPI_RX_IND_DATA_MAX, "Invalid PDU len %d\n", + pdu->rx_indication_rel8.length); + memcpy(pdu->rx_ind_data, + eNB->ulsch[UE_id]->harq_processes[harq_pid]->decodedBytes, + pdu->rx_indication_rel8.length); // estimate timing advance for MAC timing_advance_update = ul_propa[UE_id].ta; diff --git a/executables/main-ocp.c b/executables/main-ocp.c index 69fb438906..7ee685f2b3 100644 --- a/executables/main-ocp.c +++ b/executables/main-ocp.c @@ -1043,7 +1043,7 @@ void init_pdcp(void) { pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_W_MBMS_BIT; if ( split73!=SPLIT73_DU) - pdcp_module_init(pdcp_initmask); + pdcp_module_init(pdcp_initmask, 0); if (NODE_IS_CU(RC.rrc[0]->node_type)) { //pdcp_set_rlc_data_req_func(proto_agent_send_rlc_data_req); @@ -1057,14 +1057,14 @@ void init_pdcp(void) { } static void wait_nfapi_init(char *thread_name) { - printf( "waiting for NFAPI PNF connection and population of global structure (%s)\n",thread_name); + LOG_I(ENB_APP, "waiting for NFAPI PNF connection and population of global structure (%s)\n",thread_name); pthread_mutex_lock( &nfapi_sync_mutex ); while (nfapi_sync_var<0) pthread_cond_wait( &nfapi_sync_cond, &nfapi_sync_mutex ); pthread_mutex_unlock(&nfapi_sync_mutex); - printf( "NFAPI: got sync (%s)\n", thread_name); + LOG_I(ENB_APP, "NFAPI: got sync (%s)\n", thread_name); } void terminate_task(module_id_t mod_id, task_id_t from, task_id_t to) { diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index dc8960846f..4fe8cfa1bf 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -240,7 +240,6 @@ void rx_func(void *param) { // RX processing int tx_slot_type = nr_slot_select(cfg,frame_tx,slot_tx); int rx_slot_type = nr_slot_select(cfg,frame_rx,slot_rx); - if (rx_slot_type == NR_UPLINK_SLOT || rx_slot_type == NR_MIXED_SLOT) { // UE-specific RX processing for subframe n // TODO: check if this is correct for PARALLEL_RU_L1_TRX_SPLIT @@ -451,7 +450,9 @@ void init_gNB_Tpool(int inst) { msgData->next_slot = get_next_downlink_slot(gNB, &gNB->gNB_config, 0, first_tx_slot-1); pushNotifiedFIFO(gNB->resp_RU_tx,msgRUTx); // to unblock the process in the beginning - threadCreate(&proc->L1_stats_thread,nrL1_stats_thread,(void*)gNB,"L1_stats",-1,OAI_PRIORITY_RT_LOW); + if (!get_softmodem_params()->emulate_l1) { + threadCreate(&proc->L1_stats_thread,nrL1_stats_thread,(void*)gNB,"L1_stats",-1,OAI_PRIORITY_RT_LOW); + } } diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 3a2589632b..a2539a3adf 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -80,7 +80,8 @@ static int DEFBFW[] = {0x00007fff}; extern volatile int oai_exit; - +extern struct timespec timespec_sub(struct timespec lhs, struct timespec rhs); +extern struct timespec timespec_add(struct timespec lhs, struct timespec rhs); extern void nr_phy_free_RU(RU_t *); extern void nr_phy_config_request(NR_PHY_Config_t *gNB); #include "executables/thread-common.h" @@ -1323,9 +1324,35 @@ void *ru_thread( void *param ) { } // This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices + struct timespec slot_start; + clock_gettime(CLOCK_MONOTONIC, &slot_start); + + struct timespec slot_duration; + slot_duration.tv_sec = 0; + //slot_duration.tv_nsec = 0.5e6; + slot_duration.tv_nsec = 0.5e6; + + + while (!oai_exit) { // these are local subframe/frame counters to check that we are in synch with the fronthaul timing. // They are set on the first rx/tx in the underly FH routines. + slot_start = timespec_add(slot_start,slot_duration); + struct timespec curr_time; + clock_gettime(CLOCK_MONOTONIC, &curr_time); + + struct timespec sleep_time; + + if((slot_start.tv_sec > curr_time.tv_sec) || (slot_start.tv_sec == curr_time.tv_sec && slot_start.tv_nsec > curr_time.tv_nsec)){ + sleep_time = timespec_sub(slot_start,curr_time); + + usleep(sleep_time.tv_nsec * 1e-3); + } + else{//continue + } + + // clock_gettime(CLOCK_MONOTONIC, &curr_time); + //printf("sfn:%d, slot:%d, start time %d.%d slot start %d.%d \n",frame,slot,curr_time.tv_sec,curr_time.tv_nsec,slot_start.tv_sec,slot_start.tv_nsec); if (slot==(fp->slots_per_frame-1)) { slot=0; frame++; diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index c012e9f57d..62bef5a34d 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -596,8 +596,33 @@ static void wait_nfapi_init(char *thread_name) { } void init_pdcp(void) { - if (!NODE_IS_DU(RC.nrrrc[0]->node_type)) { - // pdcp_layer_init(); + if (!get_softmodem_params()->nsa) { + if (!NODE_IS_DU(RC.nrrrc[0]->node_type)) { + //pdcp_layer_init(); + uint32_t pdcp_initmask = (IS_SOFTMODEM_NOS1) ? + (PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT) : LINK_ENB_PDCP_TO_GTPV1U_BIT; + + if (IS_SOFTMODEM_NOS1) { + printf("IS_SOFTMODEM_NOS1 option enabled \n"); + pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT; + } + + nr_pdcp_module_init(pdcp_initmask, 0); + + if (NODE_IS_CU(RC.nrrrc[0]->node_type)) { + LOG_I(PDCP, "node is CU, pdcp send rlc_data_req by proto_agent \n"); + pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t)proto_agent_send_rlc_data_req); + } else { + LOG_I(PDCP, "node is gNB \n"); + pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req); + pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind); + } + } else { + LOG_I(PDCP, "node is DU, rlc send pdcp_data_ind by proto_agent \n"); + pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) proto_agent_send_pdcp_data_ind); + } + } else { + pdcp_layer_init(); uint32_t pdcp_initmask = (IS_SOFTMODEM_NOS1) ? (PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT) : LINK_ENB_PDCP_TO_GTPV1U_BIT; @@ -606,19 +631,9 @@ void init_pdcp(void) { pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT; } - pdcp_module_init(pdcp_initmask); - - if (NODE_IS_CU(RC.nrrrc[0]->node_type)) { - LOG_I(PDCP, "node is CU, pdcp send rlc_data_req by proto_agent \n"); - pdcp_set_rlc_data_req_func(proto_agent_send_rlc_data_req); - } else { - LOG_I(PDCP, "node is gNB \n"); - pdcp_set_rlc_data_req_func(rlc_data_req); - pdcp_set_pdcp_data_ind_func(pdcp_data_ind); - } - } else { - LOG_I(PDCP, "node is DU, rlc send pdcp_data_ind by proto_agent \n"); - pdcp_set_pdcp_data_ind_func(proto_agent_send_pdcp_data_ind); + nr_pdcp_module_init(pdcp_initmask, 0); + pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req); + pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind); } } @@ -645,6 +660,8 @@ int main( int argc, char **argv ) { printf("Reading in command-line options\n"); get_options (); + EPC_MODE_ENABLED = !IS_SOFTMODEM_NOS1; + if (CONFIG_ISFLAGSET(CONFIG_ABORT) ) { fprintf(stderr,"Getting configuration failed\n"); exit(-1); @@ -676,10 +693,12 @@ int main( int argc, char **argv ) { // initialize mscgen log after ITTI MSC_INIT(MSC_E_UTRAN, ADDED_QUEUES_MAX+TASK_MAX); init_opt(); - if(PDCP_USE_NETLINK) - if(!IS_SOFTMODEM_NOS1) - netlink_init(); - + if(PDCP_USE_NETLINK && !IS_SOFTMODEM_NOS1) { + netlink_init(); + if (get_softmodem_params()->nsa) { + init_pdcp(); + } + } #ifndef PACKAGE_VERSION # define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL" #endif diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 362ad80e9d..46c1cff491 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -29,7 +29,9 @@ #include "SCHED_NR_UE/defs.h" #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" #include "executables/softmodem-common.h" +#include "LAYER2/nr_pdcp/nr_pdcp_entity.h" #include "SCHED_NR_UE/pucch_uci_ue_nr.h" +#include "openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h" /* * NR SLOT PROCESSING SEQUENCE @@ -98,6 +100,10 @@ typedef enum { si = 2 } sync_mode_t; +queue_t nr_rach_ind_queue; + +static void *NRUE_phy_stub_standalone_pnf_task(void *arg); + void init_nr_ue_vars(PHY_VARS_NR_UE *ue, uint8_t UE_id, uint8_t abstraction_flag) @@ -126,6 +132,382 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue, init_N_TA_offset(ue); } +void init_nrUE_standalone_thread(int ue_idx) +{ + int standalone_tx_port = 3611 + ue_idx * 2; + int standalone_rx_port = 3612 + ue_idx * 2; + nrue_init_standalone_socket(standalone_tx_port, standalone_rx_port); + + NR_UE_MAC_INST_t *mac = get_mac_inst(0); + pthread_mutex_init(&mac->mutex_dl_info, NULL); + + pthread_t thread; + if (pthread_create(&thread, NULL, nrue_standalone_pnf_task, NULL) != 0) { + LOG_E(NR_MAC, "pthread_create failed for calling nrue_standalone_pnf_task"); + } + pthread_setname_np(thread, "oai:nrue-stand"); + pthread_t phy_thread; + if (pthread_create(&phy_thread, NULL, NRUE_phy_stub_standalone_pnf_task, NULL) != 0) { + LOG_E(NR_MAC, "pthread_create failed for calling NRUE_phy_stub_standalone_pnf_task"); + } + pthread_setname_np(phy_thread, "oai:nrue-stand-phy"); +} + +static void L1_nsa_prach_procedures(frame_t frame, int slot, fapi_nr_ul_config_prach_pdu *prach_pdu) +{ + NR_UE_MAC_INST_t *mac = get_mac_inst(0); + nfapi_nr_rach_indication_t *rach_ind = CALLOC(1, sizeof(*rach_ind)); + rach_ind->sfn = frame; + rach_ind->slot = slot; + rach_ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION; + + uint8_t pdu_index = 0; + rach_ind->pdu_list = CALLOC(1, sizeof(*rach_ind->pdu_list)); + rach_ind->number_of_pdus = 1; + rach_ind->pdu_list[pdu_index].phy_cell_id = prach_pdu->phys_cell_id; + rach_ind->pdu_list[pdu_index].symbol_index = prach_pdu->prach_start_symbol; + rach_ind->pdu_list[pdu_index].slot_index = prach_pdu->prach_slot; + rach_ind->pdu_list[pdu_index].freq_index = prach_pdu->num_ra; + rach_ind->pdu_list[pdu_index].avg_rssi = 128; + rach_ind->pdu_list[pdu_index].avg_snr = 0xff; // invalid for now + + rach_ind->pdu_list[pdu_index].num_preamble = 1; + const int num_p = rach_ind->pdu_list[pdu_index].num_preamble; + rach_ind->pdu_list[pdu_index].preamble_list = calloc(num_p, sizeof(nfapi_nr_prach_indication_preamble_t)); + uint8_t preamble_index = get_softmodem_params()->nsa ? + mac->ra.rach_ConfigDedicated->cfra->resources.choice.ssb->ssb_ResourceList.list.array[0]->ra_PreambleIndex : + mac->ra.ra_PreambleIndex; + rach_ind->pdu_list[pdu_index].preamble_list[0].preamble_index = preamble_index; + + rach_ind->pdu_list[pdu_index].preamble_list[0].timing_advance = 0; + rach_ind->pdu_list[pdu_index].preamble_list[0].preamble_pwr = 0xffffffff; + + if (!put_queue(&nr_rach_ind_queue, rach_ind)) + { + for (int pdu_index = 0; pdu_index < rach_ind->number_of_pdus; pdu_index++) + { + free(rach_ind->pdu_list[pdu_index].preamble_list); + } + free(rach_ind->pdu_list); + free(rach_ind); + } + LOG_D(NR_MAC, "We have successfully filled the rach_ind queue with the recently filled rach ind\n"); +} + +static bool sfn_slot_matcher(void *wanted, void *candidate) +{ + nfapi_p7_message_header_t *msg = candidate; + int sfn_sf = *(int*)wanted; + + switch (msg->message_id) + { + case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION: + { + nfapi_nr_rach_indication_t *ind = candidate; + return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->sfn && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->slot; + } + + case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION: + { + nfapi_nr_rx_data_indication_t *ind = candidate; + return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->sfn && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->slot; + } + + case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION: + { + nfapi_nr_crc_indication_t *ind = candidate; + return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->sfn && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->slot; + } + + case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION: + { + nfapi_nr_uci_indication_t *ind = candidate; + return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->sfn && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->slot; + } + + case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST: + { + nfapi_nr_dl_tti_request_t *ind = candidate; + return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->SFN && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->Slot; + } + + case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST: + { + nfapi_nr_tx_data_request_t *ind = candidate; + return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->SFN && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->Slot; + } + + case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST: + { + nfapi_nr_ul_dci_request_t *ind = candidate; + return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->SFN && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->Slot; + } + + case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST: + { + nfapi_nr_ul_tti_request_t *ind = candidate; + return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->SFN && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->Slot; + } + + default: + LOG_E(NR_MAC, "sfn_slot_match bad ID: %d\n", msg->message_id); + + } + + return false; +} + +static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn_slot) +{ + nfapi_nr_rach_indication_t *rach_ind = unqueue_matching(&nr_rach_ind_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &sfn_slot); + nfapi_nr_rx_data_indication_t *rx_ind = unqueue_matching(&nr_rx_ind_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &sfn_slot); + nfapi_nr_crc_indication_t *crc_ind = unqueue_matching(&nr_crc_ind_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &sfn_slot); + nfapi_nr_dl_tti_request_t *dl_tti_request = get_queue(&nr_dl_tti_req_queue); + nfapi_nr_ul_dci_request_t *ul_dci_request = get_queue(&nr_ul_dci_req_queue); + + LOG_D(NR_MAC, "Try to get a ul_tti_req for sfn/slot %d %d from queue with %lu items\n", + NFAPI_SFNSLOT2SFN(mac->nr_ue_emul_l1.active_harq_sfn_slot),NFAPI_SFNSLOT2SLOT(mac->nr_ue_emul_l1.active_harq_sfn_slot), nr_ul_tti_req_queue.num_items); + nfapi_nr_ul_tti_request_t *ul_tti_request = unqueue_matching(&nr_ul_tti_req_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &mac->nr_ue_emul_l1.active_harq_sfn_slot); + if (!ul_tti_request) + { + LOG_D(NR_MAC, "Try to get a ul_tti_req from seprate queue because dl_tti_req was late\n"); + ul_tti_request = unqueue_matching(&nr_wait_ul_tti_req_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &mac->nr_ue_emul_l1.active_harq_sfn_slot); + } + + if (rach_ind && rach_ind->number_of_pdus > 0) + { + NR_UL_IND_t UL_INFO = { + .rach_ind = *rach_ind, + }; + send_nsa_standalone_msg(&UL_INFO, rach_ind->header.message_id); + for (int i = 0; i < rach_ind->number_of_pdus; i++) + { + free(rach_ind->pdu_list[i].preamble_list); + } + free(rach_ind->pdu_list); + free(rach_ind); + nr_Msg1_transmitted(0, 0, NFAPI_SFNSLOT2SFN(sfn_slot), 0); + } + if (crc_ind && crc_ind->number_crcs > 0) + { + NR_UL_IND_t UL_INFO = { + .crc_ind = *crc_ind, + }; + send_nsa_standalone_msg(&UL_INFO, crc_ind->header.message_id); + free(crc_ind->crc_list); + free(crc_ind); + } + if (rx_ind && rx_ind->number_of_pdus > 0) + { + NR_UL_IND_t UL_INFO = { + .rx_ind = *rx_ind, + }; + send_nsa_standalone_msg(&UL_INFO, rx_ind->header.message_id); + free(rx_ind->pdu_list); + free(rx_ind); + } + if (dl_tti_request) + { + int dl_tti_sfn_slot = NFAPI_SFNSLOT2HEX(dl_tti_request->SFN, dl_tti_request->Slot); + nfapi_nr_tx_data_request_t *tx_data_request = unqueue_matching(&nr_tx_req_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &dl_tti_sfn_slot); + if (!tx_data_request) + { + LOG_E(NR_MAC, "[%d %d] No corresponding tx_data_request for given dl_tti_request sfn/slot\n", + NFAPI_SFNSLOT2SFN(dl_tti_sfn_slot), NFAPI_SFNSLOT2SLOT(dl_tti_sfn_slot)); + if (get_softmodem_params()->nsa) + save_nr_measurement_info(dl_tti_request); + free(dl_tti_request); + dl_tti_request = NULL; + } + else if (dl_tti_request->dl_tti_request_body.nPDUs > 0 && tx_data_request->Number_of_PDUs > 0) + { + if (get_softmodem_params()->nsa) + save_nr_measurement_info(dl_tti_request); + check_and_process_dci(dl_tti_request, tx_data_request, NULL, NULL); + } + else + { + AssertFatal(false, "We dont have PDUs in either dl_tti %d or tx_req %d\n", + dl_tti_request->dl_tti_request_body.nPDUs, tx_data_request->Number_of_PDUs); + } + } + if (ul_dci_request && ul_dci_request->numPdus > 0) + { + check_and_process_dci(NULL, NULL, ul_dci_request, NULL); + } + if (ul_tti_request && ul_tti_request->n_pdus > 0) + { + check_and_process_dci(NULL, NULL, NULL, ul_tti_request); + } +} + +static void check_nr_prach(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info, NR_PRACH_RESOURCES_t *prach_resources) +{ + fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, ul_info->slot_tx); + if (!ul_config) + { + LOG_E(NR_MAC, "mac->ul_config is null! \n"); + return; + } + if (mac->ra.ra_state != RA_SUCCEEDED) + { + AssertFatal(ul_config->number_pdus < sizeof(ul_config->ul_config_list) / sizeof(ul_config->ul_config_list[0]), + "Number of PDUS in ul_config = %d > ul_config_list num elements", ul_config->number_pdus); + fapi_nr_ul_config_prach_pdu *prach_pdu = &ul_config->ul_config_list[ul_config->number_pdus].prach_config_pdu; + uint8_t nr_prach = nr_ue_get_rach(prach_resources, + prach_pdu, + ul_info->module_id, + ul_info->cc_id, + ul_info->frame_tx, + ul_info->gNB_index, + ul_info->slot_tx); + if (nr_prach == 1) + { + L1_nsa_prach_procedures(ul_info->frame_tx, ul_info->slot_tx, prach_pdu); + ul_config->number_pdus = 0; + ul_info->ue_sched_mode = SCHED_ALL; + } + else if (nr_prach == 2) + { + LOG_I(NR_PHY, "In %s: [UE %d] RA completed, setting UE mode to PUSCH\n", __FUNCTION__, ul_info->module_id); + } + else if(nr_prach == 3) + { + LOG_I(NR_PHY, "In %s: [UE %d] RA failed, setting UE mode to PRACH\n", __FUNCTION__, ul_info->module_id); + } + } +} + +static void *NRUE_phy_stub_standalone_pnf_task(void *arg) +{ + LOG_I(MAC, "Clearing Queues\n"); + reset_queue(&nr_rach_ind_queue); + reset_queue(&nr_rx_ind_queue); + reset_queue(&nr_crc_ind_queue); + reset_queue(&nr_uci_ind_queue); + reset_queue(&nr_dl_tti_req_queue); + reset_queue(&nr_tx_req_queue); + reset_queue(&nr_ul_dci_req_queue); + reset_queue(&nr_ul_tti_req_queue); + reset_queue(&nr_wait_ul_tti_req_queue); + + NR_PRACH_RESOURCES_t prach_resources; + memset(&prach_resources, 0, sizeof(prach_resources)); + NR_UL_TIME_ALIGNMENT_t ul_time_alignment; + memset(&ul_time_alignment, 0, sizeof(ul_time_alignment)); + int last_sfn_slot = -1; + uint16_t sfn_slot = 0; + + while (!oai_exit) + { + if (sem_wait(&sfn_slot_semaphore) != 0) + { + LOG_E(NR_MAC, "sem_wait() error\n"); + abort(); + } + uint16_t *slot_ind = get_queue(&nr_sfn_slot_queue); + nr_phy_channel_params_t *ch_info = get_queue(&nr_chan_param_queue); + if (!slot_ind && !ch_info) + { + LOG_D(MAC, "get nr_sfn_slot_queue and nr_chan_param_queue == NULL!\n"); + continue; + } + if (slot_ind) { + sfn_slot = *slot_ind; + } + else if (ch_info) { + sfn_slot = ch_info->sfn_slot; + } + + frame_t frame = NFAPI_SFNSLOT2SFN(sfn_slot); + int slot = NFAPI_SFNSLOT2SLOT(sfn_slot); + if (sfn_slot == last_sfn_slot) + { + LOG_D(NR_MAC, "repeated sfn_sf = %d.%d\n", + frame, slot); + continue; + } + last_sfn_slot = sfn_slot; + + LOG_D(NR_MAC, "The received sfn/slot [%d %d] from proxy\n", + frame, slot); + + module_id_t mod_id = 0; + NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); + if (get_softmodem_params()->sa && mac->mib == NULL) + { + LOG_D(NR_MAC, "We haven't gotten MIB. Lets see if we received it\n"); + nr_ue_dl_indication(&mac->dl_info, &ul_time_alignment); + process_queued_nr_nfapi_msgs(mac, sfn_slot); + } + if (mac->scc == NULL && mac->scc_SIB == NULL) + { + LOG_D(MAC, "[NSA] mac->scc == NULL and [SA] mac->scc_SIB == NULL!\n"); + continue; + } + + mac->ra.generate_nr_prach = 0; + int CC_id = 0; + uint8_t gNB_id = 0; + nr_uplink_indication_t ul_info; + int slots_per_frame = 20; //30 kHZ subcarrier spacing + int slot_ahead = 2; // TODO: Make this dynamic + ul_info.cc_id = CC_id; + ul_info.gNB_index = gNB_id; + ul_info.module_id = mod_id; + ul_info.frame_rx = frame; + ul_info.slot_rx = slot; + ul_info.slot_tx = (slot + slot_ahead) % slots_per_frame; + ul_info.frame_tx = (ul_info.slot_rx + slot_ahead >= slots_per_frame) ? ul_info.frame_rx + 1 : ul_info.frame_rx; + ul_info.ue_sched_mode = SCHED_ALL; + + if (pthread_mutex_lock(&mac->mutex_dl_info)) abort(); + + memset(&mac->dl_info, 0, sizeof(mac->dl_info)); + mac->dl_info.cc_id = CC_id; + mac->dl_info.gNB_index = gNB_id; + mac->dl_info.module_id = mod_id; + mac->dl_info.frame = frame; + mac->dl_info.slot = slot; + mac->dl_info.thread_id = 0; + mac->dl_info.dci_ind = NULL; + mac->dl_info.rx_ind = NULL; + + if (is_nr_DL_slot(get_softmodem_params()->nsa ? + mac->scc->tdd_UL_DL_ConfigurationCommon : + mac->scc_SIB->tdd_UL_DL_ConfigurationCommon, + ul_info.slot_rx)) + { + nr_ue_dl_indication(&mac->dl_info, &ul_time_alignment); + } + + if (pthread_mutex_unlock(&mac->mutex_dl_info)) abort(); + + if (is_nr_UL_slot(get_softmodem_params()->nsa ? + mac->scc->tdd_UL_DL_ConfigurationCommon : + mac->scc_SIB->tdd_UL_DL_ConfigurationCommon, + ul_info.slot_tx, mac->frame_type)) + { + LOG_D(NR_MAC, "Slot %d. calling nr_ue_ul_ind() from %s\n", ul_info.slot_tx, __FUNCTION__); + nr_ue_ul_indication(&ul_info); + check_nr_prach(mac, &ul_info, &prach_resources); + } + if (!IS_SOFTMODEM_NOS1 && get_softmodem_params()->sa) { + NR_UE_MAC_INST_t *mac = get_mac_inst(0); + protocol_ctxt_t ctxt; + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_NO, mac->crnti, frame, slot, 0); + pdcp_run(&ctxt); + } + process_queued_nr_nfapi_msgs(mac, sfn_slot); + free(slot_ind); + slot_ind = NULL; + free(ch_info); + ch_info = NULL; + } + return NULL; +} + + /*! * It performs band scanning and synchonization. * \param arg is a pointer to a \ref PHY_VARS_NR_UE structure. diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 83cf4e7383..ac89bcfd4e 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -157,6 +157,7 @@ char uecap_xer[1024]; */ uint8_t abstraction_flag=0; + /*---------------------BMC: timespec helpers -----------------------------*/ struct timespec min_diff_time = { .tv_sec = 0, .tv_nsec = 0 }; @@ -190,10 +191,17 @@ int create_tasks_nrue(uint32_t ue_nb) { LOG_E(NR_RRC, "Create task for RRC UE failed\n"); return -1; } - if (itti_create_task (TASK_NAS_NRUE, nas_nrue_task, NULL) < 0) { - LOG_E(NR_RRC, "Create task for NAS UE failed\n"); - return -1; - } + if (get_softmodem_params()->nsa) { + init_connections_with_lte_ue(); + if (itti_create_task (TASK_RRC_NSA_NRUE, recv_msgs_from_lte_ue, NULL) < 0) { + LOG_E(NR_RRC, "Create task for RRC NSA nr-UE failed\n"); + return -1; + } + } + if (itti_create_task (TASK_NAS_NRUE, nas_nrue_task, NULL) < 0) { + LOG_E(NR_RRC, "Create task for NAS UE failed\n"); + return -1; + } } itti_wait_ready(0); @@ -371,25 +379,23 @@ void init_openair0(void) { } } -static void init_pdcp(void) { +static void init_pdcp(int ue_id) { uint32_t pdcp_initmask = (!IS_SOFTMODEM_NOS1) ? LINK_ENB_PDCP_TO_GTPV1U_BIT : (LINK_ENB_PDCP_TO_GTPV1U_BIT | PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT); /*if (IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM || (nfapi_getmode()==NFAPI_UE_STUB_PNF)) { pdcp_initmask = pdcp_initmask | UE_NAS_USE_TUN_BIT; }*/ - if (IS_SOFTMODEM_NOKRNMOD) + if (IS_SOFTMODEM_NOKRNMOD) { pdcp_initmask = pdcp_initmask | UE_NAS_USE_TUN_BIT; - - /*if (rlc_module_init() != 0) { + } + if (get_softmodem_params()->nsa && rlc_module_init(0) != 0) { LOG_I(RLC, "Problem at RLC initiation \n"); } pdcp_layer_init(); - nr_DRB_preconfiguration();*/ - pdcp_layer_init(); - pdcp_module_init(pdcp_initmask); - pdcp_set_rlc_data_req_func(rlc_data_req); - pdcp_set_pdcp_data_ind_func(pdcp_data_ind); + nr_pdcp_module_init(pdcp_initmask, ue_id); + pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req); + pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind); } // Stupid function addition because UE itti messages queues definition is common with eNB @@ -399,6 +405,13 @@ void *rrc_enb_process_msg(void *notUsed) { int main( int argc, char **argv ) { + set_priority(79); + if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) + { + fprintf(stderr, "mlockall: %s\n", strerror(errno)); + return EXIT_FAILURE; + } + //uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2; PHY_VARS_NR_UE *UE[MAX_NUM_CCs]; start_background_system(); @@ -441,13 +454,27 @@ int main( int argc, char **argv ) { LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); init_NR_UE(1,rrc_config_path); - if(IS_SOFTMODEM_NOS1 || get_softmodem_params()->sa) - init_pdcp(); + + int mode_offset = get_softmodem_params()->nsa ? NUMBER_OF_UE_MAX : 1; + uint16_t node_number = get_softmodem_params()->node_number; + ue_id_g = (node_number == 0) ? 0 : node_number - 2; + AssertFatal(ue_id_g >= 0, "UE id is expected to be nonnegative.\n"); + if(IS_SOFTMODEM_NOS1 || get_softmodem_params()->sa || get_softmodem_params()->nsa) { + if(node_number == 0) { + init_pdcp(0); + } + else { + init_pdcp(mode_offset + ue_id_g); + } + } NB_UE_INST=1; NB_INST=1; PHY_vars_UE_g = malloc(sizeof(PHY_VARS_NR_UE **)); PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_NR_UE *)*MAX_NUM_CCs); + if (get_softmodem_params()->emulate_l1) { + RCconfig_nr_ue_L1(); + } if (get_softmodem_params()->do_ra) AssertFatal(get_softmodem_params()->phy_test == 0,"RA and phy_test are mutually exclusive\n"); @@ -455,54 +482,57 @@ int main( int argc, char **argv ) { if (get_softmodem_params()->sa) AssertFatal(get_softmodem_params()->phy_test == 0,"Standalone mode and phy_test are mutually exclusive\n"); - for (int CC_id=0; CC_idnsa && get_softmodem_params()->emulate_l1) + start_oai_nrue_threads(); - PHY_vars_UE_g[0][CC_id] = (PHY_VARS_NR_UE *)malloc(sizeof(PHY_VARS_NR_UE)); - UE[CC_id] = PHY_vars_UE_g[0][CC_id]; - memset(UE[CC_id],0,sizeof(PHY_VARS_NR_UE)); + if (!get_softmodem_params()->emulate_l1) { + for (int CC_id=0; CC_idsa) { - uint16_t nr_band = get_band(downlink_frequency[CC_id][0],uplink_frequency_offset[CC_id][0]); - mac->nr_band = nr_band; - nr_init_frame_parms_ue_sa(&UE[CC_id]->frame_parms, - downlink_frequency[CC_id][0], - uplink_frequency_offset[CC_id][0], - get_softmodem_params()->numerology, - nr_band); - } - else{ - if(mac->if_module != NULL && mac->if_module->phy_config_request != NULL) - mac->if_module->phy_config_request(&mac->phy_config); + if (get_softmodem_params()->sa) { // set frame config to initial values from command line and assume that the SSB is centered on the grid + uint16_t nr_band = get_band(downlink_frequency[CC_id][0],uplink_frequency_offset[CC_id][0]); + mac->nr_band = nr_band; + nr_init_frame_parms_ue_sa(&UE[CC_id]->frame_parms, + downlink_frequency[CC_id][0], + uplink_frequency_offset[CC_id][0], + get_softmodem_params()->numerology, + nr_band); + } + else{ + if(mac->if_module != NULL && mac->if_module->phy_config_request != NULL) + mac->if_module->phy_config_request(&mac->phy_config); - fapi_nr_config_request_t *nrUE_config = &UE[CC_id]->nrUE_config; + fapi_nr_config_request_t *nrUE_config = &UE[CC_id]->nrUE_config; - nr_init_frame_parms_ue(&UE[CC_id]->frame_parms, nrUE_config, *mac->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]); + nr_init_frame_parms_ue(&UE[CC_id]->frame_parms, nrUE_config, + *mac->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]); + } + + init_symbol_rotation(&UE[CC_id]->frame_parms); + init_timeshift_rotation(&UE[CC_id]->frame_parms); + init_nr_ue_vars(UE[CC_id], 0, abstraction_flag); } - init_symbol_rotation(&UE[CC_id]->frame_parms); - init_timeshift_rotation(&UE[CC_id]->frame_parms); - init_nr_ue_vars(UE[CC_id], 0, abstraction_flag); + init_openair0(); + // init UE_PF_PO and mutex lock + pthread_mutex_init(&ue_pf_po_mutex, NULL); + memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs); + configure_linux(); + mlockall(MCL_CURRENT | MCL_FUTURE); + if(IS_SOFTMODEM_DOSCOPE) { + load_softscope("nr",PHY_vars_UE_g[0][0]); + } + + init_NR_UE_threads(1); + printf("UE threads created by %ld\n", gettid()); } - init_openair0(); - // init UE_PF_PO and mutex lock - pthread_mutex_init(&ue_pf_po_mutex, NULL); - memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs); - configure_linux(); - mlockall(MCL_CURRENT | MCL_FUTURE); - - if(IS_SOFTMODEM_DOSCOPE) { - load_softscope("nr",PHY_vars_UE_g[0][0]); - } - - - init_NR_UE_threads(1); - printf("UE threads created by %ld\n", gettid()); - // wait for end of program printf("TYPE TO TERMINATE\n"); diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h index 7f47ed5eb3..eb7175be9d 100644 --- a/executables/nr-uesoftmodem.h +++ b/executables/nr-uesoftmodem.h @@ -34,7 +34,8 @@ {"offset-divisor", CONFIG_HLP_OFFSET_DIV, 0, uptr:(uint32_t *)&nrUE_params.ofdm_offset_divisor, defuintval:UINT_MAX, TYPE_UINT32, 0}, \ {"nr-dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&nr_dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \ {"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, iptr:&vcdflag, defintval:0, TYPE_INT, 0}, \ - {"rrc_config_path", CONFIG_HLP_RRC_CFG_PATH,0, strptr:(char **)&rrc_config_path, defstrval:"./", TYPE_STRING, 0} \ + {"rrc_config_path", CONFIG_HLP_RRC_CFG_PATH,0, strptr:(char **)&rrc_config_path, defstrval:"./", TYPE_STRING, 0}, \ + {"ue-idx-standalone", NULL, 0, u16ptr:&ue_idx_standalone, defuintval:0xFFFF, TYPE_UINT16, 0} \ } @@ -88,7 +89,9 @@ extern void init_NR_UE(int, char*); extern void init_NR_UE_threads(int); extern void reset_opp_meas(void); extern void print_opp_meas(void); +extern void start_oai_nrue_threads(void); void *UE_thread(void *arg); void init_nr_ue_vars(PHY_VARS_NR_UE *ue, uint8_t UE_id, uint8_t abstraction_flag); +void init_nrUE_standalone_thread(int ue_idx); #endif diff --git a/executables/ocp-gnb.c b/executables/ocp-gnb.c index e8349eb1d8..7b4b1c6680 100644 --- a/executables/ocp-gnb.c +++ b/executables/ocp-gnb.c @@ -328,7 +328,7 @@ static void init_pdcp(void) { pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT ; } - pdcp_module_init(pdcp_initmask); + nr_pdcp_module_init(pdcp_initmask, 0); pdcp_set_rlc_data_req_func(rlc_data_req); pdcp_set_pdcp_data_ind_func(pdcp_data_ind); } diff --git a/executables/softmodem-common.c b/executables/softmodem-common.c index 01aec42c01..3e20081b18 100644 --- a/executables/softmodem-common.c +++ b/executables/softmodem-common.c @@ -211,10 +211,13 @@ void set_softmodem_sighandler(void) { memset(&act,0,sizeof(act)); act.sa_handler=signal_handler; sigaction(SOFTMODEM_RTSIGNAL,&act,&oldact); + // Disabled in order generate a core dump for analysis with gdb + # if 0 printf("Send signal %d to display resource usage...\n",SIGRTMIN+1); signal(SIGSEGV, signal_handler); signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); signal(SIGABRT, signal_handler); + #endif } diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h index 3a7022a502..9aca677473 100644 --- a/executables/softmodem-common.h +++ b/executables/softmodem-common.h @@ -98,6 +98,7 @@ extern "C" #define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n" #define CONFIG_HLP_USRP_THREAD "having extra thead for usrp tx\n" #define CONFIG_HLP_NFAPI "Change the nFAPI mode for NR\n" +#define CONFIG_L1_EMULATOR "Run in L1 emulated mode (disable PHY layer)\n" /*-----------------------------------------------------------------------------------------------------------------------------------------------------*/ /* command line parameters common to eNodeB and UE */ @@ -122,7 +123,10 @@ extern "C" #define USE_256QAM_TABLE softmodem_params.use_256qam_table #define PRB_INTERPOLATION softmodem_params.prb_interpolation #define NFAPI softmodem_params.nfapi +#define NSA softmodem_params.nsa +#define NODE_NUMBER softmodem_params.node_number #define NON_STOP softmodem_params.non_stop +#define EMULATE_L1 softmodem_params.emulate_l1 #define DEFAULT_RFCONFIG_FILE "/usr/local/etc/syriq/ue.band7.tm1.PRB100.NR40.dat"; @@ -155,13 +159,16 @@ extern int usrp_tx_thread; {"nokrnmod", CONFIG_HLP_NOKRNMOD, PARAMFLAG_BOOL, uptr:&nokrnmod, defintval:0, TYPE_INT, 0}, \ {"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, uptr:&nonbiot, defuintval:0, TYPE_INT, 0}, \ {"use-256qam-table", CONFIG_HLP_256QAM, PARAMFLAG_BOOL, iptr:&USE_256QAM_TABLE, defintval:0, TYPE_INT, 0}, \ - {"do-prb-interpolation", CONFIG_HLP_PRBINTER, PARAMFLAG_BOOL, iptr:&PRB_INTERPOLATION, defintval:0, TYPE_INT, 0}, \ - {"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0, iptr:&usrp_tx_thread, defstrval:0, TYPE_INT, 0}, \ - {"nfapi", CONFIG_HLP_NFAPI, 0, u8ptr:&nfapi_mode, defintval:0, TYPE_UINT8, 0}, \ - {"non-stop", CONFIG_HLP_NONSTOP, PARAMFLAG_BOOL, iptr:&NON_STOP, defintval:0, TYPE_INT, 0}, \ + {"nsa", CONFIG_HLP_NSA, PARAMFLAG_BOOL, iptr:&NSA, defintval:0, TYPE_INT, 0}, \ + {"node-number", NULL, 0, u16ptr:&NODE_NUMBER, defuintval:0, TYPE_UINT16, 0}, \ + {"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0, iptr:&usrp_tx_thread, defstrval:0, TYPE_INT, 0}, \ + {"do-prb-interpolation", CONFIG_HLP_PRBINTER, PARAMFLAG_BOOL, iptr:&PRB_INTERPOLATION, defintval:0, TYPE_INT, 0}, \ + {"nfapi", CONFIG_HLP_NFAPI, 0, u8ptr:&nfapi_mode, defintval:0, TYPE_UINT8, 0}, \ + {"non-stop", CONFIG_HLP_NONSTOP, PARAMFLAG_BOOL, iptr:&NON_STOP, defintval:0, TYPE_INT, 0}, \ + {"emulate-l1", CONFIG_L1_EMULATOR, PARAMFLAG_BOOL, iptr:&EMULATE_L1, defintval:0, TYPE_INT, 0}, \ } - +#define CONFIG_HLP_NSA "Enable NSA mode \n" #define CONFIG_HLP_FLOG "Enable online log \n" #define CONFIG_HLP_LOGL "Set the global log level, valid options: (4:trace, 3:debug, 2:info, 1:warn, (0:error))\n" #define CONFIG_HLP_LOGV "Set the global log verbosity \n" @@ -251,7 +258,10 @@ typedef struct { int use_256qam_table; int prb_interpolation; uint8_t nfapi; + int nsa; + uint16_t node_number; int non_stop; + int emulate_l1; } softmodem_params_t; extern uint64_t get_softmodem_optmask(void); @@ -272,6 +282,7 @@ void tx_func(void *param); void rx_func(void *param); void ru_tx_func(void *param); extern uint8_t nfapi_mode; +extern int16_t vnf_pnf_sfnslot_delta; #ifdef __cplusplus } #endif diff --git a/nfapi/oai_integration/gnb_ind_vars.c b/nfapi/oai_integration/gnb_ind_vars.c new file mode 100644 index 0000000000..148c28a5c4 --- /dev/null +++ b/nfapi/oai_integration/gnb_ind_vars.c @@ -0,0 +1,7 @@ +#include "gnb_ind_vars.h" + +queue_t gnb_rach_ind_queue; +queue_t gnb_rx_ind_queue; +queue_t gnb_crc_ind_queue; +queue_t gnb_uci_ind_queue; +queue_t gnb_slot_ind_queue; diff --git a/nfapi/oai_integration/gnb_ind_vars.h b/nfapi/oai_integration/gnb_ind_vars.h new file mode 100644 index 0000000000..8561037d3e --- /dev/null +++ b/nfapi/oai_integration/gnb_ind_vars.h @@ -0,0 +1,9 @@ +#pragma once + +#include "openair2/PHY_INTERFACE/queue_t.h" + +extern queue_t gnb_rach_ind_queue; +extern queue_t gnb_rx_ind_queue; +extern queue_t gnb_crc_ind_queue; +extern queue_t gnb_uci_ind_queue; +extern queue_t gnb_slot_ind_queue; diff --git a/nfapi/oai_integration/nfapi.c b/nfapi/oai_integration/nfapi.c index 86d1ae3127..5e71c5e2a4 100644 --- a/nfapi/oai_integration/nfapi.c +++ b/nfapi/oai_integration/nfapi.c @@ -23,7 +23,15 @@ #include #include "nfapi/oai_integration/vendor_ext.h" #include "common/utils/LOG/log.h" -static char nfapi_str_mode[6][24] = {"MONOLITHIC","PNF","VNF","UE_STUB_PNF","UE_STUB_OFFNET",""}; +static const char *const nfapi_str_mode[] = { + "MONOLITHIC", + "PNF", + "VNF", + "UE_STUB_PNF", + "UE_STUB_OFFNET", + "STANDALONE_PNF", + "" +}; typedef struct { nfapi_mode_t nfapi_mode; @@ -32,15 +40,9 @@ typedef struct { static nfapi_params_t nfapi_params = {0}; void set_thread_priority(int priority) { - //printf("%s(priority:%d)\n", __FUNCTION__, priority); + set_priority(priority); + pthread_attr_t ptAttr; - struct sched_param schedParam; - schedParam.__sched_priority = priority; //79; - - if(sched_setscheduler(0, SCHED_RR, &schedParam) != 0) { - printf("Failed to set scheduler to SCHED_RR\n"); - } - if(pthread_attr_setschedpolicy(&ptAttr, SCHED_RR) != 0) { printf("Failed to set pthread sched policy SCHED_RR\n"); } @@ -54,7 +56,7 @@ void set_thread_priority(int priority) { } } -char *nfapi_get_strmode(void) { +const char *nfapi_get_strmode(void) { if (nfapi_params.nfapi_mode > NFAPI_MODE_UNKNOWN) return nfapi_str_mode[NFAPI_MODE_UNKNOWN]; diff --git a/nfapi/oai_integration/nfapi_pnf.c b/nfapi/oai_integration/nfapi_pnf.c index 4edbeee342..3a59be41e9 100644 --- a/nfapi/oai_integration/nfapi_pnf.c +++ b/nfapi/oai_integration/nfapi_pnf.c @@ -218,14 +218,9 @@ void pnf_nfapi_trace(nfapi_trace_level_t nfapi_level, const char *message, ...) } void pnf_set_thread_priority(int priority) { + set_priority(priority); + pthread_attr_t ptAttr; - struct sched_param schedParam; - schedParam.__sched_priority = priority; - - if(sched_setscheduler(0, SCHED_RR, &schedParam) != 0) { - printf("failed to set SCHED_RR\n"); - } - if(pthread_attr_setschedpolicy(&ptAttr, SCHED_RR) != 0) { printf("failed to set pthread SCHED_RR %d\n", errno); } @@ -248,7 +243,7 @@ void *pnf_p7_thread_start(void *ptr) { } void *pnf_nr_p7_thread_start(void *ptr) { - NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] P7 THREAD %s\n", __FUNCTION__); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[NR_PNF] NR P7 THREAD %s\n", __FUNCTION__); pnf_set_thread_priority(79); nfapi_pnf_p7_config_t *config = (nfapi_pnf_p7_config_t *)ptr; nfapi_nr_pnf_p7_start(config); @@ -805,7 +800,7 @@ int config_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfap // to keep only the necessary just to keep the nfapi FSM rolling by sending a dummy response. LTE_DL_FRAME_PARMS *fp; - if (NFAPI_MODE!=NFAPI_UE_STUB_PNF) { + if (NFAPI_MODE!=NFAPI_UE_STUB_PNF && NFAPI_MODE!=NFAPI_MODE_STANDALONE_PNF) { struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; fp = &eNB->frame_parms; } else { @@ -967,7 +962,7 @@ int config_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfap num_tlv++; } - if(NFAPI_MODE!=NFAPI_UE_STUB_PNF) { + if(NFAPI_MODE!=NFAPI_UE_STUB_PNF && NFAPI_MODE!=NFAPI_MODE_STANDALONE_PNF) { printf("[PNF] CONFIG_REQUEST[num_tlv:%d] TLVs processed:%d\n", req->num_tlv, num_tlv); printf("[PNF] Simulating PHY CONFIG - DJP\n"); PHY_Config_t phy_config; @@ -991,7 +986,7 @@ int config_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfap nfapi_pnf_config_resp(config, &nfapi_resp); printf("[PNF] Sent NFAPI_CONFIG_RESPONSE phy_id:%d\n", phy_info->id); - if(NFAPI_MODE==NFAPI_UE_STUB_PNF) + if(NFAPI_MODE==NFAPI_UE_STUB_PNF || NFAPI_MODE==NFAPI_MODE_STANDALONE_PNF) free(fp); return 0; @@ -1226,15 +1221,15 @@ int pnf_phy_dl_tti_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, proc = &gNB->proc.L1_proc; nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu_list = req->dl_tti_request_body.dl_tti_pdu_list; - //if (req->dl_tti_request_body.nPDUs) - // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() TX:%d/%d RX:%d/%d; sfn:%d, slot:%d, nGroup:%u, nPDUs: %u, nUE: %u, PduIdx: %u,\n", - // __FUNCTION__, proc->frame_tx, proc->slot_tx, proc->frame_rx, proc->slot_rx, // TODO: change subframes to slot - // req->SFN, - // req->Slot, - // req->dl_tti_request_body.nGroup, - // req->dl_tti_request_body.nPDUs, - // req->dl_tti_request_body.nUe, - // req->dl_tti_request_body.PduIdx); + if (req->dl_tti_request_body.nPDUs) + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() TX:%d/%d RX:%d/%d; sfn:%d, slot:%d, nGroup:%u, nPDUs: %u, nUE: %p, PduIdx: %p,\n", + __FUNCTION__, proc->frame_tx, proc->slot_tx, proc->frame_rx, proc->slot_rx, // TODO: change subframes to slot + req->SFN, + req->Slot, + req->dl_tti_request_body.nGroup, + req->dl_tti_request_body.nPDUs, + req->dl_tti_request_body.nUe, + req->dl_tti_request_body.PduIdx); for (int i=0; idl_tti_request_body.nPDUs; i++) { // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() sfn/sf:%d PDU[%d] size:%d pdcch_vars->num_dci:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size,pdcch_vars->num_dci); @@ -1250,10 +1245,10 @@ int pnf_phy_dl_tti_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() PDU:%d BCH: pdu_index:%u pdu_length:%d sdu_length:%d BCH_SDU:%x,%x,%x\n", __FUNCTION__, i, pdu_index, bch_pdu->bch_pdu_rel8.length, tx_request_pdu[sfn][sf][pdu_index]->segments[0].segment_length, sdu[0], sdu[1], sdu[2]); handle_nr_nfapi_ssb_pdu(msgTx, sfn, slot, &dl_tti_pdu_list[i]); gNB->pbch_configured=1; - } + } else if (dl_tti_pdu_list[i].PDUType == NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE) { nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu = &dl_tti_pdu_list[i].pdsch_pdu; - nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15_pdu = &pdsch_pdu->pdsch_pdu_rel15; + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *rel15_pdu = &pdsch_pdu->pdsch_pdu_rel15; nfapi_nr_pdu_t *tx_data = tx_data_request[sfn][slot][rel15_pdu->pduIndex]; if (tx_data != NULL) { @@ -1466,6 +1461,7 @@ int pnf_phy_ul_tti_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, switch (ul_tti_pdu_list[i].pdu_type) { case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: //LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PUSCH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot); + //curr_sfn = curr_sfn + 3; //Gokul nr_fill_ulsch(gNB,curr_sfn, curr_slot, &ul_tti_pdu_list[i].pusch_pdu); break; case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE: @@ -1661,7 +1657,6 @@ nfapi_pnf_p7_subframe_buffer_t dummy_subframe; int start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi_start_request_t *req) { printf("[PNF] Received NFAPI_START_REQ phy_id:%d\n", req->header.phy_id); - nfapi_set_trace_level(NFAPI_TRACE_INFO); pnf_info *pnf = (pnf_info *)(config->user_data); phy_info *phy_info = pnf->phys; nfapi_pnf_p7_config_t *p7_config = nfapi_pnf_p7_config_create(); @@ -1697,11 +1692,11 @@ int start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi p7_config->tx_req = &pnf_phy_tx_req; p7_config->lbt_dl_config_req = &pnf_phy_lbt_dl_config_req; p7_config->ue_release_req = &pnf_phy_ue_release_req; - if (NFAPI_MODE==NFAPI_UE_STUB_PNF) { - p7_config->dl_config_req = &memcpy_dl_config_req; - p7_config->ul_config_req = &memcpy_ul_config_req; - p7_config->hi_dci0_req = &memcpy_hi_dci0_req; - p7_config->tx_req = &memcpy_tx_req; + if (NFAPI_MODE==NFAPI_UE_STUB_PNF || NFAPI_MODE==NFAPI_MODE_STANDALONE_PNF) { + p7_config->dl_config_req = NULL; + p7_config->ul_config_req = NULL; + p7_config->hi_dci0_req = NULL; + p7_config->tx_req = NULL; } else { p7_config->dl_config_req = &pnf_phy_dl_config_req; p7_config->ul_config_req = &pnf_phy_ul_config_req; @@ -1754,7 +1749,7 @@ int start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi //phy_init_RU(RC.ru[0]); printf("[PNF] About to call init_eNB_afterRU()\n"); - if (NFAPI_MODE!=NFAPI_UE_STUB_PNF) { + if (NFAPI_MODE!=NFAPI_UE_STUB_PNF && NFAPI_MODE!=NFAPI_MODE_STANDALONE_PNF) { init_eNB_afterRU(); } @@ -1781,7 +1776,6 @@ int start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi int nr_start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi_nr_start_request_scf_t *req) { printf("[PNF] Received NFAPI_START_REQ phy_id:%d\n", req->header.phy_id); - nfapi_set_trace_level(NFAPI_TRACE_INFO); pnf_info *pnf = (pnf_info *)(config->user_data); phy_info *phy_info = pnf->phys; nfapi_pnf_p7_config_t *p7_config = nfapi_pnf_p7_config_create(); @@ -1827,10 +1821,10 @@ int nr_start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, n p7_config->lbt_dl_config_req = &pnf_phy_lbt_dl_config_req; p7_config->ue_release_req = &pnf_phy_ue_release_req; if (NFAPI_MODE==NFAPI_UE_STUB_PNF) { - p7_config->dl_config_req = &memcpy_dl_config_req; - p7_config->ul_config_req = &memcpy_ul_config_req; - p7_config->hi_dci0_req = &memcpy_hi_dci0_req; - p7_config->tx_req = &memcpy_tx_req; + p7_config->dl_config_req = NULL; + p7_config->ul_config_req = NULL; + p7_config->hi_dci0_req = NULL; + p7_config->tx_req = NULL; } else { p7_config->dl_config_req = &pnf_phy_dl_config_req; p7_config->ul_config_req = &pnf_phy_ul_config_req; @@ -2232,7 +2226,7 @@ void configure_nr_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_add void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port) { printf("%s() PNF\n\n\n\n\n\n", __FUNCTION__); - if(NFAPI_MODE!=NFAPI_UE_STUB_PNF) { + if(NFAPI_MODE!=NFAPI_UE_STUB_PNF && NFAPI_MODE!=NFAPI_MODE_STANDALONE_PNF) { nfapi_setmode(NFAPI_MODE_PNF); // PNF! } nfapi_pnf_config_t *config = nfapi_pnf_config_create(); @@ -2286,15 +2280,13 @@ void oai_subframe_ind(uint16_t sfn, uint16_t sf) { uint16_t sfn_sf_tx = sfn<<4 | sf; if ((sfn % 100 == 0) && sf==0) { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] %s %d.%d (sfn:%u sf:%u) SFN/SF(TX):%u\n", __FUNCTION__, ts.tv_sec, ts.tv_nsec, sfn, sf, NFAPI_SFNSF2DEC(sfn_sf_tx)); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] (sfn:%u sf:%u) SFN/SF(TX):%u\n", sfn, sf, NFAPI_SFNSF2DEC(sfn_sf_tx)); } int subframe_ret = nfapi_pnf_p7_subframe_ind(p7_config_g, p7_config_g->phy_id, sfn_sf_tx); if (subframe_ret) { - NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] %s(frame:%u subframe:%u) SFN/SF(TX):%u - PROBLEM with pnf_p7_subframe_ind()\n", __FUNCTION__, sfn, sf, sfn_sf_tx, NFAPI_SFNSF2DEC(sfn_sf_tx)); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] (frame:%u subframe:%u) SFN/SF(TX):%u - PROBLEM with pnf_p7_subframe_ind()\n", sfn, sf, sfn_sf_tx); } else { //NFAPI_TRACE(NFAPI_TRACE_INFO, "***NFAPI subframe handler finished *** \n"); } diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c index d96829e127..44ee05940f 100644 --- a/nfapi/oai_integration/nfapi_vnf.c +++ b/nfapi/oai_integration/nfapi_vnf.c @@ -43,6 +43,8 @@ #include #include "common/ran_context.h" +#include "openair2/PHY_INTERFACE/queue_t.h" +#include "gnb_ind_vars.h" #define TEST @@ -203,7 +205,7 @@ extern uint16_t slot_ahead; void oai_create_enb(void) { int bodge_counter=0; PHY_VARS_eNB *eNB = RC.eNB[0][0]; - printf("[VNF] RC.eNB[0][0]. Mod_id:%d CC_id:%d nb_CC[0]:%d abstraction_flag:%d single_thread_flag:%d if_inst:%p\n", eNB->Mod_id, eNB->CC_id, RC.nb_CC[0], eNB->abstraction_flag, + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] RC.eNB[0][0]. Mod_id:%d CC_id:%d nb_CC[0]:%d abstraction_flag:%d single_thread_flag:%d if_inst:%p\n", eNB->Mod_id, eNB->CC_id, RC.nb_CC[0], eNB->abstraction_flag, eNB->single_thread_flag, eNB->if_inst); eNB->Mod_id = bodge_counter; eNB->CC_id = bodge_counter; @@ -219,20 +221,20 @@ void oai_create_enb(void) { // that will result in eNB->configured being set to TRUE. // See we need to wait for that to happen otherwise the NFAPI message exchanges won't contain the right parameter values if (RC.eNB[0][0]->if_inst==0 || RC.eNB[0][0]->if_inst->PHY_config_req==0 || RC.eNB[0][0]->if_inst->schedule_response==0) { - printf("RC.eNB[0][0]->if_inst->PHY_config_req is not installed - install it\n"); + NFAPI_TRACE(NFAPI_TRACE_INFO, "RC.eNB[0][0]->if_inst->PHY_config_req is not installed - install it\n"); install_schedule_handlers(RC.eNB[0][0]->if_inst); } do { - printf("%s() Waiting for eNB to become configured (by RRC/PHY) - need to wait otherwise NFAPI messages won't contain correct values\n", __FUNCTION__); + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() Waiting for eNB to become configured (by RRC/PHY) - need to wait otherwise NFAPI messages won't contain correct values\n", __FUNCTION__); usleep(50000); } while(eNB->configured != 1); - printf("%s() eNB is now configured\n", __FUNCTION__); + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() eNB is now configured\n", __FUNCTION__); } void oai_enb_init(void) { - printf("%s() About to call init_eNB_afterRU()\n", __FUNCTION__); + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() About to call init_eNB_afterRU()\n", __FUNCTION__); init_eNB_afterRU(); } @@ -253,7 +255,7 @@ void oai_create_gnb(void) { PHY_VARS_gNB *gNB = RC.gNB[0]; RC.nb_nr_CC = (int *)malloc(sizeof(int)); // TODO: find a better function to place this in - + gNB->Mod_id = bodge_counter; gNB->CC_id = bodge_counter; gNB->abstraction_flag = 0; @@ -263,26 +265,26 @@ void oai_create_gnb(void) { if (gNB->if_inst==0) { gNB->if_inst = NR_IF_Module_init(bodge_counter); } - + // This will cause phy_config_request to be installed. That will result in RRC configuring the PHY // that will result in gNB->configured being set to TRUE. // See we need to wait for that to happen otherwise the NFAPI message exchanges won't contain the right parameter values if (RC.gNB[0]->if_inst==0 || RC.gNB[0]->if_inst->NR_PHY_config_req==0 || RC.gNB[0]->if_inst->NR_Schedule_response==0) { - printf("RC.gNB[0][0]->if_inst->NR_PHY_config_req is not installed - install it\n"); + NFAPI_TRACE(NFAPI_TRACE_INFO, "RC.gNB[0][0]->if_inst->NR_PHY_config_req is not installed - install it\n"); install_nr_schedule_handlers(RC.gNB[0]->if_inst); } do { - printf("%s() Waiting for gNB to become configured (by RRC/PHY) - need to wait otherwise NFAPI messages won't contain correct values\n", __FUNCTION__); + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() Waiting for gNB to become configured (by RRC/PHY) - need to wait otherwise NFAPI messages won't contain correct values\n", __FUNCTION__); usleep(50000); } while(gNB->configured != 1); - printf("%s() gNB is now configured\n", __FUNCTION__); + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() gNB is now configured\n", __FUNCTION__); } int pnf_connection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) { - printf("[VNF] pnf connection indication idx:%d\n", p5_idx); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] pnf connection indication idx:%d\n", p5_idx); oai_create_enb(); nfapi_pnf_param_request_t req; memset(&req, 0, sizeof(req)); @@ -292,7 +294,7 @@ int pnf_connection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) { } int pnf_nr_connection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) { - printf("[VNF] pnf connection indication idx:%d\n", p5_idx); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] pnf connection indication idx:%d\n", p5_idx); oai_create_gnb(); nfapi_nr_pnf_param_request_t req; memset(&req, 0, sizeof(req)); @@ -302,7 +304,7 @@ int pnf_nr_connection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) { } int pnf_disconnection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) { - printf("[VNF] pnf disconnection indication idx:%d\n", p5_idx); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] pnf disconnection indication idx:%d\n", p5_idx); vnf_info *vnf = (vnf_info *)(config->user_data); pnf_info *pnf = vnf->pnfs; phy_info *phy = pnf->phys; @@ -312,7 +314,7 @@ int pnf_disconnection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) { } int pnf_nr_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_param_response_t *resp) { - printf("[VNF] pnf param response idx:%d error:%d\n", p5_idx, resp->error_code); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] pnf param response idx:%d error:%d\n", p5_idx, resp->error_code); vnf_info *vnf = (vnf_info *)(config->user_data); pnf_info *pnf = vnf->pnfs; @@ -320,11 +322,11 @@ int pnf_nr_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_pa phy_info phy; memset(&phy,0,sizeof(phy)); phy.index = resp->pnf_phy.phy[i].phy_config_index; - printf("[VNF] (PHY:%d) phy_config_idx:%d\n", i, resp->pnf_phy.phy[i].phy_config_index); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] (PHY:%d) phy_config_idx:%d\n", i, resp->pnf_phy.phy[i].phy_config_index); nfapi_vnf_allocate_phy(config, p5_idx, &(phy.id)); for(int j = 0; j < resp->pnf_phy.phy[i].number_of_rfs; ++j) { - printf("[VNF] (PHY:%d) (RF%d) %d\n", i, j, resp->pnf_phy.phy[i].rf_config[j].rf_config_index); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] (PHY:%d) (RF%d) %d\n", i, j, resp->pnf_phy.phy[i].rf_config[j].rf_config_index); phy.rfs[0] = resp->pnf_phy.phy[i].rf_config[j].rf_config_index; } @@ -335,7 +337,7 @@ int pnf_nr_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_pa req.header.message_id = NFAPI_PNF_CONFIG_REQUEST; req.pnf_phy_rf_config.tl.tag = NFAPI_PNF_PHY_RF_TAG; req.pnf_phy_rf_config.number_phy_rf_config_info = 2; // DJP pnf.phys.size(); - printf("DJP:Hard coded num phy rf to 2\n"); + NFAPI_TRACE(NFAPI_TRACE_INFO, "DJP:Hard coded num phy rf to 2\n"); for(unsigned i = 0; i < 2; ++i) { req.pnf_phy_rf_config.phy_rf_config[i].phy_id = pnf->phys[i].id; @@ -348,7 +350,7 @@ int pnf_nr_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_pa } int pnf_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_param_response_t *resp) { - printf("[VNF] pnf param response idx:%d error:%d\n", p5_idx, resp->error_code); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] pnf param response idx:%d error:%d\n", p5_idx, resp->error_code); vnf_info *vnf = (vnf_info *)(config->user_data); pnf_info *pnf = vnf->pnfs; @@ -356,11 +358,11 @@ int pnf_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_param_re phy_info phy; memset(&phy,0,sizeof(phy)); phy.index = resp->pnf_phy.phy[i].phy_config_index; - printf("[VNF] (PHY:%d) phy_config_idx:%d\n", i, resp->pnf_phy.phy[i].phy_config_index); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] (PHY:%d) phy_config_idx:%d\n", i, resp->pnf_phy.phy[i].phy_config_index); nfapi_vnf_allocate_phy(config, p5_idx, &(phy.id)); for(int j = 0; j < resp->pnf_phy.phy[i].number_of_rfs; ++j) { - printf("[VNF] (PHY:%d) (RF%d) %d\n", i, j, resp->pnf_phy.phy[i].rf_config[j].rf_config_index); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] (PHY:%d) (RF%d) %d\n", i, j, resp->pnf_phy.phy[i].rf_config[j].rf_config_index); phy.rfs[0] = resp->pnf_phy.phy[i].rf_config[j].rf_config_index; } @@ -370,7 +372,7 @@ int pnf_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_param_re rf_info rf; memset(&rf,0,sizeof(rf)); rf.index = resp->pnf_rf.rf[i].rf_config_index; - printf("[VNF] (RF:%d) rf_config_idx:%d\n", i, resp->pnf_rf.rf[i].rf_config_index); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] (RF:%d) rf_config_idx:%d\n", i, resp->pnf_rf.rf[i].rf_config_index); pnf->rfs[0] = rf; } nfapi_pnf_config_request_t req; @@ -378,7 +380,7 @@ int pnf_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_param_re req.header.message_id = NFAPI_PNF_CONFIG_REQUEST; req.pnf_phy_rf_config.tl.tag = NFAPI_PNF_PHY_RF_TAG; req.pnf_phy_rf_config.number_phy_rf_config_info = 2; // DJP pnf.phys.size(); - printf("DJP:Hard coded num phy rf to 2\n"); + NFAPI_TRACE(NFAPI_TRACE_INFO, "DJP:Hard coded num phy rf to 2\n"); for(unsigned i = 0; i < 2; ++i) { req.pnf_phy_rf_config.phy_rf_config[i].phy_id = pnf->phys[i].id; @@ -391,7 +393,7 @@ int pnf_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_param_re } int pnf_nr_config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_config_response_t *resp) { - printf("[VNF] pnf config response idx:%d resp[header[phy_id:%u message_id:%02x message_length:%u]]\n", p5_idx, resp->header.phy_id, resp->header.message_id, resp->header.message_length); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] pnf config response idx:%d resp[header[phy_id:%u message_id:%02x message_length:%u]]\n", p5_idx, resp->header.phy_id, resp->header.message_id, resp->header.message_length); if(1) { nfapi_nr_pnf_start_request_t req; @@ -416,7 +418,7 @@ int pnf_nr_config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_c } int pnf_config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_config_response_t *resp) { - printf("[VNF] pnf config response idx:%d resp[header[phy_id:%u message_id:%02x message_length:%u]]\n", p5_idx, resp->header.phy_id, resp->header.message_id, resp->header.message_length); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] pnf config response idx:%d resp[header[phy_id:%u message_id:%02x message_length:%u]]\n", p5_idx, resp->header.phy_id, resp->header.message_id, resp->header.message_length); if(1) { nfapi_pnf_start_request_t req; @@ -443,12 +445,12 @@ int pnf_config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_config_ int wake_gNB_rxtx(PHY_VARS_gNB *gNB, uint16_t sfn, uint16_t slot) { struct timespec curr_t; clock_gettime(CLOCK_MONOTONIC,&curr_t); - //printf("\n wake_gNB_rxtx before assignment sfn:%d slot:%d TIME %d.%d",sfn,slot,curr_t.tv_sec,curr_t.tv_nsec); + //NFAPI_TRACE(NFAPI_TRACE_INFO, "\n wake_gNB_rxtx before assignment sfn:%d slot:%d TIME %d.%d",sfn,slot,curr_t.tv_sec,curr_t.tv_nsec); gNB_L1_proc_t *proc=&gNB->proc; gNB_L1_rxtx_proc_t *L1_proc= (slot&1)? &proc->L1_proc : &proc->L1_proc_tx; NR_DL_FRAME_PARMS *fp = &gNB->frame_parms; - //printf("%s(eNB:%p, sfn:%d, sf:%d)\n", __FUNCTION__, eNB, sfn, sf); + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s(eNB:%p, sfn:%d, sf:%d)\n", __FUNCTION__, eNB, sfn, sf); //int i; struct timespec wait; clock_gettime(CLOCK_REALTIME, &wait); @@ -471,7 +473,7 @@ int wake_gNB_rxtx(PHY_VARS_gNB *gNB, uint16_t sfn, uint16_t slot) { // Try to be 1 frame back old_slot = slot; old_sfn = sfn; - //printf("\n wake_gNB_rxtx after assignment sfn:%d slot:%d",proc->frame_rx,proc->slot_rx); + //NFAPI_TRACE(NFAPI_TRACE_INFO, "\n wake_gNB_rxtx after assignment sfn:%d slot:%d",proc->frame_rx,proc->slot_rx); if (old_slot == 0 && old_sfn % 100 == 0) LOG_W( PHY,"[gNB] sfn/slot:%d%d old_sfn/slot:%d%d proc[rx:%d%d]\n", sfn, slot, old_sfn, old_slot, proc->frame_rx, proc->slot_rx); } @@ -490,7 +492,7 @@ int wake_gNB_rxtx(PHY_VARS_gNB *gNB, uint16_t sfn, uint16_t slot) { L1_proc->slot_tx = (L1_proc->slot_rx + slot_ahead)%20; //LOG_I(PHY, "sfn/sf:%d%d proc[rx:%d%d] rx:%d%d] About to wake rxtx thread\n\n", sfn, slot, proc->frame_rx, proc->slot_rx, L1_proc->frame_rx, L1_proc->slot_rx); - //printf("\nEntering wake_gNB_rxtx sfn %d slot %d\n",L1_proc->frame_rx,L1_proc->slot_rx); + //NFAPI_TRACE(NFAPI_TRACE_INFO, "\nEntering wake_gNB_rxtx sfn %d slot %d\n",L1_proc->frame_rx,L1_proc->slot_rx); // the thread can now be woken up if (pthread_cond_signal(&L1_proc->cond) != 0) { LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB RXn-TXnp4 thread\n"); @@ -508,7 +510,7 @@ int wake_eNB_rxtx(PHY_VARS_eNB *eNB, uint16_t sfn, uint16_t sf) { L1_proc_t *proc=&eNB->proc; L1_rxtx_proc_t *L1_proc= (sf&1)? &proc->L1_proc : &proc->L1_proc_tx; LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; - //printf("%s(eNB:%p, sfn:%d, sf:%d)\n", __FUNCTION__, eNB, sfn, sf); + //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s(eNB:%p, sfn:%d, sf:%d)\n", __FUNCTION__, eNB, sfn, sf); //int i; struct timespec wait; wait.tv_sec=0; @@ -596,11 +598,11 @@ extern pthread_mutex_t nfapi_sync_mutex; extern int nfapi_sync_var; int phy_sync_indication(struct nfapi_vnf_p7_config *config, uint8_t sync) { - //printf("[VNF] SYNC %s\n", sync==1 ? "ACHIEVED" : "LOST"); + //NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] SYNC %s\n", sync==1 ? "ACHIEVED" : "LOST"); if (sync==1 && nfapi_sync_var!=0) { - - printf("[VNF] Signal to OAI main code that it can go\n"); + + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Signal to OAI main code that it can go\n"); pthread_mutex_lock(&nfapi_sync_mutex); nfapi_sync_var=0; pthread_cond_broadcast(&nfapi_sync_cond); @@ -615,19 +617,19 @@ int phy_slot_indication(struct nfapi_vnf_p7_config *config, uint16_t phy_id, uin static uint8_t first_time = 1; if (first_time) { - printf("[VNF] slot indication %d\n", NFAPI_SFNSLOT2DEC(sfn, slot)); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] slot indication %d\n", NFAPI_SFNSLOT2DEC(sfn, slot)); first_time = 0; } if (RC.gNB && RC.gNB[0]->configured) { // uint16_t sfn = NFAPI_SFNSF2SFN(sfn_sf); // uint16_t sf = NFAPI_SFNSF2SF(sfn_sf); - LOG_D(PHY,"[VNF] slot indication sfn:%d sf:%d\n", sfn, slot); + LOG_D(PHY,"[VNF] slot indication sfn:%d slot:%d\n", sfn, slot); wake_gNB_rxtx(RC.gNB[0], sfn, slot); // DONE: find NR equivalent } else { - printf("[VNF] %s() RC.gNB:%p\n", __FUNCTION__, RC.gNB); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s() RC.gNB:%p\n", __FUNCTION__, RC.gNB); - if (RC.gNB) printf("RC.gNB[0]->configured:%d\n", RC.gNB[0]->configured); + if (RC.gNB) NFAPI_TRACE(NFAPI_TRACE_INFO, "RC.gNB[0]->configured:%d\n", RC.gNB[0]->configured); } return 0; @@ -637,7 +639,7 @@ int phy_subframe_indication(struct nfapi_vnf_p7_config *config, uint16_t phy_id, static uint8_t first_time = 1; if (first_time) { - printf("[VNF] subframe indication %d\n", NFAPI_SFNSF2DEC(sfn_sf)); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] subframe indication %d\n", NFAPI_SFNSF2DEC(sfn_sf)); first_time = 0; } @@ -647,9 +649,9 @@ int phy_subframe_indication(struct nfapi_vnf_p7_config *config, uint16_t phy_id, //LOG_D(PHY,"[VNF] subframe indication sfn_sf:%d sfn:%d sf:%d\n", sfn_sf, sfn, sf); wake_eNB_rxtx(RC.eNB[0][0], sfn, sf); } else { - printf("[VNF] %s() RC.eNB:%p\n", __FUNCTION__, RC.eNB); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s() RC.eNB:%p\n", __FUNCTION__, RC.eNB); - if (RC.eNB) printf("RC.eNB[0][0]->configured:%d\n", RC.eNB[0][0]->configured); + if (RC.eNB) NFAPI_TRACE(NFAPI_TRACE_INFO, "RC.eNB[0][0]->configured:%d\n", RC.eNB[0][0]->configured); } return 0; @@ -658,21 +660,11 @@ int phy_subframe_indication(struct nfapi_vnf_p7_config *config, uint16_t phy_id, int phy_rach_indication(struct nfapi_vnf_p7_config *config, nfapi_rach_indication_t *ind) { LOG_D(MAC, "%s() NFAPI SFN/SF:%d number_of_preambles:%u\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->rach_indication_body.number_of_preambles); struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; - printf("[VNF] RACH_IND eNB:%p sfn_sf:%d number_of_preambles:%d\n", eNB, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->rach_indication_body.number_of_preambles); - pthread_mutex_lock(&eNB->UL_INFO_mutex); + LOG_D(MAC, "[VNF] RACH_IND eNB:%p sfn_sf:%d number_of_preambles:%d\n", eNB, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->rach_indication_body.number_of_preambles); + AssertFatal(pthread_mutex_lock(&eNB->UL_INFO_mutex)==0, "Mutex lock failed"); if(NFAPI_MODE == NFAPI_MODE_VNF){ - int8_t index = -1; - for(uint8_t i= 0;i< NUM_NFPAI_SUBFRAME;i++){ - if((UL_RCC_INFO.rach_ind[i].header.message_id == 0) && (index == -1)){ - index = i; - break; - } - } - if(index == -1){ - LOG_E(MAC,"phy_rach_indication : num of rach reach max \n"); - pthread_mutex_unlock(&eNB->UL_INFO_mutex); - return 0; - } + int8_t index = NFAPI_SFNSF2SF(ind->sfn_sf); + UL_RCC_INFO.rach_ind[index] = *ind; if (ind->rach_indication_body.number_of_preambles > 0) @@ -681,7 +673,7 @@ int phy_rach_indication(struct nfapi_vnf_p7_config *config, nfapi_rach_indicatio for (int i=0; irach_indication_body.number_of_preambles; i++) { if (ind->rach_indication_body.preamble_list[i].preamble_rel8.tl.tag == NFAPI_PREAMBLE_REL8_TAG) { - printf("preamble[%d]: rnti:%02x preamble:%d timing_advance:%d\n", + LOG_D(MAC, "preamble[%d]: rnti:%02x preamble:%d timing_advance:%d\n", i, ind->rach_indication_body.preamble_list[i].preamble_rel8.rnti, ind->rach_indication_body.preamble_list[i].preamble_rel8.preamble, @@ -689,7 +681,7 @@ int phy_rach_indication(struct nfapi_vnf_p7_config *config, nfapi_rach_indicatio ); } if(ind->rach_indication_body.preamble_list[i].preamble_rel13.tl.tag == NFAPI_PREAMBLE_REL13_TAG) { - printf("RACH PREAMBLE REL13 present\n"); + LOG_D(MAC, "RACH PREAMBLE REL13 present\n"); } UL_RCC_INFO.rach_ind[index].rach_indication_body.preamble_list[i] = ind->rach_indication_body.preamble_list[i]; @@ -700,7 +692,7 @@ int phy_rach_indication(struct nfapi_vnf_p7_config *config, nfapi_rach_indicatio for (int i=0; irach_indication_body.number_of_preambles; i++) { if (ind->rach_indication_body.preamble_list[i].preamble_rel8.tl.tag == NFAPI_PREAMBLE_REL8_TAG) { - printf("preamble[%d]: rnti:%02x preamble:%d timing_advance:%d\n", + LOG_D(MAC, "preamble[%d]: rnti:%02x preamble:%d timing_advance:%d\n", i, ind->rach_indication_body.preamble_list[i].preamble_rel8.rnti, ind->rach_indication_body.preamble_list[i].preamble_rel8.preamble, @@ -709,51 +701,190 @@ int phy_rach_indication(struct nfapi_vnf_p7_config *config, nfapi_rach_indicatio } if(ind->rach_indication_body.preamble_list[i].preamble_rel13.tl.tag == NFAPI_PREAMBLE_REL13_TAG) { - printf("RACH PREAMBLE REL13 present\n"); + LOG_D(MAC, "RACH PREAMBLE REL13 present\n"); } eNB->preamble_list[i] = ind->rach_indication_body.preamble_list[i]; } } - pthread_mutex_unlock(&eNB->UL_INFO_mutex); + AssertFatal(pthread_mutex_unlock(&eNB->UL_INFO_mutex)==0, "Mutex unlock failed"); // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); //mac_rach_ind(p7_vnf->mac, ind); return 1; } +int phy_nr_rach_indication(nfapi_nr_rach_indication_t *ind) +{ + if(NFAPI_MODE == NFAPI_MODE_VNF) + { + nfapi_nr_rach_indication_t *rach_ind = CALLOC(1, sizeof(*rach_ind)); + rach_ind->header.message_id = ind->header.message_id; + rach_ind->number_of_pdus = ind->number_of_pdus; + rach_ind->sfn = ind->sfn; + rach_ind->slot = ind->slot; + rach_ind->pdu_list = CALLOC(rach_ind->number_of_pdus, sizeof(*rach_ind->pdu_list)); + AssertFatal(rach_ind->pdu_list != NULL, "Memory not allocated for rach_ind->pdu_list in phy_nr_rach_indication."); + for (int i = 0; i < ind->number_of_pdus; i++) + { + rach_ind->pdu_list[i].num_preamble = ind->pdu_list[i].num_preamble; + rach_ind->pdu_list[i].freq_index = ind->pdu_list[i].freq_index; + rach_ind->pdu_list[i].symbol_index = ind->pdu_list[i].symbol_index; + rach_ind->pdu_list[i].preamble_list = CALLOC(ind->pdu_list[i].num_preamble, sizeof(nfapi_nr_prach_indication_preamble_t)); + AssertFatal(rach_ind->pdu_list[i].preamble_list != NULL, "Memory not allocated for rach_ind->pdu_list[i].preamble_list in phy_nr_rach_indication."); + for (int j = 0; j < ind->number_of_pdus; j++) + { + rach_ind->pdu_list[i].preamble_list[j].preamble_index = ind->pdu_list[i].preamble_list[j].preamble_index; + rach_ind->pdu_list[i].preamble_list[j].timing_advance = ind->pdu_list[i].preamble_list[j].timing_advance; + } + } + if (!put_queue(&gnb_rach_ind_queue, rach_ind)) + { + LOG_E(NR_MAC, "Put_queue failed for rach_ind\n"); + for (int i = 0; i < ind->number_of_pdus; i++) + { + free(rach_ind->pdu_list[i].preamble_list); + } + free(rach_ind->pdu_list); + free(rach_ind); + } + } + else { + LOG_E(NR_MAC, "NFAPI_MODE = %d not NFAPI_MODE_VNF(2)\n", nfapi_getmode()); + } + return 1; +} + +int phy_nr_uci_indication(nfapi_nr_uci_indication_t *ind) +{ + + LOG_I(NR_MAC, "In %s() NFAPI SFN/SF: %d/%d number_of_pdus :%u\n", + __FUNCTION__,ind->sfn, ind->slot, ind->num_ucis); + if(NFAPI_MODE == NFAPI_MODE_VNF) + { + nfapi_nr_uci_indication_t *uci_ind = CALLOC(1, sizeof(*uci_ind)); + AssertFatal(uci_ind != NULL, "Memory not allocated for uci_ind in phy_nr_uci_indication."); + *uci_ind = *ind; + + uci_ind->uci_list = CALLOC(NFAPI_NR_UCI_IND_MAX_PDU, sizeof(nfapi_nr_uci_t)); + AssertFatal(uci_ind->uci_list != NULL, "Memory not allocated for uci_ind->uci_list in phy_nr_uci_indication."); + for (int i = 0; i < ind->num_ucis; i++) + { + uci_ind->uci_list[i] = ind->uci_list[i]; + + switch (uci_ind->uci_list[i].pdu_type) { + case NFAPI_NR_UCI_PUSCH_PDU_TYPE: + LOG_E(MAC, "%s(): unhandled NFAPI_NR_UCI_PUSCH_PDU_TYPE\n", __func__); + break; + + case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: { + nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_ind_pdu = &uci_ind->uci_list[i].pucch_pdu_format_0_1; + nfapi_nr_uci_pucch_pdu_format_0_1_t *ind_pdu = &ind->uci_list[i].pucch_pdu_format_0_1; + if (ind_pdu->sr) { + uci_ind_pdu->sr = CALLOC(1, sizeof(*uci_ind_pdu->sr)); + AssertFatal(uci_ind_pdu->sr != NULL, "Memory not allocated for uci_ind_pdu->harq in phy_nr_uci_indication."); + *uci_ind_pdu->sr = *ind_pdu->sr; + } + if (ind_pdu->harq) { + uci_ind_pdu->harq = CALLOC(1, sizeof(*uci_ind_pdu->harq)); + AssertFatal(uci_ind_pdu->harq != NULL, "Memory not allocated for uci_ind_pdu->harq in phy_nr_uci_indication."); + + *uci_ind_pdu->harq = *ind_pdu->harq; + uci_ind_pdu->harq->harq_list = CALLOC(uci_ind_pdu->harq->num_harq, sizeof(*uci_ind_pdu->harq->harq_list)); + AssertFatal(uci_ind_pdu->harq->harq_list != NULL, "Memory not allocated for uci_ind_pdu->harq->harq_list in phy_nr_uci_indication."); + for (int j = 0; j < uci_ind_pdu->harq->num_harq; j++) + uci_ind_pdu->harq->harq_list[j].harq_value = ind_pdu->harq->harq_list[j].harq_value; + } + break; + } + + case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: { + nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_ind_pdu = &uci_ind->uci_list[i].pucch_pdu_format_2_3_4; + nfapi_nr_uci_pucch_pdu_format_2_3_4_t *ind_pdu = &ind->uci_list[i].pucch_pdu_format_2_3_4; + + uci_ind_pdu->harq.harq_payload = CALLOC(1, sizeof(*uci_ind_pdu->harq.harq_payload)); + AssertFatal(uci_ind_pdu->harq.harq_payload != NULL, "Memory not allocated for uci_ind_pdu->harq.harq_payload in phy_nr_uci_indication."); + *uci_ind_pdu->harq.harq_payload = *ind_pdu->harq.harq_payload; + + + uci_ind_pdu->csi_part1.csi_part1_payload = CALLOC(1, sizeof(*uci_ind_pdu->csi_part1.csi_part1_payload)); + AssertFatal(uci_ind_pdu->csi_part1.csi_part1_payload != NULL, "Memory not allocated for uci_ind_pdu->csi_part1.csi_part1_payload in phy_nr_uci_indication."); + *uci_ind_pdu->csi_part1.csi_part1_payload = *ind_pdu->csi_part1.csi_part1_payload; + + + uci_ind_pdu->csi_part2.csi_part2_payload = CALLOC(1, sizeof(*uci_ind_pdu->csi_part2.csi_part2_payload)); + AssertFatal(uci_ind_pdu->csi_part2.csi_part2_payload != NULL, "Memory not allocated for uci_ind_pdu->csi_part2.csi_part2_payload in phy_nr_uci_indication."); + *uci_ind_pdu->csi_part2.csi_part2_payload = *ind_pdu->csi_part2.csi_part2_payload; + + break; + } + } + } + + if (!put_queue(&gnb_uci_ind_queue, uci_ind)) + { + LOG_E(NR_MAC, "Put_queue failed for uci_ind\n"); + for (int i = 0; i < ind->num_ucis; i++) + { + if (uci_ind->uci_list[i].pdu_type == NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE) + { + if (uci_ind->uci_list[i].pucch_pdu_format_0_1.harq) { + free(uci_ind->uci_list[i].pucch_pdu_format_0_1.harq->harq_list); + uci_ind->uci_list[i].pucch_pdu_format_0_1.harq->harq_list = NULL; + free(uci_ind->uci_list[i].pucch_pdu_format_0_1.harq); + uci_ind->uci_list[i].pucch_pdu_format_0_1.harq = NULL; + } + if (uci_ind->uci_list[i].pucch_pdu_format_0_1.sr) { + free(uci_ind->uci_list[i].pucch_pdu_format_0_1.sr); + uci_ind->uci_list[i].pucch_pdu_format_0_1.sr = NULL; + } + } + if (uci_ind->uci_list[i].pdu_type == NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE) + { + free(uci_ind->uci_list[i].pucch_pdu_format_2_3_4.harq.harq_payload); + free(uci_ind->uci_list[i].pucch_pdu_format_2_3_4.csi_part1.csi_part1_payload); + free(uci_ind->uci_list[i].pucch_pdu_format_2_3_4.csi_part2.csi_part2_payload); + } + } + free(uci_ind->uci_list); + uci_ind->uci_list = NULL; + free(uci_ind); + uci_ind = NULL; + } + } + else { + LOG_E(NR_MAC, "NFAPI_MODE = %d not NFAPI_MODE_VNF(2)\n", nfapi_getmode()); + } + return 1; +} + int phy_harq_indication(struct nfapi_vnf_p7_config *config, nfapi_harq_indication_t *ind) { struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; LOG_D(MAC, "%s() NFAPI SFN/SF:%d number_of_harqs:%u\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->harq_indication_body.number_of_harqs); - pthread_mutex_lock(&eNB->UL_INFO_mutex); + AssertFatal(pthread_mutex_lock(&eNB->UL_INFO_mutex)==0, "Mutex lock failed"); if(NFAPI_MODE == NFAPI_MODE_VNF){ - int8_t index = -1; - for(uint8_t i= 0;i< NUM_NFPAI_SUBFRAME;i++){ - if((UL_RCC_INFO.harq_ind[i].header.message_id == 0) && (index == -1)){ - index = i; - break; - } - } - if(index == -1){ - LOG_E(MAC,"phy_harq_indication : num of harq reach max \n"); - pthread_mutex_unlock(&eNB->UL_INFO_mutex); - return 0; - } + int8_t index = NFAPI_SFNSF2SF(ind->sfn_sf); + UL_RCC_INFO.harq_ind[index] = *ind; - if (ind->harq_indication_body.number_of_harqs > 0) - UL_RCC_INFO.harq_ind[index].harq_indication_body.harq_pdu_list = malloc(sizeof(nfapi_harq_indication_pdu_t)*ind->harq_indication_body.number_of_harqs ); + assert(ind->harq_indication_body.number_of_harqs <= NFAPI_HARQ_IND_MAX_PDU); + if (ind->harq_indication_body.number_of_harqs > 0) { + UL_RCC_INFO.harq_ind[index].harq_indication_body.harq_pdu_list = malloc(sizeof(nfapi_harq_indication_pdu_t) * NFAPI_HARQ_IND_MAX_PDU); + } for (int i=0; iharq_indication_body.number_of_harqs; i++) { memcpy(&UL_RCC_INFO.harq_ind[index].harq_indication_body.harq_pdu_list[i], &ind->harq_indication_body.harq_pdu_list[i], sizeof(nfapi_harq_indication_pdu_t)); } }else{ - eNB->UL_INFO.harq_ind = *ind; - eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = eNB->harq_pdu_list; + eNB->UL_INFO.harq_ind = *ind; + eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = eNB->harq_pdu_list; - for (int i=0; iharq_indication_body.number_of_harqs; i++) { - memcpy(&eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list[i], &ind->harq_indication_body.harq_pdu_list[i], sizeof(eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list[i])); + assert(ind->harq_indication_body.number_of_harqs <= NFAPI_HARQ_IND_MAX_PDU); + for (int i=0; iharq_indication_body.number_of_harqs; i++) { + memcpy(&eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list[i], + &ind->harq_indication_body.harq_pdu_list[i], + sizeof(eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list[i])); + } } - } - pthread_mutex_unlock(&eNB->UL_INFO_mutex); + AssertFatal(pthread_mutex_unlock(&eNB->UL_INFO_mutex)==0, "Mutex unlock failed"); // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); //mac_harq_ind(p7_vnf->mac, ind); return 1; @@ -761,28 +892,18 @@ int phy_harq_indication(struct nfapi_vnf_p7_config *config, nfapi_harq_indicatio int phy_crc_indication(struct nfapi_vnf_p7_config *config, nfapi_crc_indication_t *ind) { struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; - pthread_mutex_lock(&eNB->UL_INFO_mutex); + AssertFatal(pthread_mutex_lock(&eNB->UL_INFO_mutex)==0, "Mutex lock failed"); if(NFAPI_MODE == NFAPI_MODE_VNF){ - int8_t index = -1; - for(uint8_t i= 0;i< NUM_NFPAI_SUBFRAME;i++){ - if((UL_RCC_INFO.crc_ind[i].header.message_id == 0) && (index == -1)){ - index = i; - } - if(UL_RCC_INFO.rx_ind[i].sfn_sf == ind->sfn_sf){ - index = i; - break; - } - } - if(index == -1){ - LOG_E(MAC,"phy_crc_indication : num of crc reach max \n"); - pthread_mutex_unlock(&eNB->UL_INFO_mutex); - return 0; - } + int8_t index = NFAPI_SFNSF2SF(ind->sfn_sf); + UL_RCC_INFO.crc_ind[index] = *ind; - if (ind->crc_indication_body.number_of_crcs > 0) - UL_RCC_INFO.crc_ind[index].crc_indication_body.crc_pdu_list = malloc(sizeof(nfapi_crc_indication_pdu_t)*ind->crc_indication_body.number_of_crcs ); + assert(ind->crc_indication_body.number_of_crcs <= NFAPI_CRC_IND_MAX_PDU); + if (ind->crc_indication_body.number_of_crcs > 0) { + UL_RCC_INFO.crc_ind[index].crc_indication_body.crc_pdu_list = malloc(sizeof(nfapi_crc_indication_pdu_t) * NFAPI_CRC_IND_MAX_PDU); + } + assert(ind->crc_indication_body.number_of_crcs <= NFAPI_CRC_IND_MAX_PDU); for (int i=0; icrc_indication_body.number_of_crcs; i++) { memcpy(&UL_RCC_INFO.crc_ind[index].crc_indication_body.crc_pdu_list[i], &ind->crc_indication_body.crc_pdu_list[i], sizeof(ind->crc_indication_body.crc_pdu_list[0])); @@ -804,6 +925,7 @@ int phy_crc_indication(struct nfapi_vnf_p7_config *config, nfapi_crc_indication_ LOG_D(MAC, "%s() NFAPI SFN/SF:%d IND:number_of_crcs:%u UL_INFO:crcs:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->crc_indication_body.number_of_crcs, eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs); + assert(ind->crc_indication_body.number_of_crcs <= NFAPI_CRC_IND_MAX_PDU); for (int i=0; icrc_indication_body.number_of_crcs; i++) { memcpy(&dest_ind->crc_indication_body.crc_pdu_list[i], &ind->crc_indication_body.crc_pdu_list[i], sizeof(ind->crc_indication_body.crc_pdu_list[0])); LOG_D(MAC, "%s() NFAPI SFN/SF:%d CRC_IND:number_of_crcs:%u UL_INFO:crcs:%d PDU[%d] rnti:%04x UL_INFO:rnti:%04x\n", @@ -814,12 +936,54 @@ int phy_crc_indication(struct nfapi_vnf_p7_config *config, nfapi_crc_indication_ eNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list[i].rx_ue_information.rnti); } } - pthread_mutex_unlock(&eNB->UL_INFO_mutex); + AssertFatal(pthread_mutex_unlock(&eNB->UL_INFO_mutex)==0, "Mutex unlock failed"); // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); //mac_crc_ind(p7_vnf->mac, ind); return 1; } +int phy_nr_crc_indication(nfapi_nr_crc_indication_t *ind) { + + LOG_I(NR_MAC, "In %s() NFAPI SFN/SF: %d/%d number_of_pdus :%u\n", + __FUNCTION__,ind->sfn, ind->slot, ind->number_crcs); + + if(NFAPI_MODE == NFAPI_MODE_VNF) + { + nfapi_nr_crc_indication_t *crc_ind = CALLOC(1, sizeof(*crc_ind)); + crc_ind->header.message_id = ind->header.message_id; + crc_ind->number_crcs = ind->number_crcs; + crc_ind->sfn = ind->sfn; + crc_ind->slot = ind->slot; + if (ind->number_crcs > 0) { + crc_ind->crc_list = CALLOC(NFAPI_NR_CRC_IND_MAX_PDU, sizeof(nfapi_nr_crc_t)); + AssertFatal(crc_ind->crc_list != NULL, "Memory not allocated for crc_ind->crc_list in phy_nr_crc_indication."); + } + for (int j = 0; j < ind->number_crcs; j++) + { + crc_ind->crc_list[j].handle = ind->crc_list[j].handle; + crc_ind->crc_list[j].harq_id = ind->crc_list[j].harq_id; + crc_ind->crc_list[j].num_cb = ind->crc_list[j].num_cb; + crc_ind->crc_list[j].rnti = ind->crc_list[j].rnti; + crc_ind->crc_list[j].tb_crc_status = ind->crc_list[j].tb_crc_status; + crc_ind->crc_list[j].timing_advance = ind->crc_list[j].timing_advance; + crc_ind->crc_list[j].ul_cqi = ind->crc_list[j].ul_cqi; + LOG_I(NR_MAC, "Received crc_ind.harq_id = %d for %d index SFN SLot %u %u with rnti %x\n", + ind->crc_list[j].harq_id, j, ind->sfn, ind->slot, ind->crc_list[j].rnti); + } + if (!put_queue(&gnb_crc_ind_queue, crc_ind)) + { + LOG_E(NR_MAC, "Put_queue failed for crc_ind\n"); + free(crc_ind->crc_list); + free(crc_ind); + } + } + else + { + LOG_E(NR_MAC, "NFAPI_MODE = %d not NFAPI_MODE_VNF(2)\n", nfapi_getmode()); + } + return 1; +} + int phy_rx_indication(struct nfapi_vnf_p7_config *config, nfapi_rx_indication_t *ind) { struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; @@ -827,51 +991,40 @@ int phy_rx_indication(struct nfapi_vnf_p7_config *config, nfapi_rx_indication_t LOG_D(MAC, "%s() NFAPI SFN/SF:%d number_of_pdus:%u\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->rx_indication_body.number_of_pdus); } - pthread_mutex_lock(&eNB->UL_INFO_mutex); + AssertFatal(pthread_mutex_lock(&eNB->UL_INFO_mutex)==0, "Mutex lock failed"); if(NFAPI_MODE == NFAPI_MODE_VNF){ - int8_t index = -1; - for(uint8_t i= 0;i< NUM_NFPAI_SUBFRAME;i++){ - if((UL_RCC_INFO.rx_ind[i].header.message_id == 0) && (index == -1)){ - index = i; - } - if(UL_RCC_INFO.crc_ind[i].sfn_sf == ind->sfn_sf){ - index = i; - break; - } - } - if(index == -1){ - LOG_E(MAC,"phy_rx_indication : num of rx reach max \n"); - pthread_mutex_unlock(&eNB->UL_INFO_mutex); - return 0; - } + int8_t index = NFAPI_SFNSF2SF(ind->sfn_sf); + UL_RCC_INFO.rx_ind[index] = *ind; - if (ind->rx_indication_body.number_of_pdus > 0) - UL_RCC_INFO.rx_ind[index].rx_indication_body.rx_pdu_list = malloc(sizeof(nfapi_rx_indication_pdu_t)*ind->rx_indication_body.number_of_pdus ); + size_t number_of_pdus = ind->rx_indication_body.number_of_pdus; + assert(number_of_pdus <= NFAPI_RX_IND_MAX_PDU); - for (int i=0; irx_indication_body.number_of_pdus; i++) { + if (number_of_pdus > 0) { + UL_RCC_INFO.rx_ind[index].rx_indication_body.rx_pdu_list = + malloc(sizeof(nfapi_rx_indication_pdu_t) * NFAPI_RX_IND_MAX_PDU); + } + + for (int i=0; irx_indication_body.rx_pdu_list[i]; memcpy(dest_pdu, src_pdu, sizeof(*src_pdu)); - // DJP - TODO FIXME - intentional memory leak if(dest_pdu->rx_indication_rel8.length > 0){ - dest_pdu->data = malloc(dest_pdu->rx_indication_rel8.length); - memcpy(dest_pdu->data, src_pdu->data, dest_pdu->rx_indication_rel8.length); - }else{ - dest_pdu->data = NULL; + assert(dest_pdu->rx_indication_rel8.length <= NFAPI_RX_IND_DATA_MAX); + memcpy(dest_pdu->rx_ind_data, src_pdu->rx_ind_data, dest_pdu->rx_indication_rel8.length); } - LOG_D(PHY, "%s() NFAPI SFN/SF:%d PDUs:%d [PDU:%d] handle:%d rnti:%04x length:%d offset:%d ul_cqi:%d ta:%d data:%p\n", + LOG_D(PHY, "%s() NFAPI SFN/SF:%d PDUs:%zu [PDU:%d] handle:%d rnti:%04x length:%d offset:%d ul_cqi:%d ta:%d data:%p\n", __FUNCTION__, - NFAPI_SFNSF2DEC(ind->sfn_sf), ind->rx_indication_body.number_of_pdus, i, + NFAPI_SFNSF2DEC(ind->sfn_sf), number_of_pdus, i, dest_pdu->rx_ue_information.handle, dest_pdu->rx_ue_information.rnti, dest_pdu->rx_indication_rel8.length, dest_pdu->rx_indication_rel8.offset, dest_pdu->rx_indication_rel8.ul_cqi, dest_pdu->rx_indication_rel8.timing_advance, - dest_pdu->data + dest_pdu->rx_ind_data ); } }else{ @@ -880,13 +1033,15 @@ int phy_rx_indication(struct nfapi_vnf_p7_config *config, nfapi_rx_indication_t *dest_ind = *ind; dest_ind->rx_indication_body.rx_pdu_list = dest_pdu_list; + assert(ind->rx_indication_body.number_of_pdus <= NFAPI_RX_IND_MAX_PDU); for(int i=0; irx_indication_body.number_of_pdus; i++) { nfapi_rx_indication_pdu_t *dest_pdu = &dest_ind->rx_indication_body.rx_pdu_list[i]; nfapi_rx_indication_pdu_t *src_pdu = &ind->rx_indication_body.rx_pdu_list[i]; memcpy(dest_pdu, src_pdu, sizeof(*src_pdu)); - // DJP - TODO FIXME - intentional memory leak - dest_pdu->data = malloc(dest_pdu->rx_indication_rel8.length); - memcpy(dest_pdu->data, src_pdu->data, dest_pdu->rx_indication_rel8.length); + + assert(dest_pdu->rx_indication_rel8.length <= NFAPI_RX_IND_DATA_MAX); + memcpy(dest_pdu->rx_ind_data, src_pdu->rx_ind_data, dest_pdu->rx_indication_rel8.length); + LOG_D(PHY, "%s() NFAPI SFN/SF:%d PDUs:%d [PDU:%d] handle:%d rnti:%04x length:%d offset:%d ul_cqi:%d ta:%d data:%p\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->rx_indication_body.number_of_pdus, i, @@ -896,15 +1051,57 @@ int phy_rx_indication(struct nfapi_vnf_p7_config *config, nfapi_rx_indication_t dest_pdu->rx_indication_rel8.offset, dest_pdu->rx_indication_rel8.ul_cqi, dest_pdu->rx_indication_rel8.timing_advance, - dest_pdu->data + dest_pdu->rx_ind_data ); } } - pthread_mutex_unlock(&eNB->UL_INFO_mutex); + AssertFatal(pthread_mutex_unlock(&eNB->UL_INFO_mutex)==0, "Mutex unlock failed"); // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); //mac_rx_ind(p7_vnf->mac, ind); return 1; } + +int phy_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind) { + + LOG_I(NR_MAC, "In %s() NFAPI SFN/SF: %d/%d number_of_pdus :%u, and pdu %p\n", + __FUNCTION__,ind->sfn, ind->slot, ind->number_of_pdus, ind->pdu_list[0].pdu); + + if(NFAPI_MODE == NFAPI_MODE_VNF) + { + nfapi_nr_rx_data_indication_t *rx_ind = CALLOC(1, sizeof(*rx_ind)); + rx_ind->header.message_id = ind->header.message_id; + rx_ind->sfn = ind->sfn; + rx_ind->slot = ind->slot; + rx_ind->number_of_pdus = ind->number_of_pdus; + + if (ind->number_of_pdus > 0) { + rx_ind->pdu_list = CALLOC(NFAPI_NR_RX_DATA_IND_MAX_PDU, sizeof(nfapi_nr_rx_data_pdu_t)); + AssertFatal(rx_ind->pdu_list != NULL, "Memory not allocated for rx_ind->pdu_list in phy_nr_rx_data_indication."); + } + for (int j = 0; j < ind->number_of_pdus; j++) + { + rx_ind->pdu_list[j].handle = ind->pdu_list[j].handle; + rx_ind->pdu_list[j].harq_id = ind->pdu_list[j].harq_id; + rx_ind->pdu_list[j].pdu = ind->pdu_list[j].pdu; + rx_ind->pdu_list[j].pdu_length = ind->pdu_list[j].pdu_length; + rx_ind->pdu_list[j].rnti = ind->pdu_list[j].rnti; + rx_ind->pdu_list[j].timing_advance = ind->pdu_list[j].timing_advance; + rx_ind->pdu_list[j].ul_cqi = ind->pdu_list[j].ul_cqi; + } + if (!put_queue(&gnb_rx_ind_queue, rx_ind)) + { + LOG_E(NR_MAC, "Put_queue failed for rx_ind\n"); + free(rx_ind->pdu_list); + free(rx_ind); + } + } + else + { + LOG_E(NR_MAC, "NFAPI_MODE = %d not NFAPI_MODE_VNF(2)\n", nfapi_getmode()); + } + return 1; +} + int phy_srs_indication(struct nfapi_vnf_p7_config *config, nfapi_srs_indication_t *ind) { // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); //mac_srs_ind(p7_vnf->mac, ind); @@ -914,25 +1111,18 @@ int phy_srs_indication(struct nfapi_vnf_p7_config *config, nfapi_srs_indication_ int phy_sr_indication(struct nfapi_vnf_p7_config *config, nfapi_sr_indication_t *ind) { struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; LOG_D(MAC, "%s() NFAPI SFN/SF:%d srs:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->sr_indication_body.number_of_srs); - pthread_mutex_lock(&eNB->UL_INFO_mutex); + AssertFatal(pthread_mutex_lock(&eNB->UL_INFO_mutex)==0, "Mutex lock failed"); if(NFAPI_MODE == NFAPI_MODE_VNF){ - int8_t index = -1; - for(uint8_t i= 0;i< NUM_NFPAI_SUBFRAME;i++){ - if((UL_RCC_INFO.sr_ind[i].header.message_id == 0) && (index == -1)){ - index = i; - break; - } - } - if(index == -1){ - LOG_E(MAC,"phy_sr_indication : num of sr reach max \n"); - pthread_mutex_unlock(&eNB->UL_INFO_mutex); - return 0; - } + int8_t index = NFAPI_SFNSF2SF(ind->sfn_sf); + UL_RCC_INFO.sr_ind[index] = *ind; LOG_D(MAC,"%s() UL_INFO[%d].sr_ind.sr_indication_body.number_of_srs:%d\n", __FUNCTION__, index, eNB->UL_INFO.sr_ind.sr_indication_body.number_of_srs); - if (ind->sr_indication_body.number_of_srs > 0) - UL_RCC_INFO.sr_ind[index].sr_indication_body.sr_pdu_list = malloc(sizeof(nfapi_sr_indication_pdu_t)*ind->sr_indication_body.number_of_srs ); + if (ind->sr_indication_body.number_of_srs > 0) { + assert(ind->sr_indication_body.number_of_srs <= NFAPI_SR_IND_MAX_PDU); + UL_RCC_INFO.sr_ind[index].sr_indication_body.sr_pdu_list = malloc(sizeof(nfapi_sr_indication_pdu_t) * NFAPI_SR_IND_MAX_PDU); + } + assert(ind->sr_indication_body.number_of_srs <= NFAPI_SR_IND_MAX_PDU); for (int i=0; isr_indication_body.number_of_srs; i++) { nfapi_sr_indication_pdu_t *dest_pdu = &UL_RCC_INFO.sr_ind[index].sr_indication_body.sr_pdu_list[i]; nfapi_sr_indication_pdu_t *src_pdu = &ind->sr_indication_body.sr_pdu_list[i]; @@ -948,6 +1138,7 @@ int phy_sr_indication(struct nfapi_vnf_p7_config *config, nfapi_sr_indication_t dest_ind->sr_indication_body.sr_pdu_list = dest_pdu_list; LOG_D(MAC,"%s() eNB->UL_INFO.sr_ind.sr_indication_body.number_of_srs:%d\n", __FUNCTION__, eNB->UL_INFO.sr_ind.sr_indication_body.number_of_srs); + assert(eNB->UL_INFO.sr_ind.sr_indication_body.number_of_srs <= NFAPI_SR_IND_MAX_PDU); for (int i=0; iUL_INFO.sr_ind.sr_indication_body.number_of_srs; i++) { nfapi_sr_indication_pdu_t *dest_pdu = &dest_ind->sr_indication_body.sr_pdu_list[i]; nfapi_sr_indication_pdu_t *src_pdu = &ind->sr_indication_body.sr_pdu_list[i]; @@ -955,36 +1146,63 @@ int phy_sr_indication(struct nfapi_vnf_p7_config *config, nfapi_sr_indication_t memcpy(dest_pdu, src_pdu, sizeof(*src_pdu)); } } - pthread_mutex_unlock(&eNB->UL_INFO_mutex); + AssertFatal(pthread_mutex_unlock(&eNB->UL_INFO_mutex)==0, "Mutex unlock failed"); // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); //mac_sr_ind(p7_vnf->mac, ind); return 1; } +static bool is_ue_same(uint16_t ue_id_1, uint16_t ue_id_2) +{ + return (ue_id_1 == ue_id_2); +} + +static void analyze_cqi_pdus_for_duplicates(nfapi_cqi_indication_t *ind) +{ + uint16_t num_cqis = ind->cqi_indication_body.number_of_cqis; + assert(num_cqis <= NFAPI_CQI_IND_MAX_PDU); + for (int i = 0; i < num_cqis; i++) + { + nfapi_cqi_indication_pdu_t *src_pdu = &ind->cqi_indication_body.cqi_pdu_list[i]; + + LOG_I(MAC, "CQI_IND[PDU:%d][rnti:%x cqi:%d channel:%d]\n", i, src_pdu->rx_ue_information.rnti, + src_pdu->ul_cqi_information.ul_cqi, src_pdu->ul_cqi_information.channel); + + for (int j = i + 1; j < num_cqis; j++) + { + uint16_t rnti_i = ind->cqi_indication_body.cqi_pdu_list[i].rx_ue_information.rnti; + uint16_t rnti_j = ind->cqi_indication_body.cqi_pdu_list[j].rx_ue_information.rnti; + if (is_ue_same(rnti_i, rnti_j)) + { + LOG_E(MAC, "Problem, two cqis received from a single UE for rnti %x\n", + rnti_i); + //abort(); This will be fixed in merge request which handles multiple CQIs. + } + } + } +} + int phy_cqi_indication(struct nfapi_vnf_p7_config *config, nfapi_cqi_indication_t *ind) { // vnf_p7_info* p7_vnf = (vnf_p7_info*)(config->user_data); //mac_cqi_ind(p7_vnf->mac, ind); struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; LOG_D(MAC, "%s() NFAPI SFN/SF:%d number_of_cqis:%u\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind->sfn_sf), ind->cqi_indication_body.number_of_cqis); - pthread_mutex_lock(&eNB->UL_INFO_mutex); + AssertFatal(pthread_mutex_lock(&eNB->UL_INFO_mutex)==0, "Mutex lock failed"); if(NFAPI_MODE == NFAPI_MODE_VNF){ - int8_t index = -1; - for(uint8_t i= 0;i< NUM_NFPAI_SUBFRAME;i++){ - if((UL_RCC_INFO.cqi_ind[i].header.message_id == 0) && (index == -1)){ - index = i; - break; - } - } - if(index == -1){ - LOG_E(MAC,"phy_cqi_indication : num of cqi reach max \n"); - pthread_mutex_unlock(&eNB->UL_INFO_mutex); - return 0; - } + int8_t index = NFAPI_SFNSF2SF(ind->sfn_sf); + UL_RCC_INFO.cqi_ind[index] = *ind; + assert(ind->cqi_indication_body.number_of_cqis <= NFAPI_CQI_IND_MAX_PDU); if (ind->cqi_indication_body.number_of_cqis > 0){ - UL_RCC_INFO.cqi_ind[index].cqi_indication_body.cqi_pdu_list = malloc(sizeof(nfapi_cqi_indication_pdu_t)*ind->cqi_indication_body.number_of_cqis ); - UL_RCC_INFO.cqi_ind[index].cqi_indication_body.cqi_raw_pdu_list = malloc(sizeof(nfapi_cqi_indication_raw_pdu_t)*ind->cqi_indication_body.number_of_cqis ); + UL_RCC_INFO.cqi_ind[index].cqi_indication_body.cqi_pdu_list = + malloc(sizeof(nfapi_cqi_indication_pdu_t) * NFAPI_CQI_IND_MAX_PDU); + UL_RCC_INFO.cqi_ind[index].cqi_indication_body.cqi_raw_pdu_list = + malloc(sizeof(nfapi_cqi_indication_raw_pdu_t) * NFAPI_CQI_IND_MAX_PDU); } + + analyze_cqi_pdus_for_duplicates(ind); + + assert(ind->cqi_indication_body.number_of_cqis <= NFAPI_CQI_IND_MAX_PDU); for (int i=0; icqi_indication_body.number_of_cqis; i++) { nfapi_cqi_indication_pdu_t *src_pdu = &ind->cqi_indication_body.cqi_pdu_list[i]; LOG_D(MAC, "SR_IND[PDU:%d][rnti:%x cqi:%d channel:%d]\n", i, src_pdu->rx_ue_information.rnti, @@ -1000,9 +1218,10 @@ int phy_cqi_indication(struct nfapi_vnf_p7_config *config, nfapi_cqi_indication_ *dest_ind = *ind; dest_ind->cqi_indication_body.cqi_pdu_list = ind->cqi_indication_body.cqi_pdu_list; dest_ind->cqi_indication_body.cqi_raw_pdu_list = ind->cqi_indication_body.cqi_raw_pdu_list; + assert(ind->cqi_indication_body.number_of_cqis <= NFAPI_CQI_IND_MAX_PDU); for(int i=0; icqi_indication_body.number_of_cqis; i++) { nfapi_cqi_indication_pdu_t *src_pdu = &ind->cqi_indication_body.cqi_pdu_list[i]; - LOG_D(MAC, "SR_IND[PDU:%d][rnti:%x cqi:%d channel:%d]\n", i, src_pdu->rx_ue_information.rnti, + LOG_D(MAC, "CQI_IND[PDU:%d][rnti:%x cqi:%d channel:%d]\n", i, src_pdu->rx_ue_information.rnti, src_pdu->ul_cqi_information.ul_cqi, src_pdu->ul_cqi_information.channel); memcpy(&dest_ind->cqi_indication_body.cqi_pdu_list[i], src_pdu, sizeof(nfapi_cqi_indication_pdu_t)); @@ -1010,79 +1229,34 @@ int phy_cqi_indication(struct nfapi_vnf_p7_config *config, nfapi_cqi_indication_ &ind->cqi_indication_body.cqi_raw_pdu_list[i], sizeof(nfapi_cqi_indication_raw_pdu_t)); } } - pthread_mutex_unlock(&eNB->UL_INFO_mutex); + AssertFatal(pthread_mutex_unlock(&eNB->UL_INFO_mutex)==0, "Mutex unlock failed"); return 1; } //NR phy indication int phy_nr_slot_indication(nfapi_nr_slot_indication_scf_t *ind) { - - uint8_t vnf_slot_ahead = 2; + + uint8_t vnf_slot_ahead = 0; uint32_t vnf_sfn_slot = sfnslot_add_slot(ind->sfn, ind->slot, vnf_slot_ahead); - uint16_t vnf_sfn = NFAPI_SFNSLOT2SFN(vnf_sfn_slot); - uint8_t vnf_slot = NFAPI_SFNSLOT2SLOT(vnf_sfn_slot); //offsetting the vnf from pnf by vnf_slot_head slots - struct PHY_VARS_gNB_s *gNB = RC.gNB[0]; - pthread_mutex_lock(&gNB->UL_INFO_mutex); - gNB->UL_INFO.frame = vnf_sfn; - gNB->UL_INFO.slot = vnf_slot; - pthread_mutex_unlock(&gNB->UL_INFO_mutex); - LOG_D(MAC, "VNF SFN/Slot %d.%d \n", gNB->UL_INFO.frame, gNB->UL_INFO.slot); + uint16_t vnf_sfn = NFAPI_SFNSLOT2SFN(vnf_sfn_slot); + uint8_t vnf_slot = NFAPI_SFNSLOT2SLOT(vnf_sfn_slot); + LOG_D(MAC, "VNF SFN/Slot %d.%d \n", vnf_sfn, vnf_slot); + + nfapi_nr_slot_indication_scf_t *nr_slot_ind = CALLOC(1, sizeof(*nr_slot_ind)); + nr_slot_ind->header = ind->header; + nr_slot_ind->sfn = vnf_sfn; + nr_slot_ind->slot = vnf_slot; + if (!put_queue(&gnb_slot_ind_queue, nr_slot_ind)) + { + LOG_E(NR_MAC, "Put_queue failed for slot_ind\n"); + free(nr_slot_ind); + nr_slot_ind = NULL; + } return 1; } -int phy_nr_crc_indication(nfapi_nr_crc_indication_t *ind) { - struct PHY_VARS_gNB_s *gNB = RC.gNB[0]; - pthread_mutex_lock(&gNB->UL_INFO_mutex); - - gNB->UL_INFO.crc_ind = *ind; - - if (ind->number_crcs > 0) - gNB->UL_INFO.crc_ind.crc_list = malloc(sizeof(nfapi_nr_crc_t)*ind->number_crcs); - - for (int i=0; inumber_crcs; i++) - memcpy(&gNB->UL_INFO.crc_ind.crc_list[i], &ind->crc_list[i], sizeof(ind->crc_list[0])); - - pthread_mutex_unlock(&gNB->UL_INFO_mutex); - - return 1; -} - -int phy_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind) { - struct PHY_VARS_gNB_s *gNB = RC.gNB[0]; - pthread_mutex_lock(&gNB->UL_INFO_mutex); - - gNB->UL_INFO.rx_ind = *ind; - - if (ind->number_of_pdus > 0) - gNB->UL_INFO.rx_ind.pdu_list = malloc(sizeof(nfapi_nr_rx_data_pdu_t)*ind->number_of_pdus); - - for (int i=0; inumber_of_pdus; i++) - memcpy(&gNB->UL_INFO.rx_ind.pdu_list[i], &ind->pdu_list[i], sizeof(ind->pdu_list[0])); - - - pthread_mutex_unlock(&gNB->UL_INFO_mutex); - - return 1; -} - -int phy_nr_uci_indication(nfapi_nr_uci_indication_t *ind) { - struct PHY_VARS_gNB_s *gNB = RC.gNB[0]; - pthread_mutex_lock(&gNB->UL_INFO_mutex); - - gNB->UL_INFO.uci_ind = *ind; - - if (ind->num_ucis > 0) - gNB->UL_INFO.uci_ind.uci_list = malloc(sizeof(nfapi_nr_uci_t)*ind->num_ucis); - - for (int i=0; inum_ucis; i++) - memcpy(&gNB->UL_INFO.uci_ind.uci_list[i], &ind->uci_list[i], sizeof(ind->uci_list[0])); - //printf("UCI ind written to UL_info: num_ucis: %d, PDU_type : %d. \n", ind->num_ucis, ind->uci_list[0].pdu_type); - pthread_mutex_unlock(&gNB->UL_INFO_mutex); - - return 1; -} int phy_nr_srs_indication(nfapi_nr_srs_indication_t *ind) { struct PHY_VARS_gNB_s *gNB = RC.gNB[0]; @@ -1106,30 +1280,6 @@ int phy_nr_srs_indication(nfapi_nr_srs_indication_t *ind) { return 1; } - -int phy_nr_rach_indication(nfapi_nr_rach_indication_t *ind) { - struct PHY_VARS_gNB_s *gNB = RC.gNB[0]; - pthread_mutex_lock(&gNB->UL_INFO_mutex); - - gNB->UL_INFO.rach_ind = *ind; - - if (ind->number_of_pdus > 0) - gNB->UL_INFO.rach_ind.pdu_list = malloc(sizeof(nfapi_nr_prach_indication_pdu_t)*ind->number_of_pdus); - - for (int i=0; inumber_of_pdus; i++) { - memcpy(&gNB->UL_INFO.rach_ind.pdu_list[i], &ind->pdu_list[i], sizeof(ind->pdu_list[0])); - - LOG_D(MAC, "%s() NFAPI SFN/Slot:%d.%d RACH_IND:number_of_pdus:%d UL_INFO:pdus:%d\n", - __FUNCTION__, - ind->sfn,ind->slot, ind->number_of_pdus, gNB->UL_INFO.rach_ind.number_of_pdus - ); - } - - pthread_mutex_unlock(&gNB->UL_INFO_mutex); - - return 1; -} - //end NR phy indication int phy_lbt_dl_indication(struct nfapi_vnf_p7_config *config, nfapi_lbt_dl_indication_t *ind) { @@ -1171,9 +1321,9 @@ void vnf_trace(nfapi_trace_level_t nfapi_level, const char *message, ...) { int phy_vendor_ext(struct nfapi_vnf_p7_config *config, nfapi_p7_message_header_t *msg) { if(msg->message_id == P7_VENDOR_EXT_IND) { //vendor_ext_p7_ind* ind = (vendor_ext_p7_ind*)msg; - //printf("[VNF] vendor_ext (error_code:%d)\n", ind->error_code); + //NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] vendor_ext (error_code:%d)\n", ind->error_code); } else { - printf("[VNF] unknown %02x\n", msg->message_id); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] unknown %02x\n", msg->message_id); } return 0; @@ -1263,7 +1413,7 @@ static pthread_t vnf_start_pthread; static pthread_t vnf_p7_start_pthread; void *vnf_nr_p7_start_thread(void *ptr) { - printf("%s()\n", __FUNCTION__); + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s()\n", __FUNCTION__); pthread_setname_np(pthread_self(), "VNF_P7"); nfapi_vnf_p7_config_t *config = (nfapi_vnf_p7_config_t *)ptr; nfapi_nr_vnf_p7_start(config); @@ -1271,7 +1421,7 @@ void *vnf_nr_p7_start_thread(void *ptr) { } void *vnf_p7_start_thread(void *ptr) { - printf("%s()\n", __FUNCTION__); + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s()\n", __FUNCTION__); pthread_setname_np(pthread_self(), "VNF_P7"); nfapi_vnf_p7_config_t *config = (nfapi_vnf_p7_config_t *)ptr; nfapi_vnf_p7_start(config); @@ -1282,30 +1432,31 @@ void set_thread_priority(int priority); void *vnf_nr_p7_thread_start(void *ptr) { set_thread_priority(79); + init_queue(&gnb_rach_ind_queue); + init_queue(&gnb_rx_ind_queue); + init_queue(&gnb_crc_ind_queue); + init_queue(&gnb_uci_ind_queue); + init_queue(&gnb_slot_ind_queue); + vnf_p7_info *p7_vnf = (vnf_p7_info *)ptr; p7_vnf->config->port = p7_vnf->local_port; p7_vnf->config->sync_indication = &phy_sync_indication; p7_vnf->config->slot_indication = &phy_slot_indication; - p7_vnf->config->harq_indication = &phy_harq_indication; - p7_vnf->config->crc_indication = &phy_crc_indication; - p7_vnf->config->rx_indication = &phy_rx_indication; - p7_vnf->config->rach_indication = &phy_rach_indication; + p7_vnf->config->nr_crc_indication = &phy_nr_crc_indication; + p7_vnf->config->nr_rx_data_indication = &phy_nr_rx_data_indication; + p7_vnf->config->nr_rach_indication = &phy_nr_rach_indication; + p7_vnf->config->nr_uci_indication = &phy_nr_uci_indication; p7_vnf->config->srs_indication = &phy_srs_indication; p7_vnf->config->sr_indication = &phy_sr_indication; p7_vnf->config->cqi_indication = &phy_cqi_indication; p7_vnf->config->lbt_dl_indication = &phy_lbt_dl_indication; p7_vnf->config->nb_harq_indication = &phy_nb_harq_indication; p7_vnf->config->nrach_indication = &phy_nrach_indication; - p7_vnf->config->nr_crc_indication = &phy_nr_crc_indication; - p7_vnf->config->nr_slot_indication = &phy_nr_slot_indication; - p7_vnf->config->nr_rx_data_indication = &phy_nr_rx_data_indication; - p7_vnf->config->nr_uci_indication = &phy_nr_uci_indication; - p7_vnf->config->nr_rach_indication = &phy_nr_rach_indication; + p7_vnf->config->nr_slot_indication = &phy_nr_slot_indication; p7_vnf->config->nr_srs_indication = &phy_nr_srs_indication; p7_vnf->config->malloc = &vnf_allocate; p7_vnf->config->free = &vnf_deallocate; - p7_vnf->config->trace = &vnf_trace; p7_vnf->config->vendor_ext = &phy_vendor_ext; p7_vnf->config->user_data = p7_vnf; p7_vnf->mac->user_data = p7_vnf; @@ -1342,7 +1493,6 @@ void *vnf_p7_thread_start(void *ptr) { p7_vnf->config->nrach_indication = &phy_nrach_indication; p7_vnf->config->malloc = &vnf_allocate; p7_vnf->config->free = &vnf_deallocate; - p7_vnf->config->trace = &vnf_trace; p7_vnf->config->vendor_ext = &phy_vendor_ext; p7_vnf->config->user_data = p7_vnf; p7_vnf->mac->user_data = p7_vnf; @@ -1364,7 +1514,7 @@ int pnf_nr_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_st vnf_p7_info *p7_vnf = vnf->p7_vnfs; pnf_info *pnf = vnf->pnfs; nfapi_nr_param_request_scf_t req; - printf("[VNF] pnf start response idx:%d config:%p user_data:%p p7_vnf[config:%p thread_started:%d]\n", p5_idx, config, config->user_data, vnf->p7_vnfs[0].config, vnf->p7_vnfs[0].thread_started); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] pnf start response idx:%d config:%p user_data:%p p7_vnf[config:%p thread_started:%d]\n", p5_idx, config, config->user_data, vnf->p7_vnfs[0].config, vnf->p7_vnfs[0].thread_started); if(p7_vnf->thread_started == 0) { pthread_t vnf_p7_thread; @@ -1375,7 +1525,7 @@ int pnf_nr_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_st } // start all the phys in the pnf. - printf("[VNF] Sending NFAPI_VNF_PARAM_REQUEST phy_id:%d\n", pnf->phys[0].id); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Sending NFAPI_VNF_PARAM_REQUEST phy_id:%d\n", pnf->phys[0].id); memset(&req, 0, sizeof(req)); req.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST; req.header.phy_id = pnf->phys[0].id; @@ -1388,7 +1538,7 @@ int pnf_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_start_re vnf_p7_info *p7_vnf = vnf->p7_vnfs; pnf_info *pnf = vnf->pnfs; nfapi_param_request_t req; - printf("[VNF] pnf start response idx:%d config:%p user_data:%p p7_vnf[config:%p thread_started:%d]\n", p5_idx, config, config->user_data, vnf->p7_vnfs[0].config, vnf->p7_vnfs[0].thread_started); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] pnf start response idx:%d config:%p user_data:%p p7_vnf[config:%p thread_started:%d]\n", p5_idx, config, config->user_data, vnf->p7_vnfs[0].config, vnf->p7_vnfs[0].thread_started); if(p7_vnf->thread_started == 0) { pthread_t vnf_p7_thread; @@ -1399,7 +1549,7 @@ int pnf_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_start_re } // start all the phys in the pnf. - printf("[VNF] Sending NFAPI_VNF_PARAM_REQUEST phy_id:%d\n", pnf->phys[0].id); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Sending NFAPI_VNF_PARAM_REQUEST phy_id:%d\n", pnf->phys[0].id); memset(&req, 0, sizeof(req)); req.header.message_id = NFAPI_PARAM_REQUEST; req.header.phy_id = pnf->phys[0].id; @@ -1411,37 +1561,38 @@ extern uint32_t to_earfcn(int eutra_bandP,uint32_t dl_CarrierFreq,uint32_t bw); int nr_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_param_response_scf_t *resp) { - printf("[VNF] Received NFAPI_PARAM_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Received NFAPI_PARAM_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); vnf_info *vnf = (vnf_info *)(config->user_data); vnf_p7_info *p7_vnf = vnf->p7_vnfs; pnf_info *pnf = vnf->pnfs; phy_info *phy = pnf->phys; struct sockaddr_in pnf_p7_sockaddr; nfapi_nr_config_request_scf_t *req = &RC.nrmac[0]->config[0]; // check - phy->remote_port = 32123;//resp->nfapi_config.p7_pnf_port.value; + phy->remote_port = 50610;//resp->nfapi_config.p7_pnf_port.value; + //phy->remote_port = 32123;//resp->nfapi_config.p7_pnf_port.value; memcpy(&pnf_p7_sockaddr.sin_addr.s_addr, &(resp->nfapi_config.p7_pnf_address_ipv4.address[0]), 4); phy->remote_addr = inet_ntoa(pnf_p7_sockaddr.sin_addr); // for now just 1 - printf("[VNF] %d.%d pnf p7 %s:%d timing %u %u %u %u\n", p5_idx, phy->id, phy->remote_addr, phy->remote_port, p7_vnf->timing_window, p7_vnf->periodic_timing_period, p7_vnf->aperiodic_timing_enabled, + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %d.%d pnf p7 %s:%d timing %u %u %u %u\n", p5_idx, phy->id, phy->remote_addr, phy->remote_port, p7_vnf->timing_window, p7_vnf->periodic_timing_period, p7_vnf->aperiodic_timing_enabled, p7_vnf->periodic_timing_period); req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST; req->header.phy_id = phy->id; - printf("[VNF] Send NFAPI_CONFIG_REQUEST\n"); - //printf("\n NR bandP =%d\n",req->nfapi_config.rf_bands.rf_band[0]); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Send NFAPI_CONFIG_REQUEST\n"); + //NFAPI_TRACE(NFAPI_TRACE_INFO, "\n NR bandP =%d\n",req->nfapi_config.rf_bands.rf_band[0]); req->nfapi_config.p7_vnf_port.tl.tag = NFAPI_NR_NFAPI_P7_VNF_PORT_TAG; req->nfapi_config.p7_vnf_port.value = p7_vnf->local_port; req->num_tlv++; - printf("[VNF] DJP local_port:%d\n", p7_vnf->local_port); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] DJP local_port:%d\n", p7_vnf->local_port); req->nfapi_config.p7_vnf_address_ipv4.tl.tag = NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG; struct sockaddr_in vnf_p7_sockaddr; vnf_p7_sockaddr.sin_addr.s_addr = inet_addr(p7_vnf->local_addr); memcpy(&(req->nfapi_config.p7_vnf_address_ipv4.address[0]), &vnf_p7_sockaddr.sin_addr.s_addr, 4); req->num_tlv++; - printf("[VNF] DJP local_addr:%s\n", p7_vnf->local_addr); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] DJP local_addr:%s\n", p7_vnf->local_addr); req->nfapi_config.timing_window.tl.tag = NFAPI_NR_NFAPI_TIMING_WINDOW_TAG; req->nfapi_config.timing_window.value = p7_vnf->timing_window; - printf("\n[VNF]Timing window tag : %d Timing window:%u\n",NFAPI_NR_NFAPI_TIMING_WINDOW_TAG, p7_vnf->timing_window); + NFAPI_TRACE(NFAPI_TRACE_INFO, "\n[VNF]Timing window tag : %d Timing window:%u\n",NFAPI_NR_NFAPI_TIMING_WINDOW_TAG, p7_vnf->timing_window); req->num_tlv++; if(p7_vnf->periodic_timing_enabled || p7_vnf->aperiodic_timing_enabled) { @@ -1455,7 +1606,7 @@ int nr_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_param_resp req->num_tlv++; } } -//TODO: Assign tag and value for P7 message offsets +//TODO: Assign tag and value for P7 message offsets req->nfapi_config.dl_tti_timing_offset.tl.tag = NFAPI_NR_NFAPI_DL_TTI_TIMING_OFFSET; req->nfapi_config.ul_tti_timing_offset.tl.tag = NFAPI_NR_NFAPI_UL_TTI_TIMING_OFFSET; req->nfapi_config.ul_dci_timing_offset.tl.tag = NFAPI_NR_NFAPI_UL_DCI_TIMING_OFFSET; @@ -1473,7 +1624,7 @@ req->nfapi_config.tx_data_timing_offset.tl.tag = NFAPI_NR_NFAPI_TX_DATA_TIMING_O int param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_param_response_t *resp) { - printf("[VNF] Received NFAPI_PARAM_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Received NFAPI_PARAM_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); vnf_info *vnf = (vnf_info *)(config->user_data); vnf_p7_info *p7_vnf = vnf->p7_vnfs; pnf_info *pnf = vnf->pnfs; @@ -1484,24 +1635,24 @@ int param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_param_response_t memcpy(&pnf_p7_sockaddr.sin_addr.s_addr, &(resp->nfapi_config.p7_pnf_address_ipv4.address[0]), 4); phy->remote_addr = inet_ntoa(pnf_p7_sockaddr.sin_addr); // for now just 1 - printf("[VNF] %d.%d pnf p7 %s:%d timing %u %u %u %u\n", p5_idx, phy->id, phy->remote_addr, phy->remote_port, p7_vnf->timing_window, p7_vnf->periodic_timing_period, p7_vnf->aperiodic_timing_enabled, + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %d.%d pnf p7 %s:%d timing %u %u %u %u\n", p5_idx, phy->id, phy->remote_addr, phy->remote_port, p7_vnf->timing_window, p7_vnf->periodic_timing_period, p7_vnf->aperiodic_timing_enabled, p7_vnf->periodic_timing_period); req->header.message_id = NFAPI_CONFIG_REQUEST; req->header.phy_id = phy->id; - printf("[VNF] Send NFAPI_CONFIG_REQUEST\n"); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Send NFAPI_CONFIG_REQUEST\n"); req->nfapi_config.p7_vnf_port.tl.tag = NFAPI_NFAPI_P7_VNF_PORT_TAG; req->nfapi_config.p7_vnf_port.value = p7_vnf->local_port; req->num_tlv++; - printf("[VNF] DJP local_port:%d\n", p7_vnf->local_port); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] DJP local_port:%d\n", p7_vnf->local_port); req->nfapi_config.p7_vnf_address_ipv4.tl.tag = NFAPI_NFAPI_P7_VNF_ADDRESS_IPV4_TAG; struct sockaddr_in vnf_p7_sockaddr; vnf_p7_sockaddr.sin_addr.s_addr = inet_addr(p7_vnf->local_addr); memcpy(&(req->nfapi_config.p7_vnf_address_ipv4.address[0]), &vnf_p7_sockaddr.sin_addr.s_addr, 4); req->num_tlv++; - printf("[VNF] DJP local_addr:%s\n", p7_vnf->local_addr); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] DJP local_addr:%s\n", p7_vnf->local_addr); req->nfapi_config.timing_window.tl.tag = NFAPI_NFAPI_TIMING_WINDOW_TAG; req->nfapi_config.timing_window.value = p7_vnf->timing_window; - printf("[VNF] Timing window:%u\n", p7_vnf->timing_window); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Timing window:%u\n", p7_vnf->timing_window); req->num_tlv++; if(p7_vnf->periodic_timing_enabled || p7_vnf->aperiodic_timing_enabled) { @@ -1528,42 +1679,41 @@ int param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_param_response_t int nr_config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_config_response_scf_t *resp) { nfapi_nr_start_request_scf_t req; - printf("[VNF] Received NFAPI_CONFIG_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); - printf("[VNF] Calling oai_enb_init()\n"); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Received NFAPI_CONFIG_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Calling oai_enb_init()\n"); oai_enb_init(); // TODO: change to gnb memset(&req, 0, sizeof(req)); req.header.message_id = NFAPI_NR_PHY_MSG_TYPE_START_REQUEST; req.header.phy_id = resp->header.phy_id; nfapi_nr_vnf_start_req(config, p5_idx, &req); - printf("[VNF] Send NFAPI_VNF_START_REQUEST idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); return 0; } int config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_config_response_t *resp) { nfapi_start_request_t req; - printf("[VNF] Received NFAPI_CONFIG_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); - printf("[VNF] Calling oai_enb_init()\n"); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Received NFAPI_CONFIG_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Calling oai_enb_init()\n"); oai_enb_init(); memset(&req, 0, sizeof(req)); req.header.message_id = NFAPI_START_REQUEST; req.header.phy_id = resp->header.phy_id; nfapi_vnf_start_req(config, p5_idx, &req); - printf("[VNF] Send NFAPI_START_REQUEST idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Send NFAPI_VNF_START_REQUEST idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); return 0; } int start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_start_response_t *resp) { - printf("[VNF] Received NFAPI_START_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Received NFAPI_START_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); vnf_info *vnf = (vnf_info *)(config->user_data); pnf_info *pnf = vnf->pnfs; phy_info *phy = pnf->phys; vnf_p7_info *p7_vnf = vnf->p7_vnfs; - nfapi_vnf_p7_add_pnf((p7_vnf->config), phy->remote_addr, phy->remote_port, phy->id); + nfapi_vnf_p7_add_pnf((p7_vnf->config), phy->remote_addr, htons(phy->remote_port), phy->id); return 0; } int nr_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_start_response_scf_t *resp) { - printf("[VNF] Received NFAPI_START_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Received NFAPI_START_RESP idx:%d phy_id:%d\n", p5_idx, resp->header.phy_id); vnf_info *vnf = (vnf_info *)(config->user_data); pnf_info *pnf = vnf->pnfs; phy_info *phy = pnf->phys; @@ -1574,12 +1724,12 @@ int nr_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_start_resp } int vendor_ext_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_p4_p5_message_header_t *msg) { - printf("[VNF] %s\n", __FUNCTION__); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s\n", __FUNCTION__); switch(msg->message_id) { case P5_VENDOR_EXT_RSP: { vendor_ext_p5_rsp *rsp = (vendor_ext_p5_rsp *)msg; - printf("[VNF] P5_VENDOR_EXT_RSP error_code:%d\n", rsp->error_code); + NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] P5_VENDOR_EXT_RSP error_code:%d\n", rsp->error_code); // send the start request nfapi_pnf_start_request_t req; memset(&req, 0, sizeof(req)); @@ -1645,18 +1795,18 @@ void configure_nr_nfapi_vnf(char *vnf_addr, int vnf_p5_port) { NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s() vnf.p7_vnfs[0].config:%p VNF ADDRESS:%s:%d\n", __FUNCTION__, vnf.p7_vnfs[0].config, vnf_addr, vnf_p5_port); strcpy(vnf.p7_vnfs[0].local_addr, vnf_addr); //vnf.p7_vnfs[0].local_port = vnf.p7_vnfs[0].local_port; // 50001; // TODO: remove hardcode - vnf.p7_vnfs[0].local_port = 50011; + vnf.p7_vnfs[0].local_port = 50611; + //vnf.p7_vnfs[0].local_port = 50011; vnf.p7_vnfs[0].mac = (mac_t *)malloc(sizeof(mac_t)); nfapi_vnf_config_t *config = nfapi_vnf_config_create(); config->malloc = malloc; config->free = free; - config->trace = &vnf_trace; config->vnf_p5_port = vnf_p5_port; config->vnf_ipv4 = 1; config->vnf_ipv6 = 0; config->pnf_list = 0; config->phy_list = 0; - + config->pnf_nr_connection_indication = &pnf_nr_connection_indication_cb; config->pnf_disconnect_indication = &pnf_disconnection_indication_cb; @@ -1701,7 +1851,6 @@ void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port) { nfapi_vnf_config_t *config = nfapi_vnf_config_create(); config->malloc = malloc; config->free = free; - config->trace = &vnf_trace; config->vnf_p5_port = vnf_p5_port; config->vnf_ipv4 = 1; config->vnf_ipv6 = 0; @@ -1738,6 +1887,23 @@ int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config; dl_config_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! dl_config_req->header.message_id = NFAPI_DL_CONFIG_REQUEST; + LOG_I(PHY, "[VNF] %s() DL_CONFIG_REQ sfn_sf:%d_%d number_of_pdus:%d\n", __FUNCTION__, + NFAPI_SFNSF2SFN(dl_config_req->sfn_sf),NFAPI_SFNSF2SF(dl_config_req->sfn_sf), dl_config_req->dl_config_request_body.number_pdu); + if (dl_config_req->dl_config_request_body.number_pdu > 0) + { + for (int i = 0; i < dl_config_req->dl_config_request_body.number_pdu; i++) + { + uint8_t pdu_type = dl_config_req->dl_config_request_body.dl_config_pdu_list[i].pdu_type; + if(pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE) + { + uint16_t dl_rnti = dl_config_req->dl_config_request_body.dl_config_pdu_list[i].dlsch_pdu.dlsch_pdu_rel8.rnti; + uint16_t numPDUs = dl_config_req->dl_config_request_body.number_pdu; + LOG_I(MAC, "(OAI eNB) Sending dl_config_req at VNF during Frame: %d and Subframe: %d," + " with a RNTI value of: %x and with number of PDUs: %u\n", + NFAPI_SFNSF2SFN(dl_config_req->sfn_sf),NFAPI_SFNSF2SF(dl_config_req->sfn_sf), dl_rnti, numPDUs); + } + } + } int retval = nfapi_vnf_p7_dl_config_req(p7_config, dl_config_req); dl_config_req->dl_config_request_body.number_pdcch_ofdm_symbols = 1; dl_config_req->dl_config_request_body.number_dci = 0; @@ -1838,12 +2004,31 @@ int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { return retval; } +static void remove_ul_config_req_pdu(int index, nfapi_ul_config_request_t *ul_config_req) +{ + int num_pdus = ul_config_req->ul_config_request_body.number_of_pdus; + nfapi_ul_config_request_pdu_t *pdu_list = ul_config_req->ul_config_request_body.ul_config_pdu_list; + + if (index >= num_pdus || index < 0) + { + LOG_E(MAC, "%s() Unable to drop bad ul_config_req PDU\n", __FUNCTION__); + abort(); + } + + for(int i = index; i + 1 < num_pdus; i++) + { + pdu_list[i] = pdu_list[i + 1]; + } + + ul_config_req->ul_config_request_body.number_of_pdus--; +} + int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req) { nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config; ul_tti_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! ul_tti_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST; - + int retval = nfapi_vnf_p7_ul_tti_req(p7_config, ul_tti_req); if (retval!=0) { @@ -1864,6 +2049,44 @@ int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { ul_config_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; //LOG_D(PHY, "[VNF] %s() header message_id:%02x\n", __FUNCTION__, ul_config_req->header.message_id); //LOG_D(PHY, "[VNF] %s() UL_CONFIG sfn_sf:%d PDUs:%d rach_prach_frequency_resources:%d srs_present:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ul_config_req->sfn_sf), ul_config_req->ul_config_request_body.number_of_pdus, ul_config_req->ul_config_request_body.rach_prach_frequency_resources, ul_config_req->ul_config_request_body.srs_present); + + int num_pdus = ul_config_req->ul_config_request_body.number_of_pdus; + nfapi_ul_config_request_pdu_t *pdu_list = ul_config_req->ul_config_request_body.ul_config_pdu_list; + for (int i = 0; i < num_pdus; i++) + { + uint8_t pdu_type = pdu_list[i].pdu_type; + + LOG_I(MAC, "ul_config_req num_pdus: %u pdu_number: %d pdu_type: %u SFN.SF: %d.%d\n", + num_pdus, i, pdu_type, ul_config_req->sfn_sf >> 4, ul_config_req->sfn_sf & 15); + + if (pdu_type != NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE) + { + continue; + } + + for (int j = i + 1; j < num_pdus; j++) + { + uint8_t pdu_type2 = pdu_list[j].pdu_type; + if (pdu_type != pdu_type2) + { + continue; + } + + uint16_t rnti_i = pdu_list[i].ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti; + uint16_t rnti_j = pdu_list[j].ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti; + if (!is_ue_same(rnti_i, rnti_j)) + { + continue; + } + remove_ul_config_req_pdu(j, ul_config_req); + j--; + num_pdus--; + + LOG_E(MAC, "Problem, two cqis being sent to a single UE for rnti %x dropping one\n", + rnti_i); + } + } + int retval = nfapi_vnf_p7_ul_config_req(p7_config, ul_config_req); if (retval!=0) { diff --git a/nfapi/oai_integration/vendor_ext.h b/nfapi/oai_integration/vendor_ext.h index f25aa703cc..9a377dc27d 100644 --- a/nfapi/oai_integration/vendor_ext.h +++ b/nfapi/oai_integration/vendor_ext.h @@ -70,10 +70,11 @@ typedef enum { NFAPI_MODE_VNF, NFAPI_UE_STUB_PNF, NFAPI_UE_STUB_OFFNET, + NFAPI_MODE_STANDALONE_PNF, NFAPI_MODE_UNKNOWN } nfapi_mode_t; -char *nfapi_get_strmode(void); +const char *nfapi_get_strmode(void); void nfapi_logmode(void); nfapi_mode_t nfapi_getmode(void); void nfapi_setmode(nfapi_mode_t nfapi_mode); diff --git a/nfapi/open-nFAPI/common/public_inc/debug.h b/nfapi/open-nFAPI/common/public_inc/debug.h index 14f97a17f6..574b097301 100644 --- a/nfapi/open-nFAPI/common/public_inc/debug.h +++ b/nfapi/open-nFAPI/common/public_inc/debug.h @@ -14,38 +14,31 @@ * limitations under the License. */ +#pragma once -#ifndef _DEBUG_H_ -#define _DEBUG_H_ +#include +#include + +#define ERR strerror(errno) /*! The trace levels used by the nfapi libraries */ typedef enum nfapi_trace_level { - NFAPI_TRACE_ERROR = 1, - NFAPI_TRACE_WARN, - NFAPI_TRACE_NOTE, - NFAPI_TRACE_INFO, - - NFAPI_TRACE_LEVEL_MAX + NFAPI_TRACE_NONE, + NFAPI_TRACE_ERROR, + NFAPI_TRACE_WARN, + NFAPI_TRACE_NOTE, + NFAPI_TRACE_INFO, + NFAPI_TRACE_DEBUG, } nfapi_trace_level_t; -/*! The trace function pointer */ -typedef void (*nfapi_trace_fn_t)(nfapi_trace_level_t level, const char* format, ...); +void nfapi_trace(nfapi_trace_level_t, char const *caller, const char *format, ...) + __attribute__((format(printf, 3, 4))); -/*! Global trace function */ -extern nfapi_trace_fn_t nfapi_trace_g; +nfapi_trace_level_t nfapi_trace_level(void); -/*! Global trace level */ -extern nfapi_trace_level_t nfapi_trace_level_g; +#define NFAPI_TRACE(LEVEL, FORMAT, ...) do { \ + if (nfapi_trace_level() >= (LEVEL)) \ + nfapi_trace(LEVEL, __func__, FORMAT, ##__VA_ARGS__); \ +} while (0) -/*! NFAPI trace macro */ -//#define NFAPI_TRACE(level, format, ...) { if(nfapi_trace_g && ((nfapi_trace_level_t)level <= nfapi_trace_level_g)) (*nfapi_trace_g)(level, format, ##__VA_ARGS__); } -#define NFAPI_TRACE(level, format, ...) { if (nfapi_trace_g) (*nfapi_trace_g)(level, format, ##__VA_ARGS__); } - -/*! Function to change the trace level - * \param new_level The modified trace level - */ - -void nfapi_set_trace_level(nfapi_trace_level_t new_level); - -#endif /* _DEBUG_H_ */ diff --git a/nfapi/open-nFAPI/common/src/debug.c b/nfapi/open-nFAPI/common/src/debug.c index 5d4ad8a194..628e64d947 100644 --- a/nfapi/open-nFAPI/common/src/debug.c +++ b/nfapi/open-nFAPI/common/src/debug.c @@ -1,75 +1,87 @@ -/* - * Copyright 2017 Cisco Systems, Inc. - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define MAX_MSG_LENGTH 2096 -#define TRACE_HEADER_LENGTH 44 - -void nfapi_trace_dbg(nfapi_trace_level_t level, const char *format, ...); - -// initialize the trace function to 0 -void (*nfapi_trace_g)(nfapi_trace_level_t level, const char* format, ...) = &nfapi_trace_dbg; - -nfapi_trace_level_t nfapi_trace_level_g = NFAPI_TRACE_INFO; -//nfapi_trace_level_t nfapi_trace_level_g = NFAPI_TRACE_WARN; - -void nfapi_set_trace_level(nfapi_trace_level_t new_level) -{ - nfapi_trace_level_g = new_level; -} - -void nfapi_trace_dbg(nfapi_trace_level_t level, const char *format, ...) -{ - char trace_buff[MAX_MSG_LENGTH + TRACE_HEADER_LENGTH]; - uint32_t num_chars; - va_list p_args; - struct timeval tv; - pthread_t tid = pthread_self(); - - (void)gettimeofday(&tv, NULL); - - num_chars = (uint32_t)snprintf(trace_buff, TRACE_HEADER_LENGTH, "%04u.%06u: 0x%02x: %10u: ", ((uint32_t)tv.tv_sec) & 0x1FFF, (uint32_t)tv.tv_usec, (uint32_t)level, (uint32_t)tid); - - if (num_chars > TRACE_HEADER_LENGTH) - { - printf("trace_dbg: Error, num_chars is too large: %d", num_chars); - return; - } - - va_start(p_args, format); - if ((num_chars = (uint32_t)vsnprintf(&trace_buff[num_chars], MAX_MSG_LENGTH, format, p_args))) - { - if (level <= NFAPI_TRACE_WARN) - { - printf("%s", trace_buff); - } - printf("%s", trace_buff); - } - va_end(p_args); -} +/* + * Copyright 2017 Cisco Systems, Inc. + * + * 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. + */ + +#include "debug.h" +#include +#include +#include +#include +#include +#include + +static nfapi_trace_level_t trace_level = NFAPI_TRACE_WARN; + +static void nfapi_trace_init(void) +{ + static bool initialized; + if (initialized) + return; + initialized = true; + + const char *env = getenv("NFAPI_TRACE_LEVEL"); + if (!env) + return; + if (strcmp(env, "none") == 0) + trace_level = NFAPI_TRACE_NONE; + else if (strcmp(env, "error") == 0) + trace_level = NFAPI_TRACE_ERROR; + else if (strcmp(env, "warn") == 0) + trace_level = NFAPI_TRACE_WARN; + else if (strcmp(env, "note") == 0) + trace_level = NFAPI_TRACE_NOTE; + else if (strcmp(env, "info") == 0) + trace_level = NFAPI_TRACE_INFO; + else if (strcmp(env, "debug") == 0) + trace_level = NFAPI_TRACE_DEBUG; + else + { + nfapi_trace(NFAPI_TRACE_ERROR, __func__, "Invalid NFAPI_TRACE_LEVEL='%s'", env); + return; + } + nfapi_trace(trace_level, __func__, "NFAPI_TRACE_LEVEL='%s'", env); +} + +nfapi_trace_level_t nfapi_trace_level() +{ + nfapi_trace_init(); + return trace_level; +} + +void nfapi_trace(nfapi_trace_level_t level, + char const *caller, + char const *format, ...) +{ + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + printf("%ld%06ld [%c] %10u: %s: ", + ts.tv_sec, + ts.tv_nsec / 1000, + "XEWNID"[level], // NFAPI_TRACE_NONE, NFAPI_TRACE_ERROR, ... + (unsigned) pthread_self(), + caller); + + va_list ap; + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + + // Add a newline if the format string didn't have one + int len = strlen(format); + if (len == 0 || format[len - 1] != '\n') + putchar('\n'); + + fflush(stdout); +} diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index 0e923931ad..21cbaf93c1 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -118,11 +118,18 @@ typedef struct { short rsrp_dBm; } fapi_nr_ssb_pdu_t; +typedef struct { + uint32_t pdu_length; + uint8_t* pdu; + uint32_t sibs_mask; +} fapi_nr_sib_pdu_t; + typedef struct { uint8_t pdu_type; union { fapi_nr_pdsch_pdu_t pdsch_pdu; fapi_nr_ssb_pdu_t ssb_pdu; + fapi_nr_sib_pdu_t sib_pdu; }; } fapi_nr_rx_indication_body_t; @@ -403,8 +410,11 @@ typedef struct { uint8_t tb2_rv; uint8_t harq_process_nbr; vrb_to_prb_mapping_t vrb_to_prb_mapping; + uint8_t dai; double scaling_factor_S; int8_t accumulated_delta_PUCCH; + uint8_t pucch_resource_id; + uint8_t pdsch_to_harq_feedback_time_ind; uint8_t n_dmrs_cdm_groups; uint8_t dmrs_ports[10]; uint8_t n_front_load_symb; @@ -451,6 +461,437 @@ typedef struct { } fapi_nr_dl_config_request_t; +// +// P5 +// + + + +typedef struct { + fapi_nr_coreset_t coreset; + + uint8_t monitoring_slot_peridicity; + uint8_t monitoring_slot_offset; + uint16_t duration; + uint16_t monitoring_symbols_within_slot; + uint8_t number_of_candidates[5]; // aggregation level 1, 2, 4, 8, 16 + + uint8_t dci_2_0_number_of_candidates[5]; // aggregation level 1, 2, 4, 8, 16 + uint8_t dci_2_3_monitorying_periodicity; + uint8_t dci_2_3_number_of_candidates; + +} fapi_nr_search_space_t; + +typedef struct { + fapi_nr_search_space_t search_space_sib1; + fapi_nr_search_space_t search_space_others_sib; + fapi_nr_search_space_t search_space_paging; + //fapi_nr_coreset_t coreset_ra; // common coreset + fapi_nr_search_space_t search_space_ra; +} fapi_nr_pdcch_config_common_t; + +typedef struct { + uint8_t k0; + uint8_t mapping_type; + uint8_t symbol_starting; + uint8_t symbol_length; +} fapi_nr_pdsch_time_domain_resource_allocation_t; + +typedef struct { + fapi_nr_pdsch_time_domain_resource_allocation_t allocation_list[FAPI_NR_MAX_NUM_DL_ALLOCATIONS]; +} fapi_nr_pdsch_config_common_t; + +typedef struct { + uint8_t prach_configuration_index; + uint8_t msg1_fdm; + uint8_t msg1_frequency_start; + uint8_t zero_correlation_zone_config; + uint8_t preamble_received_target_power; + uint8_t preamble_transmission_max; + uint8_t power_ramping_step; + uint8_t ra_window_size; + + uint8_t total_number_of_preamble; + uint8_t ssb_occasion_per_rach; + uint8_t cb_preamble_per_ssb; + + uint8_t group_a_msg3_size; + uint8_t group_a_number_of_preamble; + uint8_t group_b_power_offset; + uint8_t contention_resolution_timer; + uint8_t rsrp_threshold_ssb; + uint8_t rsrp_threshold_ssb_sul; + uint8_t prach_length; // l839, l139 + uint8_t prach_root_sequence_index; // 0 - 837 for l839, 0 - 137 for l139 + uint8_t msg1_subcarrier_spacing; + uint8_t restrictedset_config; + uint8_t msg3_transform_precoding; +} fapi_nr_rach_config_common_t; + +typedef struct { + uint8_t k2; + uint8_t mapping_type; + uint8_t symbol_starting; + uint8_t symbol_length; +} fapi_nr_pusch_time_domain_resource_allocation_t; + +typedef struct { + uint8_t group_hopping_enabled_transform_precoding; + fapi_nr_pusch_time_domain_resource_allocation_t allocation_list[FAPI_NR_MAX_NUM_UL_ALLOCATIONS]; + uint8_t msg3_delta_preamble; + uint8_t p0_nominal_with_grant; +} fapi_nr_pusch_config_common_t; + +typedef struct { + uint8_t pucch_resource_common; + uint8_t pucch_group_hopping; + uint8_t hopping_id; + uint8_t p0_nominal; +} fapi_nr_pucch_config_common_t; + +typedef struct { + + fapi_nr_pdcch_config_common_t pdcch_config_common; + fapi_nr_pdsch_config_common_t pdsch_config_common; + +} fapi_nr_dl_bwp_common_config_t; + + + +typedef struct { + uint16_t int_rnti; + uint8_t time_frequency_set; + uint8_t dci_payload_size; + uint8_t serving_cell_id[FAPI_NR_MAX_NUM_SERVING_CELLS]; // interrupt configuration per serving cell + uint8_t position_in_dci[FAPI_NR_MAX_NUM_SERVING_CELLS]; // interrupt configuration per serving cell +} fapi_nr_downlink_preemption_t; + +typedef struct { + uint8_t tpc_index; + uint8_t tpc_index_sul; + uint8_t target_cell; +} fapi_nr_pusch_tpc_command_config_t; + +typedef struct { + uint8_t tpc_index_pcell; + uint8_t tpc_index_pucch_scell; +} fapi_nr_pucch_tpc_command_config_t; + +typedef struct { + uint8_t starting_bit_of_format_2_3; + uint8_t feild_type_format_2_3; +} fapi_nr_srs_tpc_command_config_t; + +typedef struct { + fapi_nr_downlink_preemption_t downlink_preemption; + fapi_nr_pusch_tpc_command_config_t tpc_pusch; + fapi_nr_pucch_tpc_command_config_t tpc_pucch; + fapi_nr_srs_tpc_command_config_t tpc_srs; +} fapi_nr_pdcch_config_dedicated_t; + +typedef struct { + uint8_t dmrs_type; + uint8_t dmrs_addition_position; + uint8_t max_length; + uint16_t scrambling_id0; + uint16_t scrambling_id1; + uint8_t ptrs_frequency_density[2]; // phase tracking rs + uint8_t ptrs_time_density[3]; // phase tracking rs + uint8_t ptrs_epre_ratio; // phase tracking rs + uint8_t ptrs_resource_element_offset; // phase tracking rs +} fapi_nr_dmrs_downlink_config_t; + +typedef struct { + uint8_t bwp_or_cell_level; + uint8_t pattern_type; + uint32_t resource_blocks[9]; // bitmaps type 275 bits + uint8_t slot_type; // bitmaps type one/two slot(s) + uint32_t symbols_in_resouece_block; // bitmaps type 14/28 bits + uint8_t periodic; // bitmaps type + uint32_t pattern[2]; // bitmaps type 2/4/5/8/10/20/40 bits + + fapi_nr_coreset_t coreset; // coreset + + uint8_t subcarrier_spacing; + uint8_t mode; +} fapi_nr_rate_matching_pattern_group_t; + +typedef struct { + // resource mapping + uint8_t row; // row1/row2/row4/other + uint16_t frequency_domain_allocation; // 4/12/3/6 bits + uint8_t number_of_ports; + uint8_t first_ofdm_symbol_in_time_domain; + uint8_t first_ofdm_symbol_in_time_domain2; + uint8_t cdm_type; + uint8_t density; // .5/1/3 + uint8_t density_dot5_type; // even/odd PRBs + + uint8_t frequency_band_starting_rb; // freqBand + uint8_t frequency_band_number_of_rb; // freqBand + + // periodicityAndOffset + uint8_t periodicity; // slot4/5/8/10/16/20/32/40/64/80/160/320/640 + uint32_t offset; // 0..639 bits +} fapi_nr_zp_csi_rs_resource_t; + +typedef struct { + uint16_t data_scrambling_id_pdsch; + fapi_nr_dmrs_downlink_config_t dmrs_dl_for_pdsch_mapping_type_a; + fapi_nr_dmrs_downlink_config_t dmrs_dl_for_pdsch_mapping_type_b; + uint8_t vrb_to_prb_interleaver; + uint8_t resource_allocation; + fapi_nr_pdsch_time_domain_resource_allocation_t allocation_list[FAPI_NR_MAX_NUM_DL_ALLOCATIONS]; + uint8_t pdsch_aggregation_factor; + fapi_nr_rate_matching_pattern_group_t rate_matching_pattern_group1; + fapi_nr_rate_matching_pattern_group_t rate_matching_pattern_group2; + uint8_t rbg_size; + uint8_t mcs_table; + uint8_t max_num_of_code_word_scheduled_by_dci; + uint8_t bundle_size; // prb_bundling static + uint8_t bundle_size_set1; // prb_bundling dynamic + uint8_t bundle_size_set2; // prb_bundling dynamic + fapi_nr_zp_csi_rs_resource_t periodically_zp_csi_rs_resource_set[FAPI_NR_MAX_NUM_ZP_CSI_RS_RESOURCE_PER_SET]; +} fapi_nr_pdsch_config_dedicated_t; + +typedef struct { + uint16_t starting_prb; + uint8_t intra_slot_frequency_hopping; + uint16_t second_hop_prb; + uint8_t format; // pucch format 0..4 + uint8_t initial_cyclic_shift; + uint8_t number_of_symbols; + uint8_t starting_symbol_index; + uint8_t time_domain_occ; + uint8_t number_of_prbs; + uint8_t occ_length; + uint8_t occ_index; +} fapi_nr_pucch_resource_t; + +typedef struct { + uint8_t periodicity; + uint8_t number_of_harq_process; + fapi_nr_pucch_resource_t n1_pucch_an; +} fapi_nr_sps_config_t; + +typedef struct { + uint8_t beam_failure_instance_max_count; + uint8_t beam_failure_detection_timer; +} fapi_nr_radio_link_monitoring_config_t; + +typedef struct { + fapi_nr_pdcch_config_dedicated_t pdcch_config_dedicated; + fapi_nr_pdsch_config_dedicated_t pdsch_config_dedicated; + fapi_nr_sps_config_t sps_config; + fapi_nr_radio_link_monitoring_config_t radio_link_monitoring_config; + +} fapi_nr_dl_bwp_dedicated_config_t; + +typedef struct { + fapi_nr_rach_config_common_t rach_config_common; + fapi_nr_pusch_config_common_t pusch_config_common; + fapi_nr_pucch_config_common_t pucch_config_common; + +} fapi_nr_ul_bwp_common_config_t; + +typedef struct { + uint8_t inter_slot_frequency_hopping; + uint8_t additional_dmrs; + uint8_t max_code_rate; + uint8_t number_of_slots; + uint8_t pi2bpsk; + uint8_t simultaneous_harq_ack_csi; +} fapi_nr_pucch_format_config_t; + +typedef struct { + fapi_nr_pucch_format_config_t format1; + fapi_nr_pucch_format_config_t format2; + fapi_nr_pucch_format_config_t format3; + fapi_nr_pucch_format_config_t format4; + fapi_nr_pucch_resource_t multi_csi_pucch_resources[2]; + uint8_t dl_data_to_ul_ack[8]; + // pucch power control + uint8_t deltaF_pucch_f0; + uint8_t deltaF_pucch_f1; + uint8_t deltaF_pucch_f2; + uint8_t deltaF_pucch_f3; + uint8_t deltaF_pucch_f4; + uint8_t two_pucch_pc_adjusment_states; +} fapi_nr_pucch_config_dedicated_t; + +typedef struct { + uint8_t dmrs_type; + uint8_t dmrs_addition_position; + uint8_t ptrs_uplink_config; // to indicate if PTRS Uplink is configured of not + uint8_t ptrs_type; //cp-OFDM, dft-S-OFDM + uint16_t ptrs_frequency_density[2]; + uint8_t ptrs_time_density[3]; + uint8_t ptrs_max_number_of_ports; + uint8_t ptrs_resource_element_offset; + uint8_t ptrs_power; + uint16_t ptrs_sample_density[5]; + uint8_t ptrs_time_density_transform_precoding; + + uint8_t max_length; + uint16_t scrambling_id0; + uint16_t scrambling_id1; + uint8_t npusch_identity; + uint8_t disable_sequence_group_hopping; + uint8_t sequence_hopping_enable; +} fapi_nr_dmrs_uplink_config_t; + +typedef struct { + uint8_t tpc_accmulation; + uint8_t msg3_alpha; + uint8_t p0_nominal_with_grant; + uint8_t two_pusch_pc_adjustments_states; + uint8_t delta_mcs; +} fapi_nr_pusch_power_control_t; + +typedef enum {tx_config_codebook = 1, tx_config_nonCodebook = 2} tx_config_t; +typedef enum {transform_precoder_enabled = 0, transform_precoder_disabled = 1} transform_precoder_t; +typedef enum { + codebook_subset_fullyAndPartialAndNonCoherent = 1, + codebook_subset_partialAndNonCoherent = 2, + codebook_subset_nonCoherent = 3} codebook_subset_t; +typedef struct { + uint16_t data_scrambling_identity; + tx_config_t tx_config; + fapi_nr_dmrs_uplink_config_t dmrs_ul_for_pusch_mapping_type_a; + fapi_nr_dmrs_uplink_config_t dmrs_ul_for_pusch_mapping_type_b; + fapi_nr_pusch_power_control_t pusch_power_control; + uint8_t frequency_hopping; + uint16_t frequency_hopping_offset_lists[4]; + uint8_t resource_allocation; + fapi_nr_pusch_time_domain_resource_allocation_t allocation_list[FAPI_NR_MAX_NUM_UL_ALLOCATIONS]; + uint8_t pusch_aggregation_factor; + uint8_t mcs_table; + uint8_t mcs_table_transform_precoder; + transform_precoder_t transform_precoder; + codebook_subset_t codebook_subset; + uint8_t max_rank; + uint8_t rbg_size; + + //uci-OnPUSCH + uint8_t uci_on_pusch_type; //dynamic, semi-static + uint8_t beta_offset_ack_index1[4]; + uint8_t beta_offset_ack_index2[4]; + uint8_t beta_offset_ack_index3[4]; + uint8_t beta_offset_csi_part1_index1[4]; + uint8_t beta_offset_csi_part1_index2[4]; + uint8_t beta_offset_csi_part2_index1[4]; + uint8_t beta_offset_csi_part2_index2[4]; + + uint8_t tp_pi2BPSK; +} fapi_nr_pusch_config_dedicated_t; + +typedef struct { + uint8_t frequency_hopping; + fapi_nr_dmrs_uplink_config_t cg_dmrs_configuration; + uint8_t mcs_table; + uint8_t mcs_table_transform_precoder; + + //uci-OnPUSCH + uint8_t uci_on_pusch_type; //dynamic, semi-static + uint8_t beta_offset_ack_index1[4]; + uint8_t beta_offset_ack_index2[4]; + uint8_t beta_offset_ack_index3[4]; + uint8_t beta_offset_csi_part1_index1[4]; + uint8_t beta_offset_csi_part1_index2[4]; + uint8_t beta_offset_csi_part2_index1[4]; + uint8_t beta_offset_csi_part2_index2[4]; + + uint8_t resource_allocation; + // rgb-Size structure missing in spec. + uint8_t power_control_loop_to_use; + // p0-PUSCH-Alpha + uint8_t p0; + uint8_t alpha; + + uint8_t transform_precoder; + uint8_t number_of_harq_process; + uint8_t rep_k; + uint8_t rep_k_rv; + uint8_t periodicity; + uint8_t configured_grant_timer; + // rrc-ConfiguredUplinkGrant + uint16_t time_domain_offset; + uint8_t time_domain_allocation; + uint32_t frequency_domain_allocation; + uint8_t antenna_ports; + uint8_t dmrs_seq_initialization; + uint8_t precoding_and_number_of_layers; + uint8_t srs_resource_indicator; + uint8_t mcs_and_tbs; + uint8_t frequency_hopping_offset; + uint8_t path_loss_reference_index; + +} fapi_nr_configured_grant_config_t; + +typedef struct { + uint8_t qcl_type1_serving_cell_index; + uint8_t qcl_type1_bwp_id; + uint8_t qcl_type1_rs_type; // csi-rs or ssb + uint8_t qcl_type1_nzp_csi_rs_resource_id; + uint8_t qcl_type1_ssb_index; + uint8_t qcl_type1_type; + + uint8_t qcl_type2_serving_cell_index; + uint8_t qcl_type2_bwp_id; + uint8_t qcl_type2_rs_type; // csi-rs or ssb + uint8_t qcl_type2_nzp_csi_rs_resource_id; + uint8_t qcl_type2_ssb_index; + uint8_t qcl_type2_type; + +} fapi_nr_tci_state_t; + +typedef struct { + uint8_t root_sequence_index; + // rach genertic + uint8_t prach_configuration_index; + uint8_t msg1_fdm; + uint8_t msg1_frequency_start; + uint8_t zero_correlation_zone_config; + uint8_t preamble_received_target_power; + uint8_t preamble_transmission_max; + uint8_t power_ramping_step; + uint8_t ra_window_size; + + uint8_t rsrp_threshold_ssb; + // PRACH-ResourceDedicatedBFR + uint8_t bfr_ssb_index[FAPI_NR_MAX_NUM_CANDIDATE_BEAMS]; + uint8_t bfr_ssb_ra_preamble_index[FAPI_NR_MAX_NUM_CANDIDATE_BEAMS]; + // NZP-CSI-RS-Resource + uint8_t bfr_csi_rs_nzp_resource_mapping[FAPI_NR_MAX_NUM_CANDIDATE_BEAMS]; + uint8_t bfr_csi_rs_power_control_offset[FAPI_NR_MAX_NUM_CANDIDATE_BEAMS]; + uint8_t bfr_csi_rs_power_control_offset_ss[FAPI_NR_MAX_NUM_CANDIDATE_BEAMS]; + uint16_t bfr_csi_rs_scrambling_id[FAPI_NR_MAX_NUM_CANDIDATE_BEAMS]; + uint8_t bfr_csi_rs_resource_periodicity[FAPI_NR_MAX_NUM_CANDIDATE_BEAMS]; + uint16_t bfr_csi_rs_resource_offset[FAPI_NR_MAX_NUM_CANDIDATE_BEAMS]; + fapi_nr_tci_state_t qcl_infomation_periodic_csi_rs[FAPI_NR_MAX_NUM_CANDIDATE_BEAMS]; + + uint8_t bfr_csirs_ra_occasions[FAPI_NR_MAX_NUM_CANDIDATE_BEAMS]; + uint8_t bfr_csirs_ra_preamble_index[FAPI_NR_MAX_NUM_CANDIDATE_BEAMS][FAPI_NR_MAX_RA_OCCASION_PER_CSIRS]; + + uint8_t ssb_per_rach_occasion; + uint8_t ra_ssb_occasion_mask_index; + fapi_nr_search_space_t recovery_search_space; + // RA-Prioritization + uint8_t power_ramping_step_high_priority; + uint8_t scaling_factor_bi; + uint8_t beam_failure_recovery_timer; +} fapi_nr_beam_failure_recovery_config_t; + +typedef struct { + fapi_nr_pucch_config_dedicated_t pucch_config_dedicated; + fapi_nr_pusch_config_dedicated_t pusch_config_dedicated; + fapi_nr_configured_grant_config_t configured_grant_config; + // SRS-Config + uint8_t srs_tpc_accumulation; + fapi_nr_beam_failure_recovery_config_t beam_failure_recovery_config; + +} fapi_nr_ul_bwp_dedicated_config_t; + #define FAPI_NR_CONFIG_REQUEST_MASK_PBCH 0x01 #define FAPI_NR_CONFIG_REQUEST_MASK_DL_BWP_COMMON 0x02 #define FAPI_NR_CONFIG_REQUEST_MASK_UL_BWP_COMMON 0x04 diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h index ea459138e1..e1cfc26336 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h @@ -27,6 +27,8 @@ #define NFAPI_PNF_PARAM_GENERAL_OUI_LENGTH 3 #define NFAPI_MAX_NUM_RF_BANDS 16 +#define NFAPI_MAX_PACKED_MESSAGE_SIZE 8192 + // The following definition control the size of arrays used in the interface. // These may be changed if desired. They are used in the encoder to make sure // that the user has not specified a 'count' larger than the max array, and also @@ -122,12 +124,13 @@ typedef struct { // Convenience methods to convert between SFN/SLOT formats #define NFAPI_SFNSLOT2DEC(_sfn,_slot) ( _sfn*20 + _slot ) // total count of slots -#define NFAPI_SFNSLOTDEC2SFNSLOT(_sfnslot_dec) ((((_sfnslot_dec) / 20) << 4) | (((_sfnslot_dec) - (((_sfnslot_dec) / 20) * 10)) & 0x3F)) +#define NFAPI_SFNSLOTDEC2SFNSLOT(_sfnslot_dec) ((((_sfnslot_dec) / 20) << 6) | (((_sfnslot_dec) - (((_sfnslot_dec) / 20) * 20)) & 0x3F)) #define NFAPI_SFNSLOT2SFN(_sfnslot) ((_sfnslot) >> 6) #define NFAPI_SFNSLOT2SLOT(_sfnslot) ((_sfnslot) & 0x3F) #define NFAPI_SFNSLOTDEC2SFN(_sfnslot_dec) ((_sfnslot_dec) / 20) #define NFAPI_SFNSLOTDEC2SLOT(_sfnslot_dec) ((_sfnslot_dec) % 20) +#define NFAPI_SFNSLOT2HEX(_sfn,_slot) ((_sfn << 6) | (_slot & 0x3F)) #define NFAPI_MAX_SFNSLOTDEC 1024*20 // 20 is for numerology 1 @@ -706,7 +709,6 @@ typedef struct { #define NFAPI_PHICH_CONFIG_PHICH_DURATION_TAG 0x0015 #define NFAPI_PHICH_CONFIG_PHICH_POWER_OFFSET_TAG 0x0016 - typedef struct { nfapi_uint16_tlv_t primary_synchronization_signal_epre_eprers; nfapi_uint16_tlv_t secondary_synchronization_signal_epre_eprers; @@ -2497,7 +2499,7 @@ typedef struct { typedef struct { nfapi_p7_message_header_t header; uint32_t t1; - int32_t delta_sfn_sf; + int32_t delta_sfn_sf; nfapi_vendor_extension_tlv_t vendor_extension; } nfapi_dl_node_sync_t; @@ -2872,11 +2874,12 @@ typedef struct { } nfapi_rx_indication_rel9_t; #define NFAPI_RX_INDICATION_REL9_TAG 0x2025 +#define NFAPI_RX_IND_DATA_MAX 8192 typedef struct { nfapi_rx_ue_information rx_ue_information; nfapi_rx_indication_rel8_t rx_indication_rel8; nfapi_rx_indication_rel9_t rx_indication_rel9; - uint8_t* data; + uint8_t rx_ind_data[NFAPI_RX_IND_DATA_MAX]; } nfapi_rx_indication_pdu_t; #define NFAPI_RX_IND_MAX_PDU 100 diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h index 9d245446c8..c124ad9fb9 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h @@ -984,6 +984,8 @@ typedef struct { /// A value indicating how the BCH payload is generated. This should match the PARAM/CONFIG TLVs. Value: 0: MAC generates the full PBCH payload, see Table 3-41, where bchPayload has 31 bits 1: PHY generates the timing PBCH bits, see Table 3-41, where the bchPayload has 24 bits 2: PHY generates the full PBCH payload uint8_t bchPayloadFlag; uint32_t bchPayload; + /// A value indicating the channel quality between the gNB and nrUE. Value: 0->255 dBM + uint8_t ssbRsrp; nfapi_nr_tx_precoding_and_beamforming_t precoding_and_beamforming; } nfapi_nr_dl_tti_ssb_pdu_rel15_t; @@ -1476,7 +1478,7 @@ typedef enum { //section 3.4.7 rx_data_indication //table 3-61 - +#define NFAPI_NR_RX_DATA_IND_MAX_PDU 100 typedef struct { uint32_t handle; @@ -1497,12 +1499,13 @@ typedef struct uint16_t sfn; uint16_t slot; uint16_t number_of_pdus; - nfapi_nr_rx_data_pdu_t *pdu_list; + nfapi_nr_rx_data_pdu_t *pdu_list; } nfapi_nr_rx_data_indication_t; //3.4.8 crc_indication //table 3-62 +#define NFAPI_NR_CRC_IND_MAX_PDU 100 typedef struct { uint32_t handle; @@ -1642,6 +1645,7 @@ typedef enum { NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE = 2, } nfapi_nr_uci_pdu_type_e; +#define NFAPI_NR_UCI_IND_MAX_PDU 100 typedef struct { uint16_t pdu_type; // 0 for PDU on PUSCH, 1 for PUCCH format 0 or 1, 2 for PUCCH format 2 to 4 @@ -1678,7 +1682,7 @@ typedef struct nfapi_nr_srs_indication_reported_symbol_resource_block_t* rb_list; }nfapi_nr_srs_indication_reported_symbol_t; - +#define NFAPI_NR_SRS_IND_MAX_PDU 100 typedef struct { uint32_t handle; diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi.c b/nfapi/open-nFAPI/nfapi/src/nfapi.c index 63dd8a16ae..2783781e2c 100644 --- a/nfapi/open-nFAPI/nfapi/src/nfapi.c +++ b/nfapi/open-nFAPI/nfapi/src/nfapi.c @@ -1,783 +1,783 @@ -/* - * Copyright (c) 2001-2016, Cisco Systems, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * Neither the name of the Cisco Systems, Inc. nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - - -// Fundamental routines - -uint8_t push8(uint8_t in, uint8_t **out, uint8_t *end) { - uint8_t *pOut = *out; - - if((end - pOut) >= 1) { - pOut[0] = in; - (*out)+=1; - return 1; - } else { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); - return 0; - } -} - -uint8_t pushs8(int8_t in, uint8_t **out, uint8_t *end) { - uint8_t *pOut = *out; - - if((end - pOut) >= 1) { - pOut[0] = in; - (*out)+=1; - return 1; - } else { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); - return 0; - } -} - -uint8_t push16(uint16_t in, uint8_t **out, uint8_t *end) { - uint8_t *pOut = *out; - - if((end - pOut) >= 2) { - pOut[0] = (in & 0xFF00) >> 8; - pOut[1] = (in & 0xFF); - (*out)+=2; - return 2; - } else { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); - return 0; - } -} - -uint8_t pushs16(int16_t in, uint8_t **out, uint8_t *end) { - uint8_t *pOut = *out; - - if((end - pOut) >= 2) { - pOut[0] = (in & 0xFF00) >> 8; - pOut[1] = (in & 0xFF); - (*out)+=2; - return 2; - } else { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); - return 0; - } -} - -uint8_t push32(uint32_t in, uint8_t **out, uint8_t *end) { - uint8_t *pOut = *out; - - if((end - pOut) >= 4) { - pOut[0] = (in & 0xFF000000) >> 24; - pOut[1] = (in & 0xFF0000) >> 16; - pOut[2] = (in & 0xFF00) >> 8; - pOut[3] = (in & 0xFF); - (*out)+=4; - return 4; - } else { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); - return 0; - } -} - -uint8_t pushs32(int32_t in, uint8_t **out, uint8_t *end) { - uint8_t *pOut = *out; - - if((end - pOut) >= 4) { - pOut[0] = (in & 0xFF000000) >> 24; - pOut[1] = (in & 0xFF0000) >> 16; - pOut[2] = (in & 0xFF00) >> 8; - pOut[3] = (in & 0xFF); - (*out)+=4; - return 4; - } else { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); - return 0; - } -} - -uint8_t pull8(uint8_t **in, uint8_t *out, uint8_t *end) { - uint8_t *pIn = *in; - - if((end - pIn) >= 1 ) { - *out = *pIn; - (*in)+=1; - return 1; - } else { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); - return 0; - } -} - -uint8_t pulls8(uint8_t **in, int8_t *out, uint8_t *end) { - uint8_t *pIn = *in; - - if((end - pIn) >= 1 ) { - *out = *pIn; - (*in)+=1; - return 1; - } else { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); - return 0; - } -} - -uint8_t pull16(uint8_t **in, uint16_t *out, uint8_t *end) { - uint8_t *pIn = *in; - - if((end - pIn) >=2 ) { - *out = ((pIn[0]) << 8) | pIn[1]; - (*in)+=2; - return 2; - } else { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); - return 0; - } -} - -uint8_t pulls16(uint8_t **in, int16_t *out, uint8_t *end) { - uint8_t *pIn = *in; - - if((end - pIn) >=2 ) { - *out = ((pIn[0]) << 8) | pIn[1]; - (*in)+=2; - return 2; - } else { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); - return 0; - } -} - -uint8_t pull32(uint8_t **in, uint32_t *out, uint8_t *end) { - uint8_t *pIn = *in; - - if((end - pIn) >=4 ) { - *out = (pIn[0] << 24) | (pIn[1] << 16) | (pIn[2] << 8) | pIn[3]; - (*in)+=4; - return 4; - } else { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); - return 0; - } -} - -uint8_t pulls32(uint8_t **in, int32_t *out, uint8_t *end) { - uint8_t *pIn = *in; - - if((end - pIn) >=4 ) { - *out = (pIn[0] << 24) | (pIn[1] << 16) | (pIn[2] << 8) | pIn[3]; - (*in)+=4; - return 4; - } else { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); - return 0; - } -} - -/* -inline void pusharray16(uint8_t **, uint16_t, uint32_t len) -{ -} -*/ - -uint32_t pullarray16(uint8_t **in, uint16_t out[], uint32_t max_len, uint32_t len, uint8_t *end) { - if(len == 0) - return 1; - - if(len > max_len) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len); - return 0; - } - - if((end - (*in)) >= sizeof(uint16_t) * len) { - uint32_t idx; - - for(idx = 0; idx < len; ++idx) { - if(!pull16(in, &out[idx], end)) - return 0; - } - - return sizeof(uint16_t) * len; - } else { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); - return 0; - } -} - -uint32_t pullarrays16(uint8_t **in, int16_t out[], uint32_t max_len, uint32_t len, uint8_t *end) { - if(len == 0) - return 1; - - if(len > max_len) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len); - return 0; - } - - if((end - (*in)) >= sizeof(uint16_t) * len) { - uint32_t idx; - - for(idx = 0; idx < len; ++idx) { - if(!pulls16(in, &out[idx], end)) - return 0; - } - - return sizeof(uint16_t) * len; - } else { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); - return 0; - } -} -uint32_t pusharray16(uint16_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end) { - if(len == 0) - return 1; - - if(len > max_len) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len); - return 0; - } - - if((end - (*out)) >= sizeof(uint16_t) * len) { - uint32_t idx; - - for(idx = 0; idx < len; ++idx) { - if(!push16(in[idx], out, end)) - return 0; - } - - return sizeof(uint16_t) * len; - } else { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); - return 0; - } -} -uint32_t pusharrays16(int16_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end) { - if(len == 0) - return 1; - - if(len > max_len) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len); - return 0; - } - - if((end - (*out)) >= sizeof(uint16_t) * len) { - uint32_t idx; - - for(idx = 0; idx < len; ++idx) { - pushs16(in[idx], out, end); - } - - return sizeof(uint16_t) * len; - } else { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); - return 0; - } -} -uint32_t pullarray32(uint8_t **in, uint32_t out[], uint32_t max_len, uint32_t len, uint8_t *end) { - if(len == 0) - return 1; - - if(len > max_len) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len); - return 0; - } - - if((end - (*in)) >= sizeof(uint32_t) * len) { - uint32_t idx; - - for(idx = 0; idx < len; ++idx) { - if(!pull32(in, &out[idx], end)) - return 0; - } - - return sizeof(uint32_t) * len; - } else { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); - return 0; - } -} - -uint32_t pullarrays32(uint8_t **in, int32_t out[], uint32_t max_len, uint32_t len, uint8_t *end) { - if(len == 0) - return 1; - - if(len > max_len) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len); - return 0; - } - - if((end - (*in)) >= sizeof(uint32_t) * len) { - uint32_t idx; - - for(idx = 0; idx < len; ++idx) { - if(!pulls32(in, &out[idx], end)) - return 0; - } - - return sizeof(uint32_t) * len; - } else { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); - return 0; - } -} -uint32_t pusharray32(uint32_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end) { - if(len == 0) - return 1; - - if(len > max_len) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len); - return 0; - } - - if((end - (*out)) >= sizeof(uint32_t) * len) { - uint32_t idx; - - for(idx = 0; idx < len; ++idx) { - if(!push32(in[idx], out, end)) - return 0; - } - - return sizeof(uint32_t) * len; - } else { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); - return 0; - } -} -uint32_t pusharrays32(int32_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end) { - if(len == 0) - return 1; - - if(len > max_len) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len); - return 0; - } - - if((end - (*out)) >= sizeof(uint32_t) * len) { - uint32_t idx; - - for(idx = 0; idx < len; ++idx) { - pushs32(in[idx], out, end); - } - - return sizeof(uint32_t) * len; - } else { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); - return 0; - } -} -uint32_t pullarray8(uint8_t **in, uint8_t out[], uint32_t max_len, uint32_t len, uint8_t *end) { - if(len == 0) - return 1; - - if(len > max_len) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len); - return 0; - } - - if((end - (*in)) >= sizeof(uint8_t) * len) { - memcpy(out, (*in), len); - (*in)+=len; - return sizeof(uint8_t) * len; - } else { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); - return 0; - } -} - -uint32_t pusharray8(uint8_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end) { - if(len == 0) - return 1; - - if(len > max_len) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len); - return 0; - } - - if((end - (*out)) >= sizeof(uint8_t) * len) { - memcpy((*out), in, len); - (*out)+=len; - return sizeof(uint8_t) * len; - } else { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); - return 0; - } -} - -uint8_t packarray(void *array, uint16_t array_element_size, uint16_t max_count, uint16_t count, uint8_t **ppwritepackedmsg, uint8_t *end, pack_array_elem_fn fn) { - if(count > max_count) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, count, max_count); - return 0; - } - - uint16_t i = 0; - - for(i = 0; i < count; ++i) { - if((fn)(array, ppwritepackedmsg, end) == 0) - return 0; - - array += array_element_size; - } - - return 1; -} - -uint8_t unpackarray(uint8_t **ppReadPackedMsg, void *array, uint16_t array_element_size, uint16_t max_count, uint16_t count, uint8_t *end, unpack_array_elem_fn fn) { - if(count > max_count) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, count, max_count); - return 0; - } - - uint16_t i = 0; - - for(i = 0; i < count; ++i) { - if((fn)(array, ppReadPackedMsg, end) == 0) - return 0; - - array += array_element_size; - } - - return 1; -} - - -uint32_t pack_vendor_extension_tlv(nfapi_tl_t *ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) { - if(ve != 0 && config != 0) { - if(config->pack_vendor_extension_tlv) { - uint8_t *pStartOfTlv = *ppWritePackedMsg; - - if(pack_tl(ve, ppWritePackedMsg, end) == 0) - return 0; - - uint8_t *pStartOfValue = *ppWritePackedMsg; - - if((config->pack_vendor_extension_tlv)(ve, ppWritePackedMsg, end, config) == 0) - return 0; - - ve->length = (*ppWritePackedMsg) - pStartOfValue; - pack_tl(ve, &pStartOfTlv, end); - return 1; - } - } - - return 1; -} - -uint32_t unpack_vendor_extension_tlv(nfapi_tl_t *tl, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config, nfapi_tl_t **ve_tlv) { - if(ve_tlv != 0 && config != 0) { - if(config->unpack_vendor_extension_tlv) { - return (config->unpack_vendor_extension_tlv)(tl, ppReadPackedMsg, end, (void **)ve_tlv, config); - } - } - - return 1; -} - -uint32_t pack_p7_vendor_extension_tlv(nfapi_tl_t *ve, uint8_t **ppWritePackedMsg, uint8_t *end,nfapi_p7_codec_config_t *config) { - if(ve != 0 && config != 0) { - if(config->pack_vendor_extension_tlv) { - uint8_t *pStartOfTlv = *ppWritePackedMsg; - - if(pack_tl(ve, ppWritePackedMsg, end) == 0) - return 0; - - uint8_t *pStartOfValue = *ppWritePackedMsg; - - if((config->pack_vendor_extension_tlv)(ve, ppWritePackedMsg, end, config) == 0) - return 0; - - ve->length = (*ppWritePackedMsg) - pStartOfValue; - pack_tl(ve, &pStartOfTlv, end); - return 1; - } - } - - return 1; -} - -int unpack_p7_vendor_extension_tlv(nfapi_tl_t *tl, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config, nfapi_tl_t **ve_tlv) { - if(ve_tlv != 0 && config != 0) { - if(config->unpack_vendor_extension_tlv) { - return (config->unpack_vendor_extension_tlv)(tl, ppReadPackedMsg, end, (void **)ve_tlv, config); - } - } - - return 1; -} - - -uint8_t pack_tl(nfapi_tl_t *tl, uint8_t **ppWritePackedMsg, uint8_t *end) { - return (push16(tl->tag, ppWritePackedMsg, end) && - push16(tl->length, ppWritePackedMsg, end)); -} - -uint8_t unpack_tl(uint8_t **ppReadPackedMsg, nfapi_tl_t *tl, uint8_t *end) { - return (pull16(ppReadPackedMsg, &tl->tag, end) && - pull16(ppReadPackedMsg, &tl->length, end)); -} - -int unpack_tlv_list(unpack_tlv_t unpack_fns[], uint16_t size, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config, nfapi_tl_t **ve) { - nfapi_tl_t generic_tl; - uint8_t numBadTags = 0; - uint16_t idx = 0; - - while ((uint8_t *)(*ppReadPackedMsg) < end) { - // unpack the tl and process the values accordingly - if(unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0) - return 0; - - uint8_t tagMatch = 0; - uint8_t *pStartOfValue = *ppReadPackedMsg; - - for(idx = 0; idx < size; ++idx) { - if(unpack_fns[idx].tag == generic_tl.tag) { // match the extracted tag value with all the tags in unpack_fn list - tagMatch = 1; - nfapi_tl_t *tl = (nfapi_tl_t *)(unpack_fns[idx].tlv); - tl->tag = generic_tl.tag; - tl->length = generic_tl.length; - int result = (*unpack_fns[idx].unpack_func)(tl, ppReadPackedMsg, end); - - if(result == 0) { - return 0; - } - - // check if the length was right; - if(tl->length != (*ppReadPackedMsg - pStartOfValue)) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "Warning tlv tag 0x%x length %d not equal to unpack %d\n", tl->tag, tl->length, (*ppReadPackedMsg - pStartOfValue)); - } - } - } - - if(tagMatch == 0) { - if(generic_tl.tag >= NFAPI_VENDOR_EXTENSION_MIN_TAG_VALUE && - generic_tl.tag <= NFAPI_VENDOR_EXTENSION_MAX_TAG_VALUE) { - int result = unpack_vendor_extension_tlv(&generic_tl, ppReadPackedMsg, end, config, ve); - - if(result == 0) { - // got tot the end. - return 0; - } else if(result < 0) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown VE TAG value: 0x%04x\n", generic_tl.tag); - - if (++numBadTags > MAX_BAD_TAG) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "Supplied message has had too many bad tags\n"); - return 0; - } - - if((end - *ppReadPackedMsg) >= generic_tl.length) { - // Advance past the unknown TLV - (*ppReadPackedMsg) += generic_tl.length; - } else { - // go to the end - return 0; - } - } - } else { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown TAG value: 0x%04x\n", generic_tl.tag); - - if (++numBadTags > MAX_BAD_TAG) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "Supplied message has had too many bad tags\n"); - return 0; - } - - if((end - *ppReadPackedMsg) >= generic_tl.length) { - // Advance past the unknown TLV - (*ppReadPackedMsg) += generic_tl.length; - } else { - // go to the end - return 0; - } - } - } - } - - return 1; -} -int unpack_p7_tlv_list(unpack_p7_tlv_t unpack_fns[], uint16_t size, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config, nfapi_tl_t **ve) { - nfapi_tl_t generic_tl; - uint8_t numBadTags = 0; - uint16_t idx = 0; - - while ((uint8_t *)(*ppReadPackedMsg) < end) { - // unpack the tl and process the values accordingly - if(unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0) - return 0; - - uint8_t tagMatch = 0; - uint8_t *pStartOfValue = *ppReadPackedMsg; - - for(idx = 0; idx < size; ++idx) { - if(unpack_fns[idx].tag == generic_tl.tag) { - tagMatch = 1; - nfapi_tl_t *tl = (nfapi_tl_t *)(unpack_fns[idx].tlv); - tl->tag = generic_tl.tag; - tl->length = generic_tl.length; - int result = (*unpack_fns[idx].unpack_func)(tl, ppReadPackedMsg, end, config); - - if(result == 0) { - return 0; - } - - // check if the length was right; - if(tl->length != (*ppReadPackedMsg - pStartOfValue)) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "Warning tlv tag 0x%x length %d not equal to unpack %d\n", tl->tag, tl->length, (*ppReadPackedMsg - pStartOfValue)); - } - } - } - - if(tagMatch == 0) { - if(generic_tl.tag >= NFAPI_VENDOR_EXTENSION_MIN_TAG_VALUE && - generic_tl.tag <= NFAPI_VENDOR_EXTENSION_MAX_TAG_VALUE) { - int result = unpack_p7_vendor_extension_tlv(&generic_tl, ppReadPackedMsg, end, config, ve); - - if(result == 0) { - // got to end - return 0; - } else if(result < 0) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown TAG value: 0x%04x\n", generic_tl.tag); - - if (++numBadTags > MAX_BAD_TAG) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "Supplied message has had too many bad tags\n"); - return -1; - } - - if((end - *ppReadPackedMsg) >= generic_tl.length) { - // Advance past the unknown TLV - (*ppReadPackedMsg) += generic_tl.length; - } else { - // got ot the dn - return 0; - } - } - } else { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown TAG value: 0x%04x\n", generic_tl.tag); - - if (++numBadTags > MAX_BAD_TAG) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "Supplied message has had too many bad tags\n"); - return -1; - } - - if((end - *ppReadPackedMsg) >= generic_tl.length) { - // Advance past the unknown TLV - (*ppReadPackedMsg) += generic_tl.length; - } else { - // got ot the dn - return 0; - } - } - } - } - - return 1; -} - -// This intermediate function deals with calculating the length of the value -// and writing into the tlv header. -uint8_t pack_tlv(uint16_t tag, void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end, pack_tlv_fn fn) { - nfapi_tl_t *tl = (nfapi_tl_t *)tlv; - - // If the tag is defined - if(tl->tag == tag) { - uint8_t *pStartOfTlv = *ppWritePackedMsg; - - // write a dumy tlv header - if(pack_tl(tl, ppWritePackedMsg, end) == 0) - return 0; - - // Record the start of the value - uint8_t *pStartOfValue = *ppWritePackedMsg; - - // pack the tlv value - if(fn(tlv, ppWritePackedMsg, end) == 0) - return 0; - - // calculate the length of the value and rewrite the tl header - tl->length = (*ppWritePackedMsg) - pStartOfValue; - // rewrite the header with the correct length - pack_tl(tl, &pStartOfTlv, end); - } else { - if(tl->tag != 0) { - NFAPI_TRACE(NFAPI_TRACE_WARN, "Warning pack_tlv tag 0x%x does not match expected 0x%x\n", tl->tag, tag); - } else { - //NFAPI_TRACE(NFAPI_TRACE_ERROR, "Warning pack_tlv tag 0x%x ZERO does not match expected 0x%x\n", tl->tag, tag); - } - } - - return 1; -} - -const char *nfapi_error_code_to_str(nfapi_error_code_e value) { - switch(value) { - case NFAPI_MSG_OK: - return "NFAPI_MSG_OK"; - - case NFAPI_MSG_INVALID_STATE: - return "NFAPI_MSG_INVALID_STATE"; - - case NFAPI_MSG_INVALID_CONFIG: - return "NFAPI_MSG_INVALID_CONFIG"; - - case NFAPI_SFN_OUT_OF_SYNC: - return "NFAPI_SFN_OUT_OF_SYNC"; - - case NFAPI_MSG_SUBFRAME_ERR: - return "NFAPI_MSG_SUBFRAME_ERR"; - - case NFAPI_MSG_BCH_MISSING: - return "NFAPI_MSG_BCH_MISSING"; - - case NFAPI_MSG_INVALID_SFN: - return "NFAPI_MSG_INVALID_SFN"; - - case NFAPI_MSG_HI_ERR: - return "NFAPI_MSG_HI_ERR"; - - case NFAPI_MSG_TX_ERR: - return "NFAPI_MSG_TX_ERR"; - - default: - return "UNKNOWN"; - } -} +/* + * Copyright (c) 2001-2016, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +// Fundamental routines + +uint8_t push8(uint8_t in, uint8_t **out, uint8_t *end) { + uint8_t *pOut = *out; + + if((end - pOut) >= 1) { + pOut[0] = in; + (*out)+=1; + return 1; + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} + +uint8_t pushs8(int8_t in, uint8_t **out, uint8_t *end) { + uint8_t *pOut = *out; + + if((end - pOut) >= 1) { + pOut[0] = in; + (*out)+=1; + return 1; + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} + +uint8_t push16(uint16_t in, uint8_t **out, uint8_t *end) { + uint8_t *pOut = *out; + + if((end - pOut) >= 2) { + pOut[0] = (in & 0xFF00) >> 8; + pOut[1] = (in & 0xFF); + (*out)+=2; + return 2; + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} + +uint8_t pushs16(int16_t in, uint8_t **out, uint8_t *end) { + uint8_t *pOut = *out; + + if((end - pOut) >= 2) { + pOut[0] = (in & 0xFF00) >> 8; + pOut[1] = (in & 0xFF); + (*out)+=2; + return 2; + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} + +uint8_t push32(uint32_t in, uint8_t **out, uint8_t *end) { + uint8_t *pOut = *out; + + if((end - pOut) >= 4) { + pOut[0] = (in & 0xFF000000) >> 24; + pOut[1] = (in & 0xFF0000) >> 16; + pOut[2] = (in & 0xFF00) >> 8; + pOut[3] = (in & 0xFF); + (*out)+=4; + return 4; + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} + +uint8_t pushs32(int32_t in, uint8_t **out, uint8_t *end) { + uint8_t *pOut = *out; + + if((end - pOut) >= 4) { + pOut[0] = (in & 0xFF000000) >> 24; + pOut[1] = (in & 0xFF0000) >> 16; + pOut[2] = (in & 0xFF00) >> 8; + pOut[3] = (in & 0xFF); + (*out)+=4; + return 4; + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} + +uint8_t pull8(uint8_t **in, uint8_t *out, uint8_t *end) { + uint8_t *pIn = *in; + + if((end - pIn) >= 1 ) { + *out = *pIn; + (*in)+=1; + return 1; + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} + +uint8_t pulls8(uint8_t **in, int8_t *out, uint8_t *end) { + uint8_t *pIn = *in; + + if((end - pIn) >= 1 ) { + *out = *pIn; + (*in)+=1; + return 1; + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} + +uint8_t pull16(uint8_t **in, uint16_t *out, uint8_t *end) { + uint8_t *pIn = *in; + + if((end - pIn) >=2 ) { + *out = ((pIn[0]) << 8) | pIn[1]; + (*in)+=2; + return 2; + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} + +uint8_t pulls16(uint8_t **in, int16_t *out, uint8_t *end) { + uint8_t *pIn = *in; + + if((end - pIn) >=2 ) { + *out = ((pIn[0]) << 8) | pIn[1]; + (*in)+=2; + return 2; + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} + +uint8_t pull32(uint8_t **in, uint32_t *out, uint8_t *end) { + uint8_t *pIn = *in; + + if((end - pIn) >=4 ) { + *out = (pIn[0] << 24) | (pIn[1] << 16) | (pIn[2] << 8) | pIn[3]; + (*in)+=4; + return 4; + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} + +uint8_t pulls32(uint8_t **in, int32_t *out, uint8_t *end) { + uint8_t *pIn = *in; + + if((end - pIn) >=4 ) { + *out = (pIn[0] << 24) | (pIn[1] << 16) | (pIn[2] << 8) | pIn[3]; + (*in)+=4; + return 4; + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} + +/* +inline void pusharray16(uint8_t **, uint16_t, uint32_t len) +{ +} +*/ + +uint32_t pullarray16(uint8_t **in, uint16_t out[], uint32_t max_len, uint32_t len, uint8_t *end) { + if(len == 0) + return 1; + + if(len > max_len) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len); + return 0; + } + + if((end - (*in)) >= sizeof(uint16_t) * len) { + uint32_t idx; + + for(idx = 0; idx < len; ++idx) { + if(!pull16(in, &out[idx], end)) + return 0; + } + + return sizeof(uint16_t) * len; + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} + +uint32_t pullarrays16(uint8_t **in, int16_t out[], uint32_t max_len, uint32_t len, uint8_t *end) { + if(len == 0) + return 1; + + if(len > max_len) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len); + return 0; + } + + if((end - (*in)) >= sizeof(uint16_t) * len) { + uint32_t idx; + + for(idx = 0; idx < len; ++idx) { + if(!pulls16(in, &out[idx], end)) + return 0; + } + + return sizeof(uint16_t) * len; + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} +uint32_t pusharray16(uint16_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end) { + if(len == 0) + return 1; + + if(len > max_len) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len); + return 0; + } + + if((end - (*out)) >= sizeof(uint16_t) * len) { + uint32_t idx; + + for(idx = 0; idx < len; ++idx) { + if(!push16(in[idx], out, end)) + return 0; + } + + return sizeof(uint16_t) * len; + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} +uint32_t pusharrays16(int16_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end) { + if(len == 0) + return 1; + + if(len > max_len) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len); + return 0; + } + + if((end - (*out)) >= sizeof(uint16_t) * len) { + uint32_t idx; + + for(idx = 0; idx < len; ++idx) { + pushs16(in[idx], out, end); + } + + return sizeof(uint16_t) * len; + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} +uint32_t pullarray32(uint8_t **in, uint32_t out[], uint32_t max_len, uint32_t len, uint8_t *end) { + if(len == 0) + return 1; + + if(len > max_len) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len); + return 0; + } + + if((end - (*in)) >= sizeof(uint32_t) * len) { + uint32_t idx; + + for(idx = 0; idx < len; ++idx) { + if(!pull32(in, &out[idx], end)) + return 0; + } + + return sizeof(uint32_t) * len; + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} + +uint32_t pullarrays32(uint8_t **in, int32_t out[], uint32_t max_len, uint32_t len, uint8_t *end) { + if(len == 0) + return 1; + + if(len > max_len) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len); + return 0; + } + + if((end - (*in)) >= sizeof(uint32_t) * len) { + uint32_t idx; + + for(idx = 0; idx < len; ++idx) { + if(!pulls32(in, &out[idx], end)) + return 0; + } + + return sizeof(uint32_t) * len; + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} +uint32_t pusharray32(uint32_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end) { + if(len == 0) + return 1; + + if(len > max_len) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len); + return 0; + } + + if((end - (*out)) >= sizeof(uint32_t) * len) { + uint32_t idx; + + for(idx = 0; idx < len; ++idx) { + if(!push32(in[idx], out, end)) + return 0; + } + + return sizeof(uint32_t) * len; + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} +uint32_t pusharrays32(int32_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end) { + if(len == 0) + return 1; + + if(len > max_len) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len); + return 0; + } + + if((end - (*out)) >= sizeof(uint32_t) * len) { + uint32_t idx; + + for(idx = 0; idx < len; ++idx) { + pushs32(in[idx], out, end); + } + + return sizeof(uint32_t) * len; + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} +uint32_t pullarray8(uint8_t **in, uint8_t out[], uint32_t max_len, uint32_t len, uint8_t *end) { + if(len == 0) + return 1; + + if(len > max_len) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len); + return 0; + } + + if((end - (*in)) >= sizeof(uint8_t) * len) { + memcpy(out, (*in), len); + (*in)+=len; + return sizeof(uint8_t) * len; + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} + +uint32_t pusharray8(uint8_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end) { + if(len == 0) + return 1; + + if(len > max_len) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len); + return 0; + } + + if((end - (*out)) >= sizeof(uint8_t) * len) { + memcpy((*out), in, len); + (*out)+=len; + return sizeof(uint8_t) * len; + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + return 0; + } +} + +uint8_t packarray(void *array, uint16_t array_element_size, uint16_t max_count, uint16_t count, uint8_t **ppwritepackedmsg, uint8_t *end, pack_array_elem_fn fn) { + if(count > max_count) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, count, max_count); + return 0; + } + + uint16_t i = 0; + + for(i = 0; i < count; ++i) { + if((fn)(array, ppwritepackedmsg, end) == 0) + return 0; + + array += array_element_size; + } + + return 1; +} + +uint8_t unpackarray(uint8_t **ppReadPackedMsg, void *array, uint16_t array_element_size, uint16_t max_count, uint16_t count, uint8_t *end, unpack_array_elem_fn fn) { + if(count > max_count) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, count, max_count); + return 0; + } + + uint16_t i = 0; + + for(i = 0; i < count; ++i) { + if((fn)(array, ppReadPackedMsg, end) == 0) + return 0; + + array += array_element_size; + } + + return 1; +} + + +uint32_t pack_vendor_extension_tlv(nfapi_tl_t *ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) { + if(ve != 0 && config != 0) { + if(config->pack_vendor_extension_tlv) { + uint8_t *pStartOfTlv = *ppWritePackedMsg; + + if(pack_tl(ve, ppWritePackedMsg, end) == 0) + return 0; + + uint8_t *pStartOfValue = *ppWritePackedMsg; + + if((config->pack_vendor_extension_tlv)(ve, ppWritePackedMsg, end, config) == 0) + return 0; + + ve->length = (*ppWritePackedMsg) - pStartOfValue; + pack_tl(ve, &pStartOfTlv, end); + return 1; + } + } + + return 1; +} + +uint32_t unpack_vendor_extension_tlv(nfapi_tl_t *tl, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config, nfapi_tl_t **ve_tlv) { + if(ve_tlv != 0 && config != 0) { + if(config->unpack_vendor_extension_tlv) { + return (config->unpack_vendor_extension_tlv)(tl, ppReadPackedMsg, end, (void **)ve_tlv, config); + } + } + + return 1; +} + +uint32_t pack_p7_vendor_extension_tlv(nfapi_tl_t *ve, uint8_t **ppWritePackedMsg, uint8_t *end,nfapi_p7_codec_config_t *config) { + if(ve != 0 && config != 0) { + if(config->pack_vendor_extension_tlv) { + uint8_t *pStartOfTlv = *ppWritePackedMsg; + + if(pack_tl(ve, ppWritePackedMsg, end) == 0) + return 0; + + uint8_t *pStartOfValue = *ppWritePackedMsg; + + if((config->pack_vendor_extension_tlv)(ve, ppWritePackedMsg, end, config) == 0) + return 0; + + ve->length = (*ppWritePackedMsg) - pStartOfValue; + pack_tl(ve, &pStartOfTlv, end); + return 1; + } + } + + return 1; +} + +int unpack_p7_vendor_extension_tlv(nfapi_tl_t *tl, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config, nfapi_tl_t **ve_tlv) { + if(ve_tlv != 0 && config != 0) { + if(config->unpack_vendor_extension_tlv) { + return (config->unpack_vendor_extension_tlv)(tl, ppReadPackedMsg, end, (void **)ve_tlv, config); + } + } + + return 1; +} + + +uint8_t pack_tl(nfapi_tl_t *tl, uint8_t **ppWritePackedMsg, uint8_t *end) { + return (push16(tl->tag, ppWritePackedMsg, end) && + push16(tl->length, ppWritePackedMsg, end)); +} + +uint8_t unpack_tl(uint8_t **ppReadPackedMsg, nfapi_tl_t *tl, uint8_t *end) { + return (pull16(ppReadPackedMsg, &tl->tag, end) && + pull16(ppReadPackedMsg, &tl->length, end)); +} + +int unpack_tlv_list(unpack_tlv_t unpack_fns[], uint16_t size, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config, nfapi_tl_t **ve) { + nfapi_tl_t generic_tl; + uint8_t numBadTags = 0; + uint16_t idx = 0; + + while ((uint8_t *)(*ppReadPackedMsg) < end) { + // unpack the tl and process the values accordingly + if(unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0) + return 0; + + uint8_t tagMatch = 0; + uint8_t *pStartOfValue = *ppReadPackedMsg; + + for(idx = 0; idx < size; ++idx) { + if(unpack_fns[idx].tag == generic_tl.tag) { // match the extracted tag value with all the tags in unpack_fn list + tagMatch = 1; + nfapi_tl_t *tl = (nfapi_tl_t *)(unpack_fns[idx].tlv); + tl->tag = generic_tl.tag; + tl->length = generic_tl.length; + int result = (*unpack_fns[idx].unpack_func)(tl, ppReadPackedMsg, end); + + if(result == 0) { + return 0; + } + + // check if the length was right; + if(tl->length != (*ppReadPackedMsg - pStartOfValue)) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Warning tlv tag 0x%x length %d not equal to unpack %ld\n", tl->tag, tl->length, (*ppReadPackedMsg - pStartOfValue)); + } + } + } + + if(tagMatch == 0) { + if(generic_tl.tag >= NFAPI_VENDOR_EXTENSION_MIN_TAG_VALUE && + generic_tl.tag <= NFAPI_VENDOR_EXTENSION_MAX_TAG_VALUE) { + int result = unpack_vendor_extension_tlv(&generic_tl, ppReadPackedMsg, end, config, ve); + + if(result == 0) { + // got tot the end. + return 0; + } else if(result < 0) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown VE TAG value: 0x%04x\n", generic_tl.tag); + + if (++numBadTags > MAX_BAD_TAG) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Supplied message has had too many bad tags\n"); + return 0; + } + + if((end - *ppReadPackedMsg) >= generic_tl.length) { + // Advance past the unknown TLV + (*ppReadPackedMsg) += generic_tl.length; + } else { + // go to the end + return 0; + } + } + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown TAG value: 0x%04x\n", generic_tl.tag); + + if (++numBadTags > MAX_BAD_TAG) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Supplied message has had too many bad tags\n"); + return 0; + } + + if((end - *ppReadPackedMsg) >= generic_tl.length) { + // Advance past the unknown TLV + (*ppReadPackedMsg) += generic_tl.length; + } else { + // go to the end + return 0; + } + } + } + } + + return 1; +} +int unpack_p7_tlv_list(unpack_p7_tlv_t unpack_fns[], uint16_t size, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config, nfapi_tl_t **ve) { + nfapi_tl_t generic_tl; + uint8_t numBadTags = 0; + uint16_t idx = 0; + + while ((uint8_t *)(*ppReadPackedMsg) < end) { + // unpack the tl and process the values accordingly + if(unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0) + return 0; + + uint8_t tagMatch = 0; + uint8_t *pStartOfValue = *ppReadPackedMsg; + + for(idx = 0; idx < size; ++idx) { + if(unpack_fns[idx].tag == generic_tl.tag) { + tagMatch = 1; + nfapi_tl_t *tl = (nfapi_tl_t *)(unpack_fns[idx].tlv); + tl->tag = generic_tl.tag; + tl->length = generic_tl.length; + int result = (*unpack_fns[idx].unpack_func)(tl, ppReadPackedMsg, end, config); + + if(result == 0) { + return 0; + } + + // check if the length was right; + if(tl->length != (*ppReadPackedMsg - pStartOfValue)) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Warning tlv tag 0x%x length %d not equal to unpack %ld\n", tl->tag, tl->length, (*ppReadPackedMsg - pStartOfValue)); + } + } + } + + if(tagMatch == 0) { + if(generic_tl.tag >= NFAPI_VENDOR_EXTENSION_MIN_TAG_VALUE && + generic_tl.tag <= NFAPI_VENDOR_EXTENSION_MAX_TAG_VALUE) { + int result = unpack_p7_vendor_extension_tlv(&generic_tl, ppReadPackedMsg, end, config, ve); + + if(result == 0) { + // got to end + return 0; + } else if(result < 0) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown TAG value: 0x%04x\n", generic_tl.tag); + + if (++numBadTags > MAX_BAD_TAG) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Supplied message has had too many bad tags\n"); + return -1; + } + + if((end - *ppReadPackedMsg) >= generic_tl.length) { + // Advance past the unknown TLV + (*ppReadPackedMsg) += generic_tl.length; + } else { + // got ot the dn + return 0; + } + } + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown TAG value: 0x%04x\n", generic_tl.tag); + + if (++numBadTags > MAX_BAD_TAG) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Supplied message has had too many bad tags\n"); + return -1; + } + + if((end - *ppReadPackedMsg) >= generic_tl.length) { + // Advance past the unknown TLV + (*ppReadPackedMsg) += generic_tl.length; + } else { + // got ot the dn + return 0; + } + } + } + } + + return 1; +} + +// This intermediate function deals with calculating the length of the value +// and writing into the tlv header. +uint8_t pack_tlv(uint16_t tag, void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end, pack_tlv_fn fn) { + nfapi_tl_t *tl = (nfapi_tl_t *)tlv; + + // If the tag is defined + if(tl->tag == tag) { + uint8_t *pStartOfTlv = *ppWritePackedMsg; + + // write a dumy tlv header + if(pack_tl(tl, ppWritePackedMsg, end) == 0) + return 0; + + // Record the start of the value + uint8_t *pStartOfValue = *ppWritePackedMsg; + + // pack the tlv value + if(fn(tlv, ppWritePackedMsg, end) == 0) + return 0; + + // calculate the length of the value and rewrite the tl header + tl->length = (*ppWritePackedMsg) - pStartOfValue; + // rewrite the header with the correct length + pack_tl(tl, &pStartOfTlv, end); + } else { + if(tl->tag != 0) { + NFAPI_TRACE(NFAPI_TRACE_WARN, "Warning pack_tlv tag 0x%x does not match expected 0x%x\n", tl->tag, tag); + } else { + //NFAPI_TRACE(NFAPI_TRACE_ERROR, "Warning pack_tlv tag 0x%x ZERO does not match expected 0x%x\n", tl->tag, tag); + } + } + + return 1; +} + +const char *nfapi_error_code_to_str(nfapi_error_code_e value) { + switch(value) { + case NFAPI_MSG_OK: + return "NFAPI_MSG_OK"; + + case NFAPI_MSG_INVALID_STATE: + return "NFAPI_MSG_INVALID_STATE"; + + case NFAPI_MSG_INVALID_CONFIG: + return "NFAPI_MSG_INVALID_CONFIG"; + + case NFAPI_SFN_OUT_OF_SYNC: + return "NFAPI_SFN_OUT_OF_SYNC"; + + case NFAPI_MSG_SUBFRAME_ERR: + return "NFAPI_MSG_SUBFRAME_ERR"; + + case NFAPI_MSG_BCH_MISSING: + return "NFAPI_MSG_BCH_MISSING"; + + case NFAPI_MSG_INVALID_SFN: + return "NFAPI_MSG_INVALID_SFN"; + + case NFAPI_MSG_HI_ERR: + return "NFAPI_MSG_HI_ERR"; + + case NFAPI_MSG_TX_ERR: + return "NFAPI_MSG_TX_ERR"; + + default: + return "UNKNOWN"; + } +} diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p4.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p4.c index dbaa4347d3..6e79af6348 100644 --- a/nfapi/open-nFAPI/nfapi/src/nfapi_p4.c +++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p4.c @@ -29,7 +29,7 @@ static uint32_t get_packed_msg_len(uintptr_t msgHead, uintptr_t msgEnd) { if (msgEnd < msgHead) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "get_packed_msg_len: Error in pointers supplied %d, %d\n", msgHead, msgEnd); + NFAPI_TRACE(NFAPI_TRACE_ERROR, "get_packed_msg_len: Error in pointers supplied %lu, %lu\n", msgHead, msgEnd); return 0; } diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c index 3a6d807bdd..32b87f80e0 100644 --- a/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c +++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c @@ -429,16 +429,6 @@ static uint8_t pack_embms_mbsfn_config_value(void *tlv, uint8_t **ppWritePackedM pusharray8(value->fourframes_flag, 8,value->num_mbsfn_config,ppWritePackedMsg, end) && pusharrays32(value->mbsfn_subframeconfig, 8, value->num_mbsfn_config, ppWritePackedMsg, end)); } -// static uint8_t unpack_embms_mbsfn_config_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t* end) -// { -// nfapi_embms_mbsfn_config_t* value = (nfapi_embms_mbsfn_config_t*)tlv; - -// return ( pull16(ppReadPackedMsg, &value->num_mbsfn_config, end) && -// pull16(ppReadPackedMsg, &value->radioframe_allocation_period, end) && -// pull16(ppReadPackedMsg, &value->radioframe_allocation_offset, end) && -// pull8(ppReadPackedMsg, &value->fourframes_flag, end) && -// pullarrays32(ppReadPackedMsg, value->mbsfn_subframeconfig, 8, value->num_mbsfn_config, end)); -// } static uint8_t pack_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) { nfapi_param_response_t *pNfapiMsg = (nfapi_param_response_t *)msg; @@ -734,10 +724,10 @@ static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uin pack_tlv(NFAPI_NR_CONFIG_UL_K0_TAG, &(pNfapiMsg->carrier_config.ul_k0[1]), ppWritePackedMsg, end, &pack_uint16_tlv_value) && pack_tlv(NFAPI_NR_CONFIG_UPLINK_BANDWIDTH_TAG, &(pNfapiMsg->carrier_config.uplink_bandwidth), ppWritePackedMsg, end, &pack_uint16_tlv_value) && pack_tlv(NFAPI_NR_CONFIG_UPLINK_FREQUENCY_TAG, &(pNfapiMsg->carrier_config.uplink_frequency), ppWritePackedMsg, end, &pack_uint32_tlv_value) && - + pack_tlv(NFAPI_NR_CONFIG_FRAME_DUPLEX_TYPE_TAG, &(pNfapiMsg->cell_config.frame_duplex_type), ppWritePackedMsg, end, &pack_uint8_tlv_value) && pack_tlv(NFAPI_NR_CONFIG_PHY_CELL_ID_TAG, &(pNfapiMsg->cell_config.phy_cell_id), ppWritePackedMsg, end, &pack_uint8_tlv_value) && - + pack_tlv(NFAPI_NR_CONFIG_NUM_PRACH_FD_OCCASIONS_TAG, &(pNfapiMsg->prach_config.num_prach_fd_occasions), ppWritePackedMsg, end, &pack_uint8_tlv_value) && pack_tlv(NFAPI_NR_CONFIG_PRACH_SEQUENCE_LENGTH_TAG, &(pNfapiMsg->prach_config.prach_sequence_length), ppWritePackedMsg, end, &pack_uint8_tlv_value) && pack_tlv(NFAPI_NR_CONFIG_RESTRICTED_SET_CONFIG_TAG, &(pNfapiMsg->prach_config.restricted_set_config), ppWritePackedMsg, end, &pack_uint8_tlv_value) && @@ -1036,7 +1026,7 @@ static uint8_t pack_p5_message_body(nfapi_p4_p5_message_header_t *header, uint8_ static uint32_t get_packed_msg_len(uintptr_t msgHead, uintptr_t msgEnd) { if (msgEnd < msgHead) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "get_packed_msg_len: Error in pointers supplied %d, %d\n", msgHead, msgEnd); + NFAPI_TRACE(NFAPI_TRACE_ERROR, "get_packed_msg_len: Error in pointers supplied %lu, %lu\n", msgHead, msgEnd); return 0; } @@ -1351,7 +1341,6 @@ static uint8_t unpack_nr_pnf_config_request(uint8_t **ppReadPackedMsg, uint8_t * } - static uint8_t unpack_pnf_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) { nfapi_pnf_config_request_t *pNfapiMsg = (nfapi_pnf_config_request_t *)msg; unpack_tlv_t unpack_fns[] = { @@ -1723,6 +1712,7 @@ static uint8_t unpack_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, vo return ( pull8(ppReadPackedMsg, &pNfapiMsg->num_tlv, end) && unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); } + static uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config) { nfapi_nr_config_request_scf_t *pNfapiMsg = (nfapi_nr_config_request_scf_t*)msg; @@ -1786,7 +1776,7 @@ static uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, return ( pull8(ppReadPackedMsg, &pNfapiMsg->num_tlv, end) && unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension)); - + } static uint8_t unpack_config_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config) { @@ -2386,3 +2376,4 @@ int nfapi_p5_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn return result; } + diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c index 7cb74f8562..adc6d6e384 100644 --- a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c +++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c @@ -223,7 +223,6 @@ static uint8_t pack_dl_tti_csi_rs_pdu_rel15_value(void *tlv, uint8_t **ppWritePa static uint8_t pack_dl_tti_pdcch_pdu_rel15_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) { nfapi_nr_dl_tti_pdcch_pdu_rel15_t* value = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t*)tlv; - for(uint8_t i = 0; i < MAX_DCI_CORESET; ++i) { if(!(push16(value->dci_pdu[i].RNTI, ppWritePackedMsg, end) && @@ -236,7 +235,6 @@ static uint8_t pack_dl_tti_pdcch_pdu_rel15_value(void* tlv, uint8_t **ppWritePac push16(value->dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end) && pusharray8(value->dci_pdu[i].Payload, value->dci_pdu[i].PayloadSizeBits, value->dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end))) return 0; - } // TODO: resolve the packaging of array (currently sending a single element) return( @@ -300,17 +298,21 @@ static uint8_t pack_dl_tti_pdsch_pdu_rel15_value(void *tlv, uint8_t **ppWritePac static uint8_t pack_dl_tti_ssb_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) { - nfapi_nr_dl_tti_ssb_pdu_rel15_t *value = (nfapi_nr_dl_tti_ssb_pdu_rel15_t *)tlv; - return( - push16(value->PhysCellId, ppWritePackedMsg, end) && - push8(value->BetaPss, ppWritePackedMsg, end) && - push8(value->SsbBlockIndex, ppWritePackedMsg, end) && - push8(value->SsbSubcarrierOffset, ppWritePackedMsg, end) && - push16(value->ssbOffsetPointA, ppWritePackedMsg, end) && - push8(value->bchPayloadFlag, ppWritePackedMsg, end) && - push32(value->bchPayload, ppWritePackedMsg, end) - // TODO: pack precoding_and_beamforming too - ); + NFAPI_TRACE(NFAPI_TRACE_DEBUG, "Packing ssb. \n"); + nfapi_nr_dl_tti_ssb_pdu_rel15_t* value = (nfapi_nr_dl_tti_ssb_pdu_rel15_t*)tlv; + + return( + push16(value->PhysCellId, ppWritePackedMsg, end) && + push8(value->BetaPss, ppWritePackedMsg, end) && + push8(value->SsbBlockIndex, ppWritePackedMsg, end) && + push8(value->SsbSubcarrierOffset, ppWritePackedMsg, end) && + push16(value->ssbOffsetPointA, ppWritePackedMsg, end) && + push8(value->bchPayloadFlag, ppWritePackedMsg, end) && + push32(value->bchPayload, ppWritePackedMsg, end) && + push8(value->ssbRsrp, ppWritePackedMsg, end) + // TODO: pack precoding_and_beamforming too + ); + } @@ -778,38 +780,41 @@ static uint8_t pack_dl_config_request_body_value(void *tlv, uint8_t **ppWritePac } -static uint8_t pack_dl_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) { - nfapi_nr_dl_tti_request_t *pNfapiMsg = (nfapi_nr_dl_tti_request_t *)msg; +static uint8_t pack_dl_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config) +{ + nfapi_nr_dl_tti_request_t *pNfapiMsg = (nfapi_nr_dl_tti_request_t*)msg; - if (!(push16(pNfapiMsg->SFN, ppWritePackedMsg, end) && - push16(pNfapiMsg->Slot, ppWritePackedMsg, end) && - push8(pNfapiMsg->dl_tti_request_body.nGroup, ppWritePackedMsg, end) && - push8(pNfapiMsg->dl_tti_request_body.nPDUs, ppWritePackedMsg, end) && - pusharray8(pNfapiMsg->dl_tti_request_body.nUe,256,pNfapiMsg->dl_tti_request_body.nGroup, ppWritePackedMsg, end) - //pusharray8(pNfapiMsg->PduIdx[0] ,256,256, ppWritePackedMsg, end) - )) - return 0; + if (!(push16(pNfapiMsg->SFN , ppWritePackedMsg, end) && + push16(pNfapiMsg->Slot , ppWritePackedMsg, end) && + push8(pNfapiMsg->dl_tti_request_body.nGroup , ppWritePackedMsg, end) && + push8(pNfapiMsg->dl_tti_request_body.nPDUs , ppWritePackedMsg, end) && + pusharray8(pNfapiMsg->dl_tti_request_body.nUe, 256, pNfapiMsg->dl_tti_request_body.nGroup, ppWritePackedMsg, end) + //pusharray8(pNfapiMsg->PduIdx[0] ,256,256, ppWritePackedMsg, end) + )) + return 0; - int arr[12]; + int arr[12]; + for(int i=0;idl_tti_request_body.nGroup;i++) + { + for(int j=0;jdl_tti_request_body.nUe[i];j++) + { + arr[j] = pNfapiMsg->dl_tti_request_body.PduIdx[i][j]; + } + if(!(pusharrays32(arr, 12, pNfapiMsg->dl_tti_request_body.nUe[i], ppWritePackedMsg, end))) + return 0; + } - for(int i=0; idl_tti_request_body.nGroup; i++) { - for(int j=0; jdl_tti_request_body.nUe[i]; j++) { - arr[j] = pNfapiMsg->dl_tti_request_body.PduIdx[i][j]; - } + for(int i=0;idl_tti_request_body.nPDUs;i++) + { + if(!pack_dl_tti_request_body_value(&pNfapiMsg->dl_tti_request_body.dl_tti_pdu_list[i],ppWritePackedMsg,end)) + return 0; + } - if(!(pusharrays32(arr,12,pNfapiMsg->dl_tti_request_body.nUe[i],ppWritePackedMsg, end))) - return 0; - } - - for(int i=0; idl_tti_request_body.nPDUs; i++) { - if(!pack_dl_tti_request_body_value(&pNfapiMsg->dl_tti_request_body.dl_tti_pdu_list[i],ppWritePackedMsg,end)) - return 0; - } - - return 1; +return 1; } + static uint8_t pack_dl_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) { nfapi_dl_config_request_t *pNfapiMsg = (nfapi_dl_config_request_t *)msg; //return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) && @@ -902,6 +907,7 @@ static uint8_t pack_ul_tti_request_pucch_pdu(nfapi_nr_pucch_pdu_t *pucch_pdu, ui push8(pucch_pdu->cyclic_prefix, ppWritePackedMsg, end) && push8(pucch_pdu->format_type, ppWritePackedMsg, end) && push8(pucch_pdu->multi_slot_tx_indicator, ppWritePackedMsg, end) && + push8(pucch_pdu->pi_2bpsk, ppWritePackedMsg, end) && push16(pucch_pdu->prb_start, ppWritePackedMsg, end) && push16(pucch_pdu->prb_size, ppWritePackedMsg, end) && push8(pucch_pdu->start_symbol_index, ppWritePackedMsg, end) && @@ -1803,7 +1809,6 @@ static uint8_t pack_hi_dci0_request_body_value(void *tlv, uint8_t **ppWritePacke static uint8_t pack_ul_dci_pdu_list_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) { nfapi_nr_ul_dci_request_pdus_t* value = (nfapi_nr_ul_dci_request_pdus_t*)tlv; - for(uint8_t i = 0; i < MAX_DCI_CORESET; ++i) { if(!(push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].RNTI, ppWritePackedMsg, end) && @@ -1816,7 +1821,6 @@ static uint8_t pack_ul_dci_pdu_list_value(void* tlv, uint8_t **ppWritePackedMsg, push8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].powerControlOffsetSS, ppWritePackedMsg, end) && push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end) && - pusharray8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].Payload, value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].PayloadSizeBits, value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end))) return 0; @@ -2263,6 +2267,7 @@ static uint8_t pack_crc_indication_body_value(void *tlv, uint8_t **ppWritePacked uint16_t i = 0; uint16_t total_number_of_pdus = value->number_of_crcs; + assert(total_number_of_pdus <= NFAPI_CRC_IND_MAX_PDU); for(; i < total_number_of_pdus; ++i) { nfapi_crc_indication_pdu_t *pdu = &(value->crc_pdu_list[i]); uint8_t *instance_length_p = *ppWritePackedMsg; @@ -2304,7 +2309,7 @@ static uint8_t pack_rx_indication_rel9_value(void *tlv, uint8_t **ppWritePackedM static uint8_t pack_rx_ulsch_indication_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) { nfapi_rx_indication_body_t *value = (nfapi_rx_indication_body_t *)tlv; - //printf("RX ULSCH BODY\n"); + //NFAPI_TRACE(NFAPI_TRACE_DEBUG, "RX ULSCH BODY\n"); if( push16(value->number_of_pdus, ppWritePackedMsg, end) == 0) return 0; @@ -2313,28 +2318,30 @@ static uint8_t pack_rx_ulsch_indication_body_value(void *tlv, uint8_t **ppWriteP uint16_t i = 0; uint16_t offset = 2; // taking into account the number_of_pdus uint16_t total_number_of_pdus = value->number_of_pdus; - //printf("ULSCH:pdus:%d\n", total_number_of_pdus); + //NFAPI_TRACE(NFAPI_TRACE_DEBUG, "ULSCH:pdus:%d\n", total_number_of_pdus); + assert(total_number_of_pdus <= NFAPI_RX_IND_MAX_PDU); for(i = 0; i < total_number_of_pdus; ++i) { nfapi_rx_indication_pdu_t *pdu = &(value->rx_pdu_list[i]); if(pdu->rx_ue_information.tl.tag == NFAPI_RX_UE_INFORMATION_TAG) { - //printf("NFAPI_RX_UE_INFORMATION_TAG\n"); + //NFAPI_TRACE(NFAPI_TRACE_DEBUG, "NFAPI_RX_UE_INFORMATION_TAG\n"); offset += 4 + 6; } if(pdu->rx_indication_rel8.tl.tag == NFAPI_RX_INDICATION_REL8_TAG) { - //printf("NFAPI_RX_INDICATION_REL8_TAG\n"); + //NFAPI_TRACE(NFAPI_TRACE_DEBUG, "NFAPI_RX_INDICATION_REL8_TAG\n"); offset += 4 + 7; } if(pdu->rx_indication_rel9.tl.tag == NFAPI_RX_INDICATION_REL9_TAG) { - //printf("NFAPI_RX_INDICATION_REL9_TAG\n"); + //NFAPI_TRACE(NFAPI_TRACE_DEBUG, "NFAPI_RX_INDICATION_REL9_TAG\n"); offset += 4 + 2; } } // Now update the structure to include the offset + assert(total_number_of_pdus <= NFAPI_RX_IND_MAX_PDU); for(i =0; i < total_number_of_pdus; ++i) { nfapi_rx_indication_pdu_t *pdu = &(value->rx_pdu_list[i]); @@ -2347,6 +2354,7 @@ static uint8_t pack_rx_ulsch_indication_body_value(void *tlv, uint8_t **ppWriteP } // Write out the pdu + assert(total_number_of_pdus <= NFAPI_RX_IND_MAX_PDU); for(i = 0; i < total_number_of_pdus; ++i) { nfapi_rx_indication_pdu_t *pdu = &(value->rx_pdu_list[i]); @@ -2357,6 +2365,7 @@ static uint8_t pack_rx_ulsch_indication_body_value(void *tlv, uint8_t **ppWriteP } // Write out the pdu data + assert(total_number_of_pdus <= NFAPI_RX_IND_MAX_PDU); for(i = 0; i < total_number_of_pdus; ++i) { uint16_t length = 0; nfapi_rx_indication_pdu_t *pdu = &(value->rx_pdu_list[i]); @@ -2365,7 +2374,7 @@ static uint8_t pack_rx_ulsch_indication_body_value(void *tlv, uint8_t **ppWriteP length = pdu->rx_indication_rel8.length; } - if( pusharray8(value->rx_pdu_list[i].data, length, length, ppWritePackedMsg, end) == 0) + if( pusharray8(value->rx_pdu_list[i].rx_ind_data, NFAPI_RX_IND_DATA_MAX, length, ppWritePackedMsg, end) == 0) return 0; } @@ -2584,6 +2593,7 @@ static uint8_t pack_cqi_indication_body_value(void *tlv, uint8_t **ppWritePacked uint16_t offset = 2; // taking into account the number_of_cqis uint16_t total_number_of_pdus = value->number_of_cqis; + assert(total_number_of_pdus <= NFAPI_CQI_IND_MAX_PDU); for(i = 0; i < total_number_of_pdus; ++i) { nfapi_cqi_indication_pdu_t *pdu = &(value->cqi_pdu_list[i]); offset += 2; // for the instance length @@ -2625,6 +2635,7 @@ static uint8_t pack_cqi_indication_body_value(void *tlv, uint8_t **ppWritePacked } // Write out the cqi information + assert(total_number_of_pdus <= NFAPI_CQI_IND_MAX_PDU); for(i = 0; i < total_number_of_pdus; ++i) { nfapi_cqi_indication_pdu_t *pdu = &(value->cqi_pdu_list[i]); uint8_t *instance_length_p = *ppWritePackedMsg; @@ -2645,6 +2656,7 @@ static uint8_t pack_cqi_indication_body_value(void *tlv, uint8_t **ppWritePacked } // Write out the cqi raw data + assert(total_number_of_pdus <= NFAPI_CQI_IND_MAX_PDU); for(i = 0; i < total_number_of_pdus; ++i) { uint16_t length = 0; nfapi_cqi_indication_pdu_t *pdu = &(value->cqi_pdu_list[i]); @@ -3008,7 +3020,10 @@ static uint8_t pack_nr_rx_data_indication_body(void* tlv, uint8_t **ppWritePacke push16(value->timing_advance, ppWritePackedMsg, end) && push16(value->rssi, ppWritePackedMsg, end) )) - return 0; + return 0; + + if(pusharray8(value->pdu, value->pdu_length, value->pdu_length, ppWritePackedMsg, end) == 0) + return 0; return 1; } @@ -3022,22 +3037,21 @@ static uint8_t pack_nr_rx_data_indication(void *msg, uint8_t **ppWritePackedMsg, push16(pNfapiMsg->slot , ppWritePackedMsg, end) && push16(pNfapiMsg->number_of_pdus, ppWritePackedMsg, end) )) - return 0; - - for(int i=0; inumber_of_pdus;i++) - { - if(!pack_nr_rx_data_indication_body(pNfapiMsg->pdu_list,ppWritePackedMsg,end)) return 0; + + for (int i = 0; i < pNfapiMsg->number_of_pdus; i++) + { + if(!pack_nr_rx_data_indication_body(&(pNfapiMsg->pdu_list[i]), ppWritePackedMsg, end)) + return 0; } -return 1; + return 1; } //NR CRC INDICATION -static uint8_t pack_nr_crc_indication_body(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) +static uint8_t pack_nr_crc_indication_body(nfapi_nr_crc_t* value, uint8_t **ppWritePackedMsg, uint8_t *end) { - nfapi_nr_crc_t* value = (nfapi_nr_crc_t*)tlv; if(!(push32(value->handle, ppWritePackedMsg, end) && push16(value->rnti, ppWritePackedMsg, end) && @@ -3064,9 +3078,9 @@ static uint8_t pack_nr_crc_indication(void *msg, uint8_t **ppWritePackedMsg, uin )) return 0; - for(int i=0; inumber_crcs;i++) + for (int i = 0; i < pNfapiMsg->number_crcs; i++) { - if(!pack_nr_crc_indication_body(pNfapiMsg->crc_list,ppWritePackedMsg,end)) + if(!pack_nr_crc_indication_body(&pNfapiMsg->crc_list[i], ppWritePackedMsg, end)) return 0; } @@ -3133,9 +3147,9 @@ static uint8_t pack_nr_rach_indication_body(void* tlv, uint8_t **ppWritePackedMs return 0; for(int i = 0; i < value->num_preamble; i++) { - if(!(push8(value->preamble_list->preamble_index, ppWritePackedMsg, end) && - push16(value->preamble_list->timing_advance, ppWritePackedMsg, end) && - push32(value->preamble_list->preamble_pwr, ppWritePackedMsg, end) + if(!(push8(value->preamble_list[i].preamble_index, ppWritePackedMsg, end) && + push16(value->preamble_list[i].timing_advance, ppWritePackedMsg, end) && + push32(value->preamble_list[i].preamble_pwr, ppWritePackedMsg, end) )) return 0; } @@ -3177,23 +3191,22 @@ static uint8_t pack_nr_uci_pucch_0_1(void* tlv, uint8_t **ppWritePackedMsg, uint )) return 0; if (value->pduBitmap & 0x01) { //SR - if(!(push8(value->sr->sr_indication, ppWritePackedMsg, end) && - push8(value->sr->sr_confidence_level, ppWritePackedMsg, end) + if (!(push8(value->sr->sr_indication, ppWritePackedMsg, end) && + push8(value->sr->sr_confidence_level, ppWritePackedMsg, end) )) return 0; } if (((value->pduBitmap >> 1) & 0x01)) { //HARQ - if(!(push8(value->harq->num_harq, ppWritePackedMsg, end) && - push8(value->harq->harq_confidence_level, ppWritePackedMsg, end) + if (!(push8(value->harq->num_harq, ppWritePackedMsg, end) && + push8(value->harq->harq_confidence_level, ppWritePackedMsg, end) )) return 0; - - for(int i=0; iharq->num_harq;i++) + for (int i = 0; i < value->harq->num_harq; i++) { - if(!(push8(value->harq->harq_list[i].harq_value, ppWritePackedMsg, end) + if (!(push8(value->harq->harq_list[i].harq_value, ppWritePackedMsg, end) )) - return 0; + return 0; } } @@ -3258,7 +3271,7 @@ static uint8_t pack_nr_uci_indication_body(void* tlv, uint8_t **ppWritePackedMsg switch (value->pdu_type) { case NFAPI_NR_UCI_PUSCH_PDU_TYPE: - printf("Unhandled NFAPI_NR_UCI_PUSCH_PDU_TYPE \n"); + NFAPI_TRACE(NFAPI_TRACE_WARN, "Unhandled NFAPI_NR_UCI_PUSCH_PDU_TYPE \n"); break; case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: @@ -3285,8 +3298,9 @@ static uint8_t pack_nr_uci_indication(void *msg, uint8_t **ppWritePackedMsg, uin for(int i=0; inum_ucis;i++) { - if(!pack_nr_uci_indication_body(pNfapiMsg->uci_list,ppWritePackedMsg,end)) - return 0; + if (!pack_nr_uci_indication_body(&pNfapiMsg->uci_list[i], ppWritePackedMsg, end)) + return 0; + } return 1; @@ -3307,13 +3321,6 @@ int nfapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packe NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack supplied pointers are null\n"); return -1; } - /* - printf("\n P7 MESSAGE SENT: \n"); - for(int i=0; i< packedBufLen; i++){ - printf("%d", *(uint8_t *)(pMessageBuf + i)); - } - printf("\n"); - */ // process the header if(!(push16(pMessageHeader->phy_id, &pWritePackedMessage, end) && push16(pMessageHeader->message_id, &pWritePackedMessage, end) && @@ -3349,7 +3356,6 @@ int nfapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packe case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST: result = pack_ul_dci_request(pMessageHeader, &pWritePackedMessage, end, config); break; - case NFAPI_UE_RELEASE_REQUEST: result =pack_ue_release_request(pMessageHeader, &pWritePackedMessage, end, config); break; @@ -3465,13 +3471,6 @@ int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBu return -1; } - /* - printf("\n P7 MESSAGE SENT: \n"); - for(int i=0; i< packedBufLen; i++){ - printf("%d", *(uint8_t *)(pMessageBuf + i)); - } - printf("\n"); - */ // process the header if(!(push16(pMessageHeader->phy_id, &pWritePackedMessage, end) && push16(pMessageHeader->message_id, &pWritePackedMessage, end) && @@ -3651,7 +3650,6 @@ static uint8_t unpack_dl_tti_csi_rs_pdu_rel15_value(void *tlv, uint8_t **ppReadP static uint8_t unpack_dl_tti_pdcch_pdu_rel15_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) { nfapi_nr_dl_tti_pdcch_pdu_rel15_t* value = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t*)tlv; - for(uint8_t i = 0; i < MAX_DCI_CORESET; ++i) { if(!(pull16(ppReadPackedMsg, &value->dci_pdu[i].RNTI, end) && @@ -3738,7 +3736,8 @@ static uint8_t unpack_dl_tti_ssb_pdu_rel15_value(void *tlv, uint8_t **ppReadPack pull8(ppReadPackedMsg, &value->SsbSubcarrierOffset, end) && pull16(ppReadPackedMsg, &value->ssbOffsetPointA, end) && pull8(ppReadPackedMsg, &value->bchPayloadFlag, end) && - pull32(ppReadPackedMsg, &value->bchPayload, end) + pull32(ppReadPackedMsg, &value->bchPayload, end) && + pull8(ppReadPackedMsg, &value->ssbRsrp, end) // TODO: pack precoding_and_beamforming too ); } @@ -4404,6 +4403,7 @@ static uint8_t unpack_ul_tti_request_pucch_pdu(void *tlv, uint8_t **ppReadPacked pull8(ppReadPackedMsg, &pucch_pdu->cyclic_prefix, end) && pull8(ppReadPackedMsg, &pucch_pdu->format_type, end) && pull8(ppReadPackedMsg, &pucch_pdu->multi_slot_tx_indicator, end) && + pull8(ppReadPackedMsg, &pucch_pdu->pi_2bpsk, end) && pull16(ppReadPackedMsg, &pucch_pdu->prb_start, end) && pull16(ppReadPackedMsg, &pucch_pdu->prb_size, end) && pull8(ppReadPackedMsg, &pucch_pdu->start_symbol_index, end) && @@ -5364,7 +5364,7 @@ static uint8_t unpack_hi_dci0_request_body_value(void *tlv, uint8_t **ppReadPack if(packedPduEnd > end) { // pdu end if past buffer end - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s pdu size to big %d %d\n", __FUNCTION__, packedPduEnd, end); + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s pdu size to big %p %p\n", __FUNCTION__, packedPduEnd, end); return 0; } @@ -5464,7 +5464,6 @@ static uint8_t unpack_ul_dci_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t * pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.ShiftIndex, end) && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.precoderGranularity, end) && pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, end)); - } static uint8_t unpack_ul_dci_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) { @@ -5654,12 +5653,13 @@ static uint8_t unpack_nr_slot_indication(uint8_t **ppReadPackedMsg, uint8_t *end return 1; } -//RX DATA INDICATION +//RX DATA INDICATION -static uint8_t unpack_nr_rx_data_indication_body(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +static uint8_t unpack_nr_rx_data_indication_body(nfapi_nr_rx_data_pdu_t* value, + uint8_t **ppReadPackedMsg, + uint8_t *end, + nfapi_p7_codec_config_t* config) { - nfapi_nr_rx_data_pdu_t* value = (nfapi_nr_rx_data_pdu_t*)tlv; - if(!(pull32(ppReadPackedMsg, &value->handle, end) && pull16(ppReadPackedMsg, &value->rnti, end) && pull8(ppReadPackedMsg, &value->harq_id, end) && @@ -5668,7 +5668,16 @@ static uint8_t unpack_nr_rx_data_indication_body(void* tlv, uint8_t **ppReadPack pull16(ppReadPackedMsg, &value->timing_advance, end) && pull16(ppReadPackedMsg, &value->rssi, end) )) - return 0; + return 0; + + uint16_t length = value->pdu_length; + value->pdu = nfapi_p7_allocate(length, config); + + if (pullarray8(ppReadPackedMsg, value->pdu, length, length, end) == 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s pullarray8 failure\n", __FUNCTION__); + return 0; + } return 1; } @@ -5682,10 +5691,14 @@ static uint8_t unpack_nr_rx_data_indication(uint8_t **ppReadPackedMsg, uint8_t * pull16(ppReadPackedMsg, &pNfapiMsg->number_of_pdus, end) )) return 0; + if (pNfapiMsg->number_of_pdus > 0) + { + pNfapiMsg->pdu_list = nfapi_p7_allocate(sizeof(*pNfapiMsg->pdu_list) * pNfapiMsg->number_of_pdus, config); + } - for(int i=0; inumber_of_pdus;i++) + for (int i = 0; i < pNfapiMsg->number_of_pdus; i++) { - if(!unpack_nr_rx_data_indication_body(pNfapiMsg->pdu_list, ppReadPackedMsg, end)) + if(!unpack_nr_rx_data_indication_body(&pNfapiMsg->pdu_list[i], ppReadPackedMsg, end, config)) return 0; } @@ -5715,21 +5728,23 @@ static uint8_t unpack_nr_crc_indication_body(nfapi_nr_crc_t* value, uint8_t **pp static uint8_t unpack_nr_crc_indication(uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_nr_crc_indication_t *msg, nfapi_p7_codec_config_t* config) { - nfapi_nr_crc_indication_t *pNfapiMsg = (nfapi_nr_crc_indication_t *) msg; - // pNfapiMsg = (nfapi_nr_crc_indication_t *) malloc(sizeof(nfapi_nr_crc_indication_t)); - // pNfapiMsg->crc_list = (nfapi_nr_crc_t *) malloc(sizeof(nfapi_nr_crc_t)); + nfapi_nr_crc_indication_t *pNfapiMsg = (nfapi_nr_crc_indication_t*)msg; - if (!(pull16(ppReadPackedMsg, &pNfapiMsg->sfn, end) && - pull16(ppReadPackedMsg, &pNfapiMsg->slot, end) && + if (!(pull16(ppReadPackedMsg, &pNfapiMsg->sfn , end) && + pull16(ppReadPackedMsg, &pNfapiMsg->slot , end) && pull16(ppReadPackedMsg, &pNfapiMsg->number_crcs, end) )) - return 0; + return 0; - for(int i=0; inumber_crcs;i++) + if (pNfapiMsg->number_crcs > 0) + { + pNfapiMsg->crc_list = nfapi_p7_allocate(sizeof(*pNfapiMsg->crc_list) * pNfapiMsg->number_crcs, config); + } + + for (int i = 0; i < pNfapiMsg->number_crcs; i++) { - if(!unpack_nr_crc_indication_body(pNfapiMsg->crc_list,ppReadPackedMsg,end)) - //if(!unpack_nr_crc_indication_body(value,ppReadPackedMsg,end)) - return 0; + if(!unpack_nr_crc_indication_body(&pNfapiMsg->crc_list[i], ppReadPackedMsg, end)) + return 0; } return 1; @@ -5780,9 +5795,11 @@ return 1; //NR RACH -static uint8_t unpack_nr_rach_indication_body(nfapi_nr_prach_indication_pdu_t* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +static uint8_t unpack_nr_rach_indication_body(nfapi_nr_prach_indication_pdu_t* value, + uint8_t **ppReadPackedMsg, + uint8_t *end, + nfapi_p7_codec_config_t* config) { - nfapi_nr_prach_indication_pdu_t* value = (nfapi_nr_prach_indication_pdu_t*)tlv; if(!(pull16(ppReadPackedMsg, &value->phy_cell_id, end) && pull8(ppReadPackedMsg, &value->symbol_index, end) && @@ -5793,15 +5810,18 @@ static uint8_t unpack_nr_rach_indication_body(nfapi_nr_prach_indication_pdu_t* t pull8(ppReadPackedMsg, &value->num_preamble, end) )) return 0; - value->preamble_list = (nfapi_nr_prach_indication_preamble_t*) malloc(sizeof(nfapi_nr_prach_indication_preamble_t) * value->num_preamble); - for(int i = 0; i < value->num_preamble; i++) - { - if(!(pull8(ppReadPackedMsg, &value->preamble_list->preamble_index, end) && - pull16(ppReadPackedMsg, &value->preamble_list->timing_advance, end) && - pull32(ppReadPackedMsg, &value->preamble_list->preamble_pwr, end) - )) - return 0; - } + + if (value->num_preamble > 0) { + value->preamble_list = nfapi_p7_allocate(sizeof(*value->preamble_list) * value->num_preamble, config); + for(int i = 0; i < value->num_preamble; i++) + { + if(!(pull8(ppReadPackedMsg, &value->preamble_list[i].preamble_index, end) && + pull16(ppReadPackedMsg, &value->preamble_list[i].timing_advance, end) && + pull32(ppReadPackedMsg, &value->preamble_list[i].preamble_pwr, end) + )) + return 0; + } + } return 1; } @@ -5812,31 +5832,27 @@ static uint8_t unpack_nr_rach_indication(uint8_t **ppReadPackedMsg, uint8_t *end pull16(ppReadPackedMsg, &pNfapiMsg->slot , end) && pull8(ppReadPackedMsg, &pNfapiMsg->number_of_pdus, end) )) - return 0; - pNfapiMsg->pdu_list = (nfapi_nr_prach_indication_pdu_t*) malloc(sizeof(nfapi_nr_prach_indication_pdu_t) * pNfapiMsg->number_of_pdus); - for(int i=0; i< pNfapiMsg->number_of_pdus;i++) - { - if(!unpack_nr_rach_indication_body(pNfapiMsg->pdu_list,ppReadPackedMsg,end)) return 0; - } -return 1; + if (pNfapiMsg->number_of_pdus > 0) { + pNfapiMsg->pdu_list = nfapi_p7_allocate(sizeof(*pNfapiMsg->pdu_list) * pNfapiMsg->number_of_pdus, config); + for(int i = 0; i < pNfapiMsg->number_of_pdus; i++) + { + if(!unpack_nr_rach_indication_body(&pNfapiMsg->pdu_list[i], ppReadPackedMsg, end, config)) + return 0; + } + } + return 1; } -//NR UCI +//NR UCI -static uint8_t unpack_nr_uci_pucch_0_1(nfapi_nr_uci_pucch_pdu_format_0_1_t* tlv, uint8_t **ppReadPackedMsg, uint8_t *end) { - nfapi_nr_uci_pucch_pdu_format_0_1_t* value = (nfapi_nr_uci_pucch_pdu_format_0_1_t*)tlv; +static uint8_t unpack_nr_uci_pucch_0_1(nfapi_nr_uci_pucch_pdu_format_0_1_t *value, + uint8_t **ppReadPackedMsg, + uint8_t *end, + nfapi_p7_codec_config_t *config) { - // uint8_t *ptr = *ppReadPackedMsg; - // printf("\n Read P7 message uci_0_1 indication unpack: "); - // while(ptr < end){ - // printf(" %d ", *ptr); - // ptr++; - // } - // printf("\n"); - - if(!(pull8(ppReadPackedMsg, &value->pduBitmap, end) && + if (!(pull8(ppReadPackedMsg, &value->pduBitmap, end) && pull32(ppReadPackedMsg, &value->handle, end) && pull16(ppReadPackedMsg, &value->rnti, end) && pull8(ppReadPackedMsg, &value->pucch_format, end) && @@ -5846,26 +5862,45 @@ static uint8_t unpack_nr_uci_pucch_0_1(nfapi_nr_uci_pucch_pdu_format_0_1_t* tlv, )) return 0; if (value->pduBitmap & 0x01) { //SR - value->sr = (nfapi_nr_sr_pdu_0_1_t*) malloc(sizeof(nfapi_nr_sr_pdu_0_1_t)); + value->sr = nfapi_p7_allocate(sizeof(*value->sr), config); + if (value->sr == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate sr pdu\n", __FUNCTION__); + return 0; + } if(!(pull8(ppReadPackedMsg, &value->sr->sr_indication, end) && - pull8(ppReadPackedMsg, &value->sr->sr_confidence_level, end) + pull8(ppReadPackedMsg, &value->sr->sr_confidence_level, end) )) return 0; } if (((value->pduBitmap >> 1) & 0x01)) { //HARQ - value->harq = (nfapi_nr_harq_pdu_0_1_t*) malloc(sizeof(nfapi_nr_harq_pdu_0_1_t)); - if(!(pull8(ppReadPackedMsg, &value->harq->num_harq, end) && - pull8(ppReadPackedMsg, &value->harq->harq_confidence_level, end) - )) - return 0; - value->harq->harq_list = (nfapi_nr_harq_t*) malloc(sizeof(nfapi_nr_harq_t*) * value->harq->num_harq); - for(int i=0; iharq->num_harq;i++) - { - if(!(pull8(ppReadPackedMsg, &value->harq->harq_list->harq_value, end) - )) - return 0; - } + + value->harq = nfapi_p7_allocate(sizeof(*value->harq), config); + if (value->harq == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate nr_harq pdu\n", __FUNCTION__); + return 0; + } + if (!(pull8(ppReadPackedMsg, &value->harq->num_harq, end) && + pull8(ppReadPackedMsg, &value->harq->harq_confidence_level, end) + )) + return 0; + value->harq->harq_list = NULL; + if (value->harq->num_harq > 0) { + value->harq->harq_list = nfapi_p7_allocate(sizeof(*value->harq->harq_list) * value->harq->num_harq, config); + if (value->harq->harq_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate harq ind pdu list (count:%d)\n", + __FUNCTION__, value->harq->num_harq); + return 0; + } + for (int i = 0; i < value->harq->num_harq; i++) { + if (!pull8(ppReadPackedMsg, &value->harq->harq_list[i].harq_value, end)) { + return 0; + } + } + } } return 1; @@ -5930,7 +5965,10 @@ static uint8_t unpack_nr_uci_pucch_2_3_4(nfapi_nr_uci_pucch_pdu_format_2_3_4_t* return 1; } -static uint8_t unpack_nr_uci_indication_body(nfapi_nr_uci_t* value, uint8_t **ppReadPackedMsg, uint8_t *end) +static uint8_t unpack_nr_uci_indication_body(nfapi_nr_uci_t *value, + uint8_t **ppReadPackedMsg, + uint8_t *end, + nfapi_p7_codec_config_t *config) { if(!(pull16(ppReadPackedMsg, &value->pdu_type, end) && pull16(ppReadPackedMsg, &value->pdu_size, end) @@ -5938,21 +5976,26 @@ static uint8_t unpack_nr_uci_indication_body(nfapi_nr_uci_t* value, uint8_t **pp return 0; switch (value->pdu_type) { - case NFAPI_NR_UCI_PUSCH_PDU_TYPE: - printf("Unhandled NFAPI_NR_UCI_PUSCH_PDU_TYPE \n"); - break; + case NFAPI_NR_UCI_PUSCH_PDU_TYPE: + NFAPI_TRACE(NFAPI_TRACE_WARN, "Unhandled NFAPI_NR_UCI_PUSCH_PDU_TYPE \n"); + break; - case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: { - nfapi_nr_uci_pucch_pdu_format_0_1_t* uci_pdu = &value->pucch_pdu_format_0_1; - unpack_nr_uci_pucch_0_1(uci_pdu, ppReadPackedMsg, end); - break; + case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: { + nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &value->pucch_pdu_format_0_1; + if (!unpack_nr_uci_pucch_0_1(uci_pdu, ppReadPackedMsg, end, config)) + return 0; + break; + } + case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: { + nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu = &value->pucch_pdu_format_2_3_4; + if (!unpack_nr_uci_pucch_2_3_4(uci_pdu, ppReadPackedMsg, end)) + return 0; + break; + } + default: + NFAPI_TRACE(NFAPI_TRACE_WARN, "Unexpected pdu type %d\n", value->pdu_type); + break; } - case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: { - nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu = &value->pucch_pdu_format_2_3_4; - unpack_nr_uci_pucch_2_3_4(uci_pdu, ppReadPackedMsg, end); - break; - } - } return 1; } @@ -5967,13 +6010,14 @@ static uint8_t unpack_nr_uci_indication(uint8_t **ppReadPackedMsg, uint8_t *end, )) return 0; - for(int i=0; inum_ucis;i++) + pNfapiMsg->uci_list = nfapi_p7_allocate(sizeof(*pNfapiMsg->uci_list) * pNfapiMsg->num_ucis, config); + for (int i = 0; i < pNfapiMsg->num_ucis; i++) { - if(!unpack_nr_uci_indication_body(pNfapiMsg->uci_list,ppReadPackedMsg,end)) - return 0; + if(!unpack_nr_uci_indication_body(&pNfapiMsg->uci_list[i], ppReadPackedMsg, end, config)) + return 0; } -return 1; + return 1; } static uint8_t unpack_ue_release_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) { @@ -6233,6 +6277,7 @@ static uint8_t unpack_harq_indication_body_value(void *tlv, uint8_t **ppReadPack return 0; } + assert(value->number_of_harqs <= NFAPI_HARQ_IND_MAX_PDU); value->harq_pdu_list = (nfapi_harq_indication_pdu_t *)nfapi_p7_allocate(sizeof(nfapi_harq_indication_pdu_t) * value->number_of_harqs, config); if(value->harq_pdu_list == NULL) { @@ -6297,7 +6342,8 @@ static uint8_t unpack_crc_indication_body_value(void *tlv, uint8_t **ppReadPacke } if(value->number_of_crcs > 0) { - value->crc_pdu_list = (nfapi_crc_indication_pdu_t *)nfapi_p7_allocate(sizeof(nfapi_crc_indication_pdu_t) * value->number_of_crcs, config); + assert(value->number_of_crcs <= NFAPI_CRC_IND_MAX_PDU); + value->crc_pdu_list = (nfapi_crc_indication_pdu_t *)nfapi_p7_allocate(sizeof(nfapi_crc_indication_pdu_t) * NFAPI_CRC_IND_MAX_PDU, config); if(value->crc_pdu_list == NULL) { NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate crc ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_crcs); @@ -6349,114 +6395,141 @@ static uint8_t unpack_rx_indication_rel9_value(void *tlv, uint8_t **ppReadPacked return (pull16(ppReadPackedMsg, &value->timing_advance_r9, end)); } -static uint8_t unpack_rx_indication_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) { - nfapi_rx_indication_body_t *value = (nfapi_rx_indication_body_t *)tlv; - // the rxBodyEnd points to the end of the cqi PDU's - uint8_t *rxBodyEnd = *ppReadPackedMsg + value->tl.length; - uint8_t *rxPduEnd = rxBodyEnd; - uint8_t *numberOfPdusAddress = *ppReadPackedMsg; +static uint8_t unpack_rx_indication_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) +{ + nfapi_rx_indication_body_t *value = (nfapi_rx_indication_body_t*)tlv; - if(rxBodyEnd > end) { - // pdu end is past buffer end - return 0; - } + NFAPI_TRACE(NFAPI_TRACE_DEBUG, "%s value->tl.length in unpack: %u \n", __FUNCTION__, + value->tl.length); + uint8_t *rxBodyEnd = *ppReadPackedMsg + value->tl.length; - if(pull16(ppReadPackedMsg, &value->number_of_pdus, end) == 0) - return 0; + NFAPI_TRACE(NFAPI_TRACE_DEBUG, "%s rxBodyEnd: %p end: %p\n", __FUNCTION__, + rxBodyEnd, end); + if (rxBodyEnd > end) + { + // pdu end is past buffer end + return 0; + } - if(value->number_of_pdus > NFAPI_RX_IND_MAX_PDU) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of rx ind pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_pdus, NFAPI_RX_IND_MAX_PDU); - return 0; - } + if (pull16(ppReadPackedMsg, &value->number_of_pdus, end) == 0) + return 0; - if(value->number_of_pdus > 0) { - value->rx_pdu_list = (nfapi_rx_indication_pdu_t *)nfapi_p7_allocate(sizeof(nfapi_rx_indication_pdu_t) * value->number_of_pdus, config); + if (value->number_of_pdus > NFAPI_RX_IND_MAX_PDU) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of rx ind pdu's exceed maxium (count:%d max:%d)\n", __FUNCTION__, value->number_of_pdus, NFAPI_RX_IND_MAX_PDU); + return 0; + } - if(value->rx_pdu_list == NULL) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate rx ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_pdus); - return 0; - } - } else { - value->rx_pdu_list = 0; - } + if (value->number_of_pdus > 0) + { + assert(value->number_of_pdus <= NFAPI_RX_IND_MAX_PDU); + value->rx_pdu_list = (nfapi_rx_indication_pdu_t *)nfapi_p7_allocate(sizeof(nfapi_rx_indication_pdu_t) * NFAPI_RX_IND_MAX_PDU, config); + if (value->rx_pdu_list == NULL) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate rx ind pdu list (count:%d)\n", __FUNCTION__, value->number_of_pdus); + return 0; + } + } + else + { + value->rx_pdu_list = 0; + } - uint8_t i = 0; - nfapi_rx_indication_pdu_t *pdu = 0; + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s number_of_pdus = %u\n", __FUNCTION__, value->number_of_pdus); + for (int i = 0; i < value->number_of_pdus; i++) + { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s i = %u\n", __FUNCTION__, i); + nfapi_tl_t generic_tl; - while((uint8_t *)(*ppReadPackedMsg) < rxBodyEnd && (uint8_t *)(*ppReadPackedMsg) < rxPduEnd) { - nfapi_tl_t generic_tl; + // NFAPI_RX_UE_INFORMATION_TAG + if (unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s unpack_tl failed\n", __FUNCTION__); + return 0; + } - if( unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0) - return 0; + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s generic_tl.tag = 0x%x length = %u\n", __FUNCTION__, generic_tl.tag, generic_tl.length); - switch(generic_tl.tag) { - case NFAPI_RX_UE_INFORMATION_TAG: { - pdu = &(value->rx_pdu_list[i++]); - pdu->rx_ue_information.tl = generic_tl; + if (generic_tl.tag != NFAPI_RX_UE_INFORMATION_TAG) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s generic_tl.tag wrong\n", __FUNCTION__); + return 0; + } - if(unpack_rx_ue_information_value(&pdu->rx_ue_information, ppReadPackedMsg, end) == 0) - return 0; - } - break; + assert(i < NFAPI_RX_IND_MAX_PDU); + nfapi_rx_indication_pdu_t *pdu = &value->rx_pdu_list[i]; - case NFAPI_RX_INDICATION_REL8_TAG: { - if(pdu != 0) { - pdu->rx_indication_rel8.tl = generic_tl; + pdu->rx_ue_information.tl = generic_tl; + if (unpack_rx_ue_information_value(&pdu->rx_ue_information, ppReadPackedMsg, end) == 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s unpack_rx_ue_info failure\n", __FUNCTION__); + return 0; + } - if(unpack_rx_indication_rel8_value(&pdu->rx_indication_rel8, ppReadPackedMsg, end) == 0) - return 0; + // NFAPI_RX_INDICATION_REL8_TAG + if (unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s unpack_tl failed\n", __FUNCTION__); + return 0; + } - if(pdu->rx_indication_rel8.offset > 0) { - // Need to check that the data is within the tlv - if(numberOfPdusAddress + pdu->rx_indication_rel8.offset + pdu->rx_indication_rel8.length <= rxBodyEnd) { - // If this the first pdu set the rxPduEnd - if(numberOfPdusAddress + pdu->rx_indication_rel8.offset < rxPduEnd) { - rxPduEnd = numberOfPdusAddress + pdu->rx_indication_rel8.offset; + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s generic_tl.tag = 0x%x length = %u\n", __FUNCTION__, generic_tl.tag, generic_tl.length); - if(rxPduEnd > end) { - // pdu end is past buffer end - return 0; - } - } - } else { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME: the rx data is outside of the tlv\n"); - } - } - } - } - break; + if (generic_tl.tag != NFAPI_RX_INDICATION_REL8_TAG) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s generic_tl.tag wrong\n", __FUNCTION__); + return 0; + } - case NFAPI_RX_INDICATION_REL9_TAG: { - if(pdu != 0) { - pdu->rx_indication_rel9.tl = generic_tl; + pdu->rx_indication_rel8.tl = generic_tl; + if (unpack_rx_indication_rel8_value(&pdu->rx_indication_rel8, ppReadPackedMsg, end) == 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s unpack_rx_indication_rel8 failure\n", __FUNCTION__); + return 0; + } + //What is offset not stripping 10 bytes + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s pdu->rx_indication_rel8.offset = %u", __FUNCTION__, + pdu->rx_indication_rel8.offset); - if(unpack_rx_indication_rel9_value(&pdu->rx_indication_rel9, ppReadPackedMsg, end) == 0) - return 0; - } - } - break; + // NFAPI_RX_INDICATION_REL9_TAG + if (unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s unpack_tl failed\n", __FUNCTION__); + return 0; + } - default: { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "RX_ULSCH.indication Invalid pdu type %d \n", generic_tl.tag ); - } - break; - } - } + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s generic_tl.tag = 0x%x length = %u\n", __FUNCTION__, generic_tl.tag, generic_tl.length); - uint8_t idx = 0; + if (generic_tl.tag != NFAPI_RX_INDICATION_REL9_TAG) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s generic_tl.tag wrong\n", __FUNCTION__); + return 0; + } - for(idx = 0; idx < value->number_of_pdus; ++idx) { - if(value->rx_pdu_list[idx].rx_indication_rel8.tl.tag == NFAPI_RX_INDICATION_REL8_TAG) { - uint32_t length = value->rx_pdu_list[idx].rx_indication_rel8.length; - value->rx_pdu_list[idx].data = nfapi_p7_allocate(length, config); + pdu->rx_indication_rel9.tl = generic_tl; + if (unpack_rx_indication_rel9_value(&pdu->rx_indication_rel9, ppReadPackedMsg, end) == 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s unpack_rx_indication_rel9 failure\n", __FUNCTION__); + return 0; + } + } - if(pullarray8(ppReadPackedMsg, value->rx_pdu_list[idx].data, length, length, end) == 0) { - return 0; - } - } - } + assert(value->number_of_pdus <= NFAPI_RX_IND_MAX_PDU); + for (int i = 0; i < value->number_of_pdus; ++i) + { + nfapi_rx_indication_pdu_t *pdu = &value->rx_pdu_list[i]; + if (pdu->rx_indication_rel8.tl.tag == NFAPI_RX_INDICATION_REL8_TAG) + { + uint32_t length = pdu->rx_indication_rel8.length; + if (pullarray8(ppReadPackedMsg, pdu->rx_ind_data, NFAPI_RX_IND_DATA_MAX, length, end) == 0) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s pullarray8 failure\n", __FUNCTION__); + return 0; + } + } + } - return 1; + return 1; } static uint8_t unpack_rx_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) { @@ -7414,12 +7487,10 @@ static int check_nr_unpack_length(nfapi_message_id_e msgId, uint32_t unpackedBuf if (unpackedBufLen >= sizeof(nfapi_nr_tx_data_request_t)) retLen = sizeof(nfapi_nr_tx_data_request_t); break; - case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION: if (unpackedBufLen >= sizeof(nfapi_nr_rx_data_indication_t)) retLen = sizeof(nfapi_nr_rx_data_indication_t); break; - case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION: if (unpackedBufLen >= sizeof(nfapi_nr_crc_indication_t)) retLen = sizeof(nfapi_nr_crc_indication_t); @@ -7429,17 +7500,14 @@ static int check_nr_unpack_length(nfapi_message_id_e msgId, uint32_t unpackedBuf if (unpackedBufLen >= sizeof(nfapi_nr_rach_indication_t)) retLen = sizeof(nfapi_nr_rach_indication_t); break; - case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION: if (unpackedBufLen >= sizeof(nfapi_nr_uci_indication_t)) retLen = sizeof(nfapi_nr_uci_indication_t); break; - case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION: if (unpackedBufLen >= sizeof(nfapi_nr_srs_indication_t)) retLen = sizeof(nfapi_nr_srs_indication_t); break; - case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC: if (unpackedBufLen >= sizeof(nfapi_nr_dl_node_sync_t)) retLen = sizeof(nfapi_nr_dl_node_sync_t); @@ -7758,14 +7826,6 @@ int nfapi_nr_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void * return -1; } - // uint8_t *ptr = pMessageBuf; - // printf("\n Read P7 message unpack: "); - // while(ptr < end){ - // printf(" %d ", *ptr); - // ptr++; - // } - // printf("\n"); - // clean the supplied buffer for - tag value blanking (void)memset(pUnpackedBuf, 0, unpackedBufLen); @@ -7823,7 +7883,6 @@ int nfapi_nr_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void * else return -1; break; - case NFAPI_UE_RELEASE_REQUEST: if (check_nr_unpack_length(NFAPI_UE_RELEASE_REQUEST, unpackedBufLen)) result = unpack_ue_release_request(&pReadPackedMessage, end, pMessageHeader, config); diff --git a/nfapi/open-nFAPI/pnf/inc/pnf_p7.h b/nfapi/open-nFAPI/pnf/inc/pnf_p7.h index 763b5c9abe..cab2455691 100644 --- a/nfapi/open-nFAPI/pnf/inc/pnf_p7.h +++ b/nfapi/open-nFAPI/pnf/inc/pnf_p7.h @@ -148,6 +148,7 @@ typedef struct { int pnf_p7_message_pump(pnf_p7_t* pnf_p7); int pnf_nr_p7_message_pump(pnf_p7_t* pnf_p7); int pnf_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_p7_message_header_t* msg, uint32_t msg_len); +int pnf_nr_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_p7_message_header_t* header, uint32_t msg_len); int pnf_p7_send_message(pnf_p7_t* pnf_p7, uint8_t* msg, uint32_t msg_len); 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 fc9cd66077..ca8bc8d9a4 100644 --- a/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h +++ b/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h @@ -800,6 +800,7 @@ int nfapi_pnf_p7_harq_ind(nfapi_pnf_p7_config_t* config, nfapi_harq_indication_t * \return 0 means success, -1 means failure */ int nfapi_pnf_p7_crc_ind(nfapi_pnf_p7_config_t* config, nfapi_crc_indication_t* ind); +int nfapi_pnf_p7_nr_crc_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_crc_indication_t* ind); /*! Send the RX.indication * \param config A pointer to a PNF P7 config @@ -807,6 +808,7 @@ int nfapi_pnf_p7_crc_ind(nfapi_pnf_p7_config_t* config, nfapi_crc_indication_t* * \return 0 means success, -1 means failure */ int nfapi_pnf_p7_rx_ind(nfapi_pnf_p7_config_t* config, nfapi_rx_indication_t* ind); +int nfapi_pnf_p7_nr_rx_data_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rx_data_indication_t* ind); /*! Send the RACH.indication * \param config A pointer to a PNF P7 config @@ -821,6 +823,7 @@ int nfapi_pnf_p7_rach_ind(nfapi_pnf_p7_config_t* config, nfapi_rach_indication_t * \return 0 means success, -1 means failure */ int nfapi_pnf_p7_srs_ind(nfapi_pnf_p7_config_t* config, nfapi_srs_indication_t* ind); +int nfapi_pnf_p7_nr_srs_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_srs_indication_t* ind); /*! Send the SR.indication * \param config A pointer to a PNF P7 config @@ -842,6 +845,7 @@ int nfapi_pnf_p7_cqi_ind(nfapi_pnf_p7_config_t* config, nfapi_cqi_indication_t* * \return 0 means success, -1 means failure */ int nfapi_pnf_p7_lbt_dl_ind(nfapi_pnf_p7_config_t* config, nfapi_lbt_dl_indication_t* ind); +int nfapi_pnf_p7_nr_uci_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_uci_indication_t* ind); /*! Send the NB_HARQ.indication * \param config A pointer to a PNF P7 config @@ -856,6 +860,7 @@ int nfapi_pnf_p7_nb_harq_ind(nfapi_pnf_p7_config_t* config, nfapi_nb_harq_indica * \return 0 means success, -1 means failure */ int nfapi_pnf_p7_nrach_ind(nfapi_pnf_p7_config_t* config, nfapi_nrach_indication_t* ind); +int nfapi_pnf_p7_nr_rach_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rach_indication_t* ind); /*! Send a vendor exntesion message diff --git a/nfapi/open-nFAPI/pnf/src/pnf.c b/nfapi/open-nFAPI/pnf/src/pnf.c index fdafd93279..b4158dbb40 100644 --- a/nfapi/open-nFAPI/pnf/src/pnf.c +++ b/nfapi/open-nFAPI/pnf/src/pnf.c @@ -1,12 +1,12 @@ /* * Copyright 2017 Cisco Systems, Inc. - * + * * 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. @@ -93,9 +93,9 @@ void pnf_nr_handle_pnf_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) else { nfapi_nr_pnf_param_request_t req; - + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF_PARAM.request received\n"); - + // unpack the message if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(nfapi_nr_pnf_param_request_t), &pnf->_public.codec_config) >= 0) { @@ -109,7 +109,7 @@ void pnf_nr_handle_pnf_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) else { NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: PNF not in IDLE state\n", __FUNCTION__); - + nfapi_nr_pnf_param_response_t resp; memset(&resp, 0, sizeof(resp)); resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_RESPONSE; @@ -121,7 +121,7 @@ void pnf_nr_handle_pnf_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) { NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); } - + if(req.vendor_extension) pnf->_public.codec_config.deallocate(req.vendor_extension); } @@ -137,9 +137,9 @@ void pnf_handle_pnf_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) else { nfapi_pnf_param_request_t req; - + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF_PARAM.request received\n"); - + // unpack the message if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(nfapi_pnf_param_request_t), &pnf->_public.codec_config) >= 0) { @@ -153,7 +153,7 @@ void pnf_handle_pnf_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) else { NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: PNF not in IDLE state\n", __FUNCTION__); - + nfapi_pnf_param_response_t resp; memset(&resp, 0, sizeof(resp)); resp.header.message_id = NFAPI_PNF_PARAM_RESPONSE; @@ -165,7 +165,7 @@ void pnf_handle_pnf_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) { NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); } - + if(req.vendor_extension) pnf->_public.codec_config.deallocate(req.vendor_extension); } @@ -185,7 +185,7 @@ void pnf_handle_pnf_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) nfapi_pnf_config_request_t req; NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF_CONFIG.request received\n"); - + // unpack the message if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &pnf->_public.codec_config) >= 0) { @@ -194,7 +194,7 @@ void pnf_handle_pnf_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) { // delete the phy records nfapi_pnf_phy_config_delete_all(&pnf->_public); - + // create the phy records if (req.pnf_phy_rf_config.tl.tag == NFAPI_PNF_PHY_RF_TAG) { @@ -203,14 +203,14 @@ void pnf_handle_pnf_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) { nfapi_pnf_phy_config_t* phy = (nfapi_pnf_phy_config_t*)malloc(sizeof(nfapi_pnf_phy_config_t)); memset(phy, 0, sizeof(nfapi_pnf_phy_config_t)); - + phy->state = NFAPI_PNF_PHY_IDLE; phy->phy_id = req.pnf_phy_rf_config.phy_rf_config[i].phy_id; - + nfapi_pnf_phy_config_add(&(pnf->_public), phy); } } - + if(pnf->_public.pnf_config_req) { (pnf->_public.pnf_config_req)(&(pnf->_public), &req); @@ -219,7 +219,7 @@ void pnf_handle_pnf_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) else { NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: PNF not in correct state: %d\n", __FUNCTION__, pnf->_public.state); - + nfapi_pnf_config_response_t resp; memset(&resp, 0, sizeof(resp)); resp.header.message_id = NFAPI_PNF_CONFIG_RESPONSE; @@ -251,7 +251,7 @@ void pnf_nr_handle_pnf_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen nfapi_nr_pnf_config_request_t req; NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF_CONFIG.request received\n"); - + // unpack the message if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &pnf->_public.codec_config) >= 0) { @@ -260,7 +260,7 @@ void pnf_nr_handle_pnf_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen { // delete the phy records nfapi_pnf_phy_config_delete_all(&pnf->_public); - + // create the phy records if (req.pnf_phy_rf_config.tl.tag == NFAPI_PNF_PHY_RF_TAG) { @@ -269,14 +269,14 @@ void pnf_nr_handle_pnf_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen { nfapi_pnf_phy_config_t* phy = (nfapi_pnf_phy_config_t*)malloc(sizeof(nfapi_pnf_phy_config_t)); memset(phy, 0, sizeof(nfapi_pnf_phy_config_t)); - + phy->state = NFAPI_PNF_PHY_IDLE; phy->phy_id = req.pnf_phy_rf_config.phy_rf_config[i].phy_id; - + nfapi_pnf_phy_config_add(&(pnf->_public), phy); } } - + if(pnf->_public.pnf_nr_config_req) { (pnf->_public.pnf_nr_config_req)(&(pnf->_public), &req); @@ -285,7 +285,7 @@ void pnf_nr_handle_pnf_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen else { NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: PNF not in correct state: %d\n", __FUNCTION__, pnf->_public.state); - + nfapi_nr_pnf_config_response_t resp; memset(&resp, 0, sizeof(resp)); resp.header.message_id = NFAPI_PNF_CONFIG_RESPONSE; @@ -315,7 +315,7 @@ void pnf_handle_pnf_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) nfapi_pnf_start_request_t req; NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF_START.request Received\n"); - + // unpack the message if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &pnf->_public.codec_config) >= 0) { @@ -357,7 +357,7 @@ void pnf_nr_handle_pnf_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) nfapi_nr_pnf_start_request_t req; NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF_START.request Received\n"); - + // unpack the message if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &pnf->_public.codec_config) >= 0) { @@ -397,9 +397,9 @@ void pnf_handle_pnf_stop_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) else { nfapi_pnf_stop_request_t req; - + NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF_STOP.request Received\n"); - + // unpack the message if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &pnf->_public.codec_config) >= 0) { @@ -423,7 +423,7 @@ void pnf_handle_pnf_stop_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) { NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); } - + if(req.vendor_extension) pnf->_public.codec_config.deallocate(req.vendor_extension); @@ -440,11 +440,11 @@ void pnf_handle_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) else { nfapi_param_request_t req; - + nfapi_pnf_config_t* config = &(pnf->_public); - + NFAPI_TRACE(NFAPI_TRACE_INFO, "PARAM.request received\n"); - + // unpack the message if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) { @@ -479,7 +479,7 @@ void pnf_handle_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) resp.error_code = NFAPI_MSG_INVALID_CONFIG; nfapi_pnf_param_resp(config, &resp); } - + } else { @@ -495,7 +495,7 @@ void pnf_handle_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) { NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); } - + if(req.vendor_extension) pnf->_public.codec_config.deallocate(req.vendor_extension); @@ -512,11 +512,11 @@ void pnf_nr_handle_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) else { nfapi_nr_param_request_scf_t req; - + nfapi_pnf_config_t* config = &(pnf->_public); - + NFAPI_TRACE(NFAPI_TRACE_INFO, "PARAM.request received\n"); - + // unpack the message if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) { @@ -551,7 +551,7 @@ void pnf_nr_handle_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) resp.error_code = NFAPI_MSG_INVALID_CONFIG; nfapi_nr_pnf_param_resp(config, &resp); } - + } else { @@ -567,7 +567,7 @@ void pnf_nr_handle_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) { NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); } - + if(req.vendor_extension) pnf->_public.codec_config.deallocate(req.vendor_extension); @@ -587,9 +587,9 @@ void pnf_handle_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) nfapi_config_request_t req; NFAPI_TRACE(NFAPI_TRACE_INFO, "CONFIG.request received\n"); - + nfapi_pnf_config_t* config = &(pnf->_public); - + // unpack the message if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) { @@ -639,7 +639,7 @@ void pnf_handle_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) { NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); } - + if(req.vendor_extension) pnf->_public.codec_config.deallocate(req.vendor_extension); } @@ -659,9 +659,9 @@ void pnf_nr_handle_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) nfapi_nr_config_request_scf_t req; NFAPI_TRACE(NFAPI_TRACE_INFO, "CONFIG.request received\n"); - + nfapi_pnf_config_t* config = &(pnf->_public); - + // unpack the message if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) { @@ -681,7 +681,7 @@ void pnf_nr_handle_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) { (config->nr_config_req)(config, phy, &req); - + } } else @@ -718,7 +718,7 @@ void pnf_nr_handle_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) { NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); } - + if(req.vendor_extension) pnf->_public.codec_config.deallocate(req.vendor_extension); } @@ -734,11 +734,11 @@ void pnf_handle_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) else { nfapi_start_request_t req; - + nfapi_pnf_config_t* config = &(pnf->_public); - + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() START.request received state:%d\n", __FUNCTION__, config->state); - + // unpack the message if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) { @@ -788,7 +788,7 @@ void pnf_handle_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) { NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); } - + if(req.vendor_extension) pnf->_public.codec_config.deallocate(req.vendor_extension); @@ -805,11 +805,11 @@ void pnf_nr_handle_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) else { nfapi_nr_start_request_scf_t req; - + nfapi_pnf_config_t* config = &(pnf->_public); - + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() START.request received state:%d\n", __FUNCTION__, config->state); - + // unpack the message if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) { @@ -859,7 +859,7 @@ void pnf_nr_handle_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) { NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); } - + if(req.vendor_extension) pnf->_public.codec_config.deallocate(req.vendor_extension); @@ -878,9 +878,9 @@ void pnf_handle_stop_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) nfapi_stop_request_t req; NFAPI_TRACE(NFAPI_TRACE_INFO, "STOP.request received\n"); - + nfapi_pnf_config_t* config = &(pnf->_public); - + // unpack the message if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) { @@ -930,10 +930,10 @@ void pnf_handle_stop_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) { NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); } - + if(req.vendor_extension) pnf->_public.codec_config.deallocate(req.vendor_extension); - + } } @@ -949,9 +949,9 @@ void pnf_nr_handle_stop_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) nfapi_nr_stop_request_t req; NFAPI_TRACE(NFAPI_TRACE_INFO, "STOP.request received\n"); - + nfapi_pnf_config_t* config = &(pnf->_public); - + // unpack the message if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) { @@ -1001,10 +1001,10 @@ void pnf_nr_handle_stop_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) { NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); } - + if(req.vendor_extension) pnf->_public.codec_config.deallocate(req.vendor_extension); - + } } @@ -1020,9 +1020,9 @@ void pnf_handle_measurement_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) nfapi_measurement_request_t req; NFAPI_TRACE(NFAPI_TRACE_INFO, "MEASUREMENT.request received\n"); - + nfapi_pnf_config_t* config = &(pnf->_public); - + // unpack the message if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) { @@ -1072,7 +1072,7 @@ void pnf_handle_measurement_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) { NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); } - + if(req.vendor_extension) pnf->_public.codec_config.deallocate(req.vendor_extension); } @@ -1087,13 +1087,13 @@ void pnf_handle_rssi_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); } else - { + { nfapi_rssi_request_t req; - + NFAPI_TRACE(NFAPI_TRACE_INFO, "RSSI.request received\n"); - + nfapi_pnf_config_t* config = &(pnf->_public); - + // unpack the message if (nfapi_p4_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) { @@ -1143,10 +1143,10 @@ void pnf_handle_rssi_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) { NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); } - + if(req.vendor_extension) pnf->_public.codec_config.deallocate(req.vendor_extension); - + } } @@ -1159,11 +1159,11 @@ void pnf_handle_cell_search_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) else { nfapi_cell_search_request_t req; - + NFAPI_TRACE(NFAPI_TRACE_INFO, "CELL_SEARCH.request received\n"); - + nfapi_pnf_config_t* config = &(pnf->_public); - + if (nfapi_p4_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) { if(config->state == NFAPI_PNF_RUNNING) @@ -1212,7 +1212,7 @@ void pnf_handle_cell_search_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) { NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); } - + if(req.vendor_extension) pnf->_public.codec_config.deallocate(req.vendor_extension); } @@ -1231,9 +1231,9 @@ void pnf_handle_broadcast_detect_request(pnf_t* pnf, void *pRecvMsg, int recvMsg nfapi_broadcast_detect_request_t req; NFAPI_TRACE(NFAPI_TRACE_INFO, "BROADCAST_DETECT.request received\n"); - + nfapi_pnf_config_t* config = &(pnf->_public); - + if (nfapi_p4_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) { if(config->state == NFAPI_PNF_RUNNING) @@ -1282,7 +1282,7 @@ void pnf_handle_broadcast_detect_request(pnf_t* pnf, void *pRecvMsg, int recvMsg { NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); } - + if(req.vendor_extension) pnf->_public.codec_config.deallocate(req.vendor_extension); @@ -1298,11 +1298,11 @@ void pnf_handle_system_information_schedule_request(pnf_t* pnf, void *pRecvMsg, else { nfapi_system_information_schedule_request_t req; - + NFAPI_TRACE(NFAPI_TRACE_INFO, "SYSTEM_INFORMATION_SCHEDULE.request received\n"); - + nfapi_pnf_config_t* config = &(pnf->_public); - + if (nfapi_p4_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) { if(config->state == NFAPI_PNF_RUNNING) @@ -1351,7 +1351,7 @@ void pnf_handle_system_information_schedule_request(pnf_t* pnf, void *pRecvMsg, { NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); } - + if(req.vendor_extension) pnf->_public.codec_config.deallocate(req.vendor_extension); } @@ -1368,9 +1368,9 @@ void pnf_handle_system_information_request(pnf_t* pnf, void *pRecvMsg, int recvM nfapi_system_information_request_t req; NFAPI_TRACE(NFAPI_TRACE_INFO, "SYSTEM_INFORMATION.request received\n"); - + nfapi_pnf_config_t* config = &(pnf->_public); - + if (nfapi_p4_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) { if(config->state == NFAPI_PNF_RUNNING) @@ -1419,7 +1419,7 @@ void pnf_handle_system_information_request(pnf_t* pnf, void *pRecvMsg, int recvM { NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); } - + if(req.vendor_extension) pnf->_public.codec_config.deallocate(req.vendor_extension); } @@ -1435,11 +1435,11 @@ void pnf_handle_nmm_stop_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) else { nfapi_nmm_stop_request_t req; - + NFAPI_TRACE(NFAPI_TRACE_INFO, "NMM_STOP.request received\n"); - + nfapi_pnf_config_t* config = &(pnf->_public); - + if (nfapi_p4_message_unpack(pRecvMsg, recvMsgLen, &req, sizeof(req), &config->codec_config) >= 0) { if(config->state == NFAPI_PNF_RUNNING) @@ -1488,7 +1488,7 @@ void pnf_handle_nmm_stop_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) { NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); } - + if(req.vendor_extension) pnf->_public.codec_config.deallocate(req.vendor_extension); } @@ -1504,21 +1504,21 @@ void pnf_handle_vendor_extension(void* pRecvMsg, int recvMsgLen, pnf_t* pnf, uin else { nfapi_pnf_config_t* config = &(pnf->_public); - + if(config->allocate_p4_p5_vendor_ext) { uint16_t msg_size; nfapi_p4_p5_message_header_t* msg = config->allocate_p4_p5_vendor_ext(message_id, &msg_size); - + if(msg == 0) { - NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to allocate vendor extention structure\n"); + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to allocate vendor extention structure\n"); return; } - - + + int unpack_result = nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, msg, msg_size, &config->codec_config); - + if(unpack_result == 0) { if(config->vendor_ext) @@ -1528,10 +1528,10 @@ void pnf_handle_vendor_extension(void* pRecvMsg, int recvMsgLen, pnf_t* pnf, uin { NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__); } - + if(config->deallocate_p4_p5_vendor_ext) config->deallocate_p4_p5_vendor_ext(msg); - + } } } @@ -1732,8 +1732,8 @@ void pnf_handle_p5_message(pnf_t* pnf, void *pRecvMsg, int recvMsgLen) int pnf_nr_pack_and_send_p5_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len) { int packed_len = nfapi_nr_p5_message_pack(msg, msg_len, - pnf->tx_message_buffer, - sizeof(pnf->tx_message_buffer), + pnf->tx_message_buffer, + sizeof(pnf->tx_message_buffer), &pnf->_public.codec_config); if (packed_len < 0) @@ -1749,8 +1749,8 @@ int pnf_nr_pack_and_send_p5_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* ms int pnf_pack_and_send_p5_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len) { int packed_len = nfapi_p5_message_pack(msg, msg_len, - pnf->tx_message_buffer, - sizeof(pnf->tx_message_buffer), + pnf->tx_message_buffer, + sizeof(pnf->tx_message_buffer), &pnf->_public.codec_config); if (packed_len < 0) @@ -1765,8 +1765,8 @@ int pnf_pack_and_send_p5_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, int pnf_pack_and_send_p4_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len) { int packed_len = nfapi_p4_message_pack(msg, msg_len, - pnf->tx_message_buffer, - sizeof(pnf->tx_message_buffer), + pnf->tx_message_buffer, + sizeof(pnf->tx_message_buffer), &pnf->_public.codec_config); if (packed_len < 0) @@ -1797,14 +1797,14 @@ int pnf_connect(pnf_t* pnf) NFAPI_TRACE(NFAPI_TRACE_INFO, "Starting P5 PNF connection to VNF at %s:%u\n", pnf->_public.vnf_ip_addr, pnf->_public.vnf_p5_port); // todo split the vnf address list. currently only supporting 1 - + struct addrinfo hints, *servinfo; memset(&hints, 0, sizeof(hints)); hints.ai_socktype = SOCK_STREAM; // For SCTP we are only interested in SOCK_STREAM // todo : allow the client to restrict IPV4 or IPV6 // todo : randomize which address to connect to? - + char port_str[8]; snprintf(port_str, sizeof(port_str), "%d", pnf->_public.vnf_p5_port); if(getaddrinfo(pnf->_public.vnf_ip_addr, port_str, &hints, &servinfo) != 0) @@ -1822,7 +1822,7 @@ int pnf_connect(pnf_t* pnf) char* family = "Unknown"; char* address = "Unknown"; char _addr[128]; - + if(p->ai_family == AF_INET6) { family = "IPV6"; @@ -1886,7 +1886,7 @@ int pnf_connect(pnf_t* pnf) } else { - // Create an IP socket point + // Create an IP socket point if ((pnf->p5_sock = socket(p->ai_family, SOCK_STREAM, IPPROTO_IP)) < 0) { NFAPI_TRACE(NFAPI_TRACE_ERROR, "After P5 socket errno: %d\n", errno); @@ -1894,12 +1894,12 @@ int pnf_connect(pnf_t* pnf) return -1; } } - + NFAPI_TRACE(NFAPI_TRACE_INFO, "P5 socket created...\n"); - + if (connect(pnf->p5_sock, p->ai_addr, p->ai_addrlen ) < 0) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "After connect (address:%s port:%d) errno: %d\n", + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After connect (address:%s port:%d) errno: %d\n", pnf->_public.vnf_ip_addr, pnf->_public.vnf_p5_port, errno); if(errno == EINVAL) @@ -1970,14 +1970,16 @@ int pnf_connect(pnf_t* pnf) int pnf_send_message(pnf_t* pnf, uint8_t *msg, uint32_t len, uint16_t stream) { - + if (pnf->sctp) { +#if 0 printf("\nPNF SENDS: \n"); for(int i=0; ip5_sock, msg, len, NULL, 0, 42/*config->sctp_stream_number*/, 0, stream/*P5_STREAM_ID*/, 0, 0) < 0) { @@ -2069,12 +2071,14 @@ int pnf_read_dispatch_message(pnf_t* pnf) } else { +#if 0 // print the received message printf("\n MESSAGE RECEIVED: \n"); for(int i=0; ip5_sock+1, &rfds, NULL, NULL, &timeout); if(selectRetval == 0) - { + { // timeout continue; } @@ -2336,7 +2342,7 @@ int pnf_nr_message_pump(pnf_t* pnf) selectRetval = select(pnf->p5_sock+1, &rfds, NULL, NULL, &timeout); if(selectRetval == 0) - { + { // timeout continue; } @@ -2376,4 +2382,3 @@ int pnf_nr_message_pump(pnf_t* pnf) return 0; } - diff --git a/nfapi/open-nFAPI/pnf/src/pnf_interface.c b/nfapi/open-nFAPI/pnf/src/pnf_interface.c index 8c9722c13e..a53604640c 100644 --- a/nfapi/open-nFAPI/pnf/src/pnf_interface.c +++ b/nfapi/open-nFAPI/pnf/src/pnf_interface.c @@ -1,12 +1,12 @@ /* * Copyright 2017 Cisco Systems, Inc. - * + * * 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. @@ -32,11 +32,11 @@ nfapi_pnf_config_t* nfapi_pnf_config_create() memset(_this, 0, sizeof(pnf_t)); _this->sctp = 1; // enable sctp - + _this->_public.vnf_p5_port = NFAPI_P5_SCTP_PORT; - + _this->_public.malloc = &malloc; - _this->_public.free = &free; + _this->_public.free = &free; _this->_public.codec_config.allocate = &malloc; _this->_public.codec_config.deallocate = &free; @@ -55,10 +55,6 @@ int nfapi_pnf_start(nfapi_pnf_config_t* config) if(config == 0) return -1; - // Make sure to set the defined trace function before using NFAPI_TRACE - if(config->trace) - nfapi_trace_g = config->trace; - NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); pnf_t* _this = (pnf_t*)(config); @@ -89,10 +85,6 @@ int nfapi_nr_pnf_start(nfapi_pnf_config_t* config) if(config == 0) return -1; - // Make sure to set the defined trace function before using NFAPI_TRACE - if(config->trace) - nfapi_trace_g = config->trace; - NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); pnf_t* _this = (pnf_t*)(config); @@ -265,7 +257,7 @@ int nfapi_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_param_response_t* res NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); return -1; } - + pnf_t* _this = (pnf_t*)(config); return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_param_response_t)); @@ -279,7 +271,7 @@ int nfapi_nr_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_nr_param_response_ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__); return -1; } - + pnf_t* _this = (pnf_t*)(config); return pnf_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_param_response_scf_t)); @@ -591,4 +583,3 @@ int nfapi_pnf_vendor_extension(nfapi_pnf_config_t* config, nfapi_p4_p5_message_h return pnf_pack_and_send_p5_message(_this, msg, msg_len); } - diff --git a/nfapi/open-nFAPI/pnf/src/pnf_p7.c b/nfapi/open-nFAPI/pnf/src/pnf_p7.c index 092b967189..fb1a713e56 100644 --- a/nfapi/open-nFAPI/pnf/src/pnf_p7.c +++ b/nfapi/open-nFAPI/pnf/src/pnf_p7.c @@ -1060,6 +1060,23 @@ int pnf_p7_slot_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn, uint16_t sl (pnf_p7->_public.ul_dci_req_fn)(NULL, &(pnf_p7->_public), pnf_p7->_public.dummy_slot.ul_dci_req); } } + if(tx_slot_buffer->ul_tti_req != 0) + { + if(pnf_p7->_public.ul_tti_req_fn) + { + (pnf_p7->_public.ul_tti_req_fn)(NULL, &(pnf_p7->_public), tx_slot_buffer->ul_tti_req); + } + } + else + { + // send dummy + if(pnf_p7->_public.ul_tti_req_fn && pnf_p7->_public.dummy_slot.ul_tti_req) + { + pnf_p7->_public.dummy_slot.ul_tti_req->SFN = sfn_tx; + pnf_p7->_public.dummy_slot.ul_tti_req->Slot = slot_tx; + (pnf_p7->_public.ul_tti_req_fn)(NULL, &(pnf_p7->_public), pnf_p7->_public.dummy_slot.ul_tti_req); + } + } //deallocate slot buffers after passing down the PDUs to PHY processing @@ -1585,7 +1602,7 @@ void pnf_handle_dl_tti_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7) if(req == NULL) { - NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to alloced nfapi_dl_tti_request structure\n"); + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to allocate nfapi_dl_tti_request structure\n"); return; } int unpack_result = nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, req, sizeof(nfapi_nr_dl_tti_request_t), &(pnf_p7->_public.codec_config)); @@ -1659,7 +1676,7 @@ void pnf_handle_dl_config_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_ if(req == NULL) { - NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to alloced nfapi_dl_config_request structure\n"); + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to allocate nfapi_dl_config_request structure\n"); return; } @@ -1750,7 +1767,7 @@ void pnf_handle_ul_tti_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7) if(req == NULL) { - NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to alloced nfapi_ul_tti_request structure\n"); + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to allocate nfapi_ul_tti_request structure\n"); return; } @@ -1825,7 +1842,7 @@ void pnf_handle_ul_config_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_ if(req == NULL) { - NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to alloced nfapi_ul_config_request structure\n"); + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to allocate nfapi_ul_config_request structure\n"); return; } @@ -1898,7 +1915,7 @@ void pnf_handle_ul_dci_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7) if(req == NULL) { - NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to allocate nfapi_ul_dci_request structure\n"); + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to allocate nfapi_ul_dci_request structure\n"); return; } @@ -1969,7 +1986,7 @@ void pnf_handle_hi_dci0_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7 if(req == NULL) { - NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to alloced nfapi_hi_dci0_request structure\n"); + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to allocate nfapi_hi_dci0_request structure\n"); return; } @@ -2038,7 +2055,7 @@ void pnf_handle_tx_data_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7 if(req == NULL) { - NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to alloced nfapi_tx_request structure\n"); + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to allocate nfapi_tx_request structure\n"); return; } @@ -2118,7 +2135,7 @@ void pnf_handle_tx_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7) if(req == NULL) { - NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to alloced nfapi_tx_request structure\n"); + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to allocate nfapi_tx_request structure\n"); return; } @@ -2192,7 +2209,7 @@ void pnf_handle_lbt_dl_config_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* if(req == NULL) { - NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to alloced nfapi_lbt_dl_config_request structure\n"); + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to allocate nfapi_lbt_dl_config_request structure\n"); return; } @@ -2255,7 +2272,7 @@ void pnf_handle_p7_vendor_extension(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pn if(msg == 0) { - NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to allocate vendor extention structure\n"); + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to allocate vendor extention structure\n"); return; } @@ -2279,7 +2296,7 @@ void pnf_handle_ue_release_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf nfapi_ue_release_request_t* req = allocate_nfapi_ue_release_request(pnf_p7); if(req == NULL) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to alloced nfapi_ue_release_request structure\n"); + NFAPI_TRACE(NFAPI_TRACE_ERROR, "failed to allocate nfapi_ue_release_request structure\n"); return; } @@ -2381,7 +2398,7 @@ uint32_t calculate_nr_t2(uint32_t now_time_hr, uint16_t sfn,uint16_t slot, uint3 { static uint32_t prev_t2 = 0; - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s(now_time_hr:%u sfn:%d slot:%d slot_start_time_Hr:%u) slot_time_us:%u t2:%u prev_t2:%u diff:%u\n", + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s(now_time_hr:%u sfn to slot:%d slot_start_time_Hr:%u) slot_time_us:%u t2:%u prev_t2:%u diff:%u\n", __FUNCTION__, now_time_hr, NFAPI_SFNSLOT2DEC(sfn, slot), slot_start_time_hr, slot_time_us, @@ -2656,7 +2673,7 @@ void pnf_handle_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, ui // validate the input params if(pRecvMsg == NULL || recvMsgLen < 4 || pnf_p7 == NULL) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "pnf_handle_p7_message: invalid input params (%d %d %d)\n", pRecvMsg, recvMsgLen, pnf_p7); + NFAPI_TRACE(NFAPI_TRACE_ERROR, "pnf_handle_p7_message: invalid input params (%p %d %p)\n", pRecvMsg, recvMsgLen, pnf_p7); return; } @@ -2762,7 +2779,7 @@ void pnf_nr_handle_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, // validate the input params if(pRecvMsg == NULL || recvMsgLen < 4 || pnf_p7 == NULL) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "pnf_handle_p7_message: invalid input params (%d %d %d)\n", pRecvMsg, recvMsgLen, pnf_p7); + NFAPI_TRACE(NFAPI_TRACE_ERROR, "pnf_handle_p7_message: invalid input params (%p %d %p)\n", pRecvMsg, recvMsgLen, pnf_p7); return; } @@ -2889,12 +2906,19 @@ void pnf_nfapi_p7_read_dispatch_message(pnf_p7_t* pnf_p7, uint32_t now_hr_time) } // read the segment - recvfrom_result = recvfrom(pnf_p7->p7_sock, pnf_p7->rx_message_buffer, header.message_length, MSG_DONTWAIT, (struct sockaddr*)&remote_addr, &remote_addr_size); + recvfrom_result = recvfrom(pnf_p7->p7_sock, pnf_p7->rx_message_buffer, pnf_p7->rx_message_buffer_size, + MSG_DONTWAIT | MSG_TRUNC, (struct sockaddr*)&remote_addr, &remote_addr_size); now_hr_time = pnf_get_current_time_hr(); //DJP - moved to here - get closer timestamp??? if(recvfrom_result > 0) { + if (recvfrom_result != header.message_length) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "(%d) Received unexpected number of bytes. %d != %d", + __LINE__, recvfrom_result, header.message_length); + break; + } pnf_handle_p7_message(pnf_p7->rx_message_buffer, recvfrom_result, pnf_p7, now_hr_time); //printf("\npnf_handle_p7_message sfn=%d,slot=%d\n",pnf_p7->sfn,pnf_p7->slot); } @@ -3126,6 +3150,38 @@ int pnf_p7_message_pump(pnf_p7_t* pnf_p7) return 0; } +struct timespec pnf_timespec_add(struct timespec lhs, struct timespec rhs) +{ + struct timespec result; + + result.tv_sec = lhs.tv_sec + rhs.tv_sec; + result.tv_nsec = lhs.tv_nsec + rhs.tv_nsec; + + if(result.tv_nsec > 1e9) + { + result.tv_sec++; + result.tv_nsec-= 1e9; + } + + return result; +} + +struct timespec pnf_timespec_sub(struct timespec lhs, struct timespec rhs) +{ + struct timespec result; + if ((lhs.tv_nsec-rhs.tv_nsec)<0) + { + result.tv_sec = lhs.tv_sec-rhs.tv_sec-1; + result.tv_nsec = 1000000000+lhs.tv_nsec-rhs.tv_nsec; + } + else + { + result.tv_sec = lhs.tv_sec-rhs.tv_sec; + result.tv_nsec = lhs.tv_nsec-rhs.tv_nsec; + } + return result; +} + int pnf_nr_p7_message_pump(pnf_p7_t* pnf_p7) { @@ -3201,6 +3257,19 @@ int pnf_nr_p7_message_pump(pnf_p7_t* pnf_p7) } NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 bind succeeded...\n"); + //Initializaing timing structures needed for slot ticking + + struct timespec slot_start; + clock_gettime(CLOCK_MONOTONIC, &slot_start); + + struct timespec pselect_start; + + struct timespec slot_duration; + slot_duration.tv_sec = 0; + slot_duration.tv_nsec = 0.5e6; + + //Infinite loop + while(pnf_p7->terminate == 0) { fd_set rfds; @@ -3210,11 +3279,29 @@ int pnf_nr_p7_message_pump(pnf_p7_t* pnf_p7) FD_ZERO(&rfds); FD_SET(pnf_p7->p7_sock, &rfds); - struct timeval timeout; + struct timespec timeout; timeout.tv_sec = 100; - timeout.tv_usec = 0; + timeout.tv_nsec = 0; + clock_gettime(CLOCK_MONOTONIC, &pselect_start); - selectRetval = select(pnf_p7->p7_sock+1, &rfds, NULL, NULL, &timeout); + //setting the timeout + + if((pselect_start.tv_sec > slot_start.tv_sec) || ((pselect_start.tv_sec == slot_start.tv_sec) && (pselect_start.tv_nsec > slot_start.tv_nsec))) + { + // overran the end of the subframe we do not want to wait + timeout.tv_sec = 0; + timeout.tv_nsec = 0; + + //struct timespec overrun = pnf_timespec_sub(pselect_start, sf_start); + //NFAPI_TRACE(NFAPI_TRACE_INFO, "Subframe overrun detected of %d.%d running to catchup\n", overrun.tv_sec, overrun.tv_nsec); + } + else + { + // still time before the end of the subframe wait + timeout = pnf_timespec_sub(slot_start, pselect_start); + } + + selectRetval = pselect(pnf_p7->p7_sock+1, &rfds, NULL, NULL, &timeout, NULL); uint32_t now_hr_time = pnf_get_current_time_hr(); @@ -3224,6 +3311,17 @@ int pnf_nr_p7_message_pump(pnf_p7_t* pnf_p7) if(selectRetval == 0) { // timeout + + //update slot start timing + slot_start = pnf_timespec_add(slot_start, slot_duration); + + //increment sfn/slot + if (++pnf_p7->slot == 20) + { + pnf_p7->slot = 0; + pnf_p7->sfn = (pnf_p7->sfn + 1) % 1024; + } + continue; } else if (selectRetval == -1 && (errno == EINTR)) @@ -3242,7 +3340,7 @@ int pnf_nr_p7_message_pump(pnf_p7_t* pnf_p7) if(FD_ISSET(pnf_p7->p7_sock, &rfds)) { - pnf_nr_nfapi_p7_read_dispatch_message(pnf_p7, now_hr_time); + pnf_nr_nfapi_p7_read_dispatch_message(pnf_p7, now_hr_time); } } NFAPI_TRACE(NFAPI_TRACE_ERROR, "PNF_P7 Terminating..\n"); diff --git a/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c b/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c index 0db1feb398..a1be4d0edc 100644 --- a/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c +++ b/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c @@ -44,6 +44,7 @@ nfapi_pnf_p7_config_t* nfapi_pnf_p7_config_create() _this->_public.codec_config.allocate = &malloc; _this->_public.codec_config.deallocate = &free; + // cppcheck-suppress memleak return &(_this->_public); } @@ -63,10 +64,6 @@ int nfapi_pnf_p7_start(nfapi_pnf_p7_config_t* config) if(config == 0) return -1; - // Make sure to set the defined trace function before using NFAPI_TRACE - if(config->trace) - nfapi_trace_g = config->trace; - pnf_p7_t* _this = (pnf_p7_t*)(config); NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); @@ -82,10 +79,6 @@ int nfapi_nr_pnf_p7_start(nfapi_pnf_p7_config_t* config) if(config == 0) return -1; - // Make sure to set the defined trace function before using NFAPI_TRACE - if(config->trace) - nfapi_trace_g = config->trace; - pnf_p7_t* _this = (pnf_p7_t*)(config); NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__); @@ -175,17 +168,7 @@ int nfapi_pnf_p7_rach_ind(nfapi_pnf_p7_config_t* config, nfapi_rach_indication_t pnf_p7_t* _this = (pnf_p7_t*)(config); return pnf_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_rach_indication_t)); } -int nfapi_pnf_p7_srs_ind(nfapi_pnf_p7_config_t* config, nfapi_srs_indication_t* ind) -{ - if(config == NULL || ind == NULL) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__); - return -1; - } - pnf_p7_t* _this = (pnf_p7_t*)(config); - return pnf_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_srs_indication_t)); -} int nfapi_pnf_p7_sr_ind(nfapi_pnf_p7_config_t* config, nfapi_sr_indication_t* ind) { if(config == NULL || ind == NULL) diff --git a/nfapi/open-nFAPI/pnf_sim/src/fapi_stub.cpp b/nfapi/open-nFAPI/pnf_sim/src/fapi_stub.cpp index 1c2f0bef80..4fe5065cea 100644 --- a/nfapi/open-nFAPI/pnf_sim/src/fapi_stub.cpp +++ b/nfapi/open-nFAPI/pnf_sim/src/fapi_stub.cpp @@ -278,7 +278,7 @@ void *fapi_thread_start(void *ptr) { if(instance->tick == 1000) { if(instance->tx_byte_count > 0) { - printf("[FAPI] Tx rate %d bytes/sec\n", instance->tx_byte_count); + printf("[FAPI] Tx rate %u bytes/sec\n", instance->tx_byte_count); instance->tx_byte_count = 0; } @@ -319,7 +319,7 @@ void *fapi_thread_start(void *ptr) { millisec = now_ts.tv_nsec / 1e6; if(last_millisec != -1 && ((last_millisec + 1 ) % 1000) != millisec) { - printf("*** missing millisec %d %d\n", last_millisec, millisec); + printf("*** missing millisec %u %u\n", last_millisec, millisec); catchup = millisec - last_millisec - 1; } 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 31328393c9..decb48e5c8 100644 --- a/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h +++ b/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h @@ -20,6 +20,7 @@ #include "nfapi_interface.h" #include "nfapi_nr_interface_scf.h" #include "nfapi_nr_interface.h" +#include "openair2/PHY_INTERFACE/queue_t.h" #include "debug.h" @@ -86,8 +87,6 @@ typedef struct nfapi_vnf_config void* (*malloc)(size_t size); /*! A user define callback to override the default memory deallocation */ void (*free)(void*); - /*! A user define callback to handle trace from the pnf */ - void (*trace)(nfapi_trace_level_t level, const char* message, ...); /*! The port the VNF P5 SCTP connection listens on * @@ -662,12 +661,6 @@ typedef struct nfapi_vnf_p7_config * If not set the vnf p7 library will use free */ void (*free)(void*); - - /*! A user define callback to handle trace from the pnf - * \param level The trace level - * \param message The trace string - */ - void (*trace)(nfapi_trace_level_t level, const char* message, ...); /*! The port the vnf p7 will receive on */ int port; @@ -908,7 +901,7 @@ void nfapi_vnf_p7_config_destory(nfapi_vnf_p7_config_t* config); * This function is blocking and will not return until the nfapi_vnf_p7_stop * function is called. */ - +extern queue_t gnb_slot_ind_queue; int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config); int nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t* config); diff --git a/nfapi/open-nFAPI/vnf/src/vnf.c b/nfapi/open-nFAPI/vnf/src/vnf.c index 7fee47d6d5..e0431ced17 100644 --- a/nfapi/open-nFAPI/vnf/src/vnf.c +++ b/nfapi/open-nFAPI/vnf/src/vnf.c @@ -85,7 +85,7 @@ void nfapi_vnf_pnf_list_add(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* no nfapi_vnf_pnf_info_t* nfapi_vnf_pnf_list_find(nfapi_vnf_config_t* config, int p5_idx) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s : config->pnf_list:%p\n", __FUNCTION__, config->pnf_list); + NFAPI_TRACE(NFAPI_TRACE_DEBUG, "config->pnf_list:%p\n", config->pnf_list); nfapi_vnf_pnf_info_t* curr = config->pnf_list; while(curr != 0) @@ -1051,7 +1051,7 @@ void vnf_handle_vendor_extension(void* pRecvMsg, int recvMsgLen, nfapi_vnf_confi } else { - NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to allocate vendor extention structure\n"); + NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to allocate vendor extention structure\n"); } } } @@ -1383,6 +1383,7 @@ int vnf_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* uint32_t header_buffer_size = NFAPI_HEADER_LENGTH; uint8_t header_buffer[header_buffer_size]; + memset(header_buffer, 0, header_buffer_size); uint32_t stack_buffer_size = 32; //should it be the size of then sctp_notificatoin structure uint8_t stack_buffer[stack_buffer_size]; @@ -1393,6 +1394,7 @@ int vnf_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* uint32_t message_size = 0; struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); socklen_t addr_len = sizeof(addr); struct sctp_sndrcvinfo sndrcvinfo; diff --git a/nfapi/open-nFAPI/vnf/src/vnf_interface.c b/nfapi/open-nFAPI/vnf/src/vnf_interface.c index 084c4fa485..633dd18f24 100644 --- a/nfapi/open-nFAPI/vnf/src/vnf_interface.c +++ b/nfapi/open-nFAPI/vnf/src/vnf_interface.c @@ -25,6 +25,7 @@ #include #include #include +#include #include @@ -69,10 +70,6 @@ int nfapi_nr_vnf_start(nfapi_vnf_config_t* config) if(config == 0) return -1; - // Make sure to set the defined trace function before using NFAPI_TRACE - if(config->trace) - nfapi_trace_g = (nfapi_trace_fn_t)config->trace; - NFAPI_TRACE(NFAPI_TRACE_INFO, "%s()\n", __FUNCTION__); int p5ListenSock, p5Sock; @@ -218,7 +215,7 @@ int nfapi_nr_vnf_start(nfapi_vnf_config_t* config) initMsg.sinit_max_instreams = 5; //MAX_SCTP_STREAMS; // number of output streams can be greater if (setsockopt(p5ListenSock, IPPROTO_SCTP, SCTP_INITMSG, &initMsg, sizeof(initMsg)) < 0) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt (SCTP_INITMSG) errno: %d\n", errno) + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt (SCTP_INITMSG) errno: %d\n", errno); close(p5ListenSock); return 0; } @@ -477,14 +474,7 @@ int nfapi_nr_vnf_start(nfapi_vnf_config_t* config) int nfapi_vnf_start(nfapi_vnf_config_t* config) { - // Verify that config is not null - if(config == 0) - return -1; - - // Make sure to set the defined trace function before using NFAPI_TRACE - if(config->trace) - nfapi_trace_g = (nfapi_trace_fn_t)config->trace; - + assert(config != 0); NFAPI_TRACE(NFAPI_TRACE_INFO, "%s()\n", __FUNCTION__); int p5ListenSock, p5Sock; @@ -630,7 +620,7 @@ int nfapi_vnf_start(nfapi_vnf_config_t* config) initMsg.sinit_max_instreams = 5; //MAX_SCTP_STREAMS; // number of output streams can be greater if (setsockopt(p5ListenSock, IPPROTO_SCTP, SCTP_INITMSG, &initMsg, sizeof(initMsg)) < 0) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt (SCTP_INITMSG) errno: %d\n", errno) + NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt (SCTP_INITMSG) errno: %d\n", errno); close(p5ListenSock); return 0; } @@ -1164,7 +1154,7 @@ int nfapi_vnf_allocate_phy(nfapi_vnf_config_t* config, int p5_idx, uint16_t* phy info->timing_window = 30; // This seems to override what gets set by the user - why??? //TODO: Change in NR in terms of microsecends,what should be the value? info->timing_info_mode = 0x03; - info->timing_info_period = 128; + info->timing_info_period = 10; nfapi_vnf_phy_info_list_add(config, info); diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7.c b/nfapi/open-nFAPI/vnf/src/vnf_p7.c index e390031554..2ac59dd7be 100644 --- a/nfapi/open-nFAPI/vnf/src/vnf_p7.c +++ b/nfapi/open-nFAPI/vnf/src/vnf_p7.c @@ -17,14 +17,21 @@ #include +#include #include #include #include #include #include #include +#include + #include "vnf_p7.h" +#ifdef NDEBUG +# warning assert is disabled +#endif + #define SYNC_CYCLE_COUNT 2 void* vnf_p7_malloc(vnf_p7_t* vnf_p7, size_t size) @@ -816,11 +823,6 @@ void vnf_handle_rx_ulsch_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vn } } - uint16_t i = 0; - for(i = 0; i < ind.rx_indication_body.number_of_pdus; ++i) - { - vnf_p7_codec_free(vnf_p7, ind.rx_indication_body.rx_pdu_list[i].data); - } vnf_p7_codec_free(vnf_p7, ind.rx_indication_body.rx_pdu_list); vnf_p7_codec_free(vnf_p7, ind.vendor_extension); } @@ -1157,7 +1159,7 @@ void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); - NFAPI_TRACE(NFAPI_TRACE_INFO, "(%4d/%1d) %d.%d PNF to VNF phy_id:%2d (t1/2/3/4:%8u, %8u, %8u, %8u) txrx:%4u procT:%3u latency(us):%4d(avg:%4d) offset(us):%8d filtered(us):%8d wrap[t1:%u t2:%u]\n", + NFAPI_TRACE(NFAPI_TRACE_INFO, "(%4d/%1d) %ld.%ld PNF to VNF phy_id:%2d (t1/2/3/4:%8u, %8u, %8u, %8u) txrx:%4u procT:%3u latency(us):%4d(avg:%4d) offset(us):%8d filtered(us):%8d wrap[t1:%u t2:%u]\n", NFAPI_SFNSF2SFN(phy->sfn_sf), NFAPI_SFNSF2SF(phy->sfn_sf), ts.tv_sec, ts.tv_nsec, ind.header.phy_id, ind.t1, ind.t2, ind.t3, t4, tx_2_rx, pnf_proc_time, latency, phy->average_latency, phy->sf_offset, phy->sf_offset_filtered, @@ -1292,7 +1294,7 @@ void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) //NFAPI_TRACE(NFAPI_TRACE_NOTE, "VNF P7 In Sync with phy (phy_id:%d)\n", phy->phy_id); if(vnf_p7->_public.sync_indication) - (vnf_p7->_public.sync_indication)(&(vnf_p7->_public), 1); + (vnf_p7->_public.sync_indication)(&(vnf_p7->_public), phy->in_sync); } phy->in_sync = 1; @@ -1471,7 +1473,8 @@ void vnf_handle_nr_slot_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf } else { - if(vnf_p7->_public.nr_slot_indication) + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s: Handling NR SLOT Indication\n", __FUNCTION__); + if(vnf_p7->_public.nr_slot_indication) { (vnf_p7->_public.nr_slot_indication)(&ind); } @@ -1496,12 +1499,12 @@ void vnf_handle_nr_rx_data_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* } else { - if(vnf_p7->_public.nr_rx_data_indication) + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s: Handling RX Indication\n", __FUNCTION__); + if(vnf_p7->_public.nr_rx_data_indication) { (vnf_p7->_public.nr_rx_data_indication)(&ind); } } - } } @@ -1522,12 +1525,12 @@ void vnf_handle_nr_crc_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_ } else { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s: Handling CRC Indication\n", __FUNCTION__); if(vnf_p7->_public.nr_crc_indication) - { + { (vnf_p7->_public.nr_crc_indication)(&ind); } } - } } @@ -1573,12 +1576,12 @@ void vnf_handle_nr_uci_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_ } else { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s: Handling UCI Indication\n", __FUNCTION__); if(vnf_p7->_public.nr_uci_indication) { (vnf_p7->_public.nr_uci_indication)(&ind); } } - } } @@ -1599,12 +1602,12 @@ void vnf_handle_nr_rach_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf } else { + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s: Handling RACH Indication\n", __FUNCTION__); if(vnf_p7->_public.nr_rach_indication) { (vnf_p7->_public.nr_rach_indication)(&ind); } } - } } @@ -1699,14 +1702,7 @@ void vnf_nr_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7 } if (phy->filtered_adjust && (phy->slot_offset_filtered > 1e6 || phy->slot_offset_filtered < -1e6)) - { struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%1d) %d.%d PNF to VNF phy_id:%2d (t1/2/3/4:%8u, %8u, %8u, %8u) txrx:%4u procT:%3u latency(us):%4d(avg:%4d) offset(us):%8d filtered(us):%8d wrap[t1:%u t2:%u]\n", - phy->sfn, phy->slot, ts.tv_sec, ts.tv_nsec, ind.header.phy_id, - ind.t1, ind.t2, ind.t3, t4, - tx_2_rx, pnf_proc_time, latency, phy->average_latency, phy->slot_offset, phy->slot_offset_filtered, - (ind.t1previous_t1), (ind.t2previous_t2)); - + { phy->filtered_adjust = 0; phy->zero_count=0; phy->min_sync_cycle_count = 2; @@ -1738,7 +1734,7 @@ void vnf_nr_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7 sfn_slot_dec += (phy->slot_offset / 500); - //NFAPI_TRACE(NFAPI_TRACE_NOTE, "PNF to VNF slot offset:%d sfn :%d slot:%d \n",phy->slot_offset,NFAPI_SFNSLOTDEC2SFN(sfn_slot_dec),NFAPI_SFNSLOTDEC2SLOT(sfn_slot_dec) ); + NFAPI_TRACE(NFAPI_TRACE_NOTE, "PNF to VNF slot offset:%d sfn :%d slot:%d \n",phy->slot_offset,NFAPI_SFNSLOTDEC2SFN(sfn_slot_dec),NFAPI_SFNSLOTDEC2SLOT(sfn_slot_dec) ); } @@ -1838,7 +1834,7 @@ void vnf_nr_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7 NFAPI_TRACE(NFAPI_TRACE_NOTE, "VNF P7 In Sync with phy (phy_id:%d)\n", phy->phy_id); if(vnf_p7->_public.sync_indication) - (vnf_p7->_public.sync_indication)(&(vnf_p7->_public), 1); + (vnf_p7->_public.sync_indication)(&(vnf_p7->_public), phy->in_sync); } phy->in_sync = 1; @@ -2032,6 +2028,7 @@ void vnf_handle_timing_info(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) } } +int16_t vnf_pnf_sfnslot_delta; void vnf_nr_handle_timing_info(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) { @@ -2051,18 +2048,21 @@ void vnf_nr_handle_timing_info(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) if (vnf_p7 && vnf_p7->p7_connections) { //int16_t vnf_pnf_sfnsf_delta = NFAPI_SFNSF2DEC(vnf_p7->p7_connections[0].sfn_sf) - NFAPI_SFNSF2DEC(ind.last_sfn_sf); - int16_t vnf_pnf_sfnslot_delta = NFAPI_SFNSLOT2DEC(vnf_p7->p7_connections[0].sfn,vnf_p7->p7_connections[0].slot) - NFAPI_SFNSLOT2DEC(ind.last_sfn,ind.last_slot); + vnf_pnf_sfnslot_delta = NFAPI_SFNSLOT2DEC(vnf_p7->p7_connections[0].sfn,vnf_p7->p7_connections[0].slot) - NFAPI_SFNSLOT2DEC(ind.last_sfn,ind.last_slot); //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() PNF:SFN/SF:%d VNF:SFN/SF:%d deltaSFNSF:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ind.last_sfn_sf), NFAPI_SFNSF2DEC(vnf_p7->p7_connections[0].sfn_sf), vnf_pnf_sfnsf_delta); // Panos: Careful here!!! Modification of the original nfapi-code //if (vnf_pnf_sfnsf_delta>1 || vnf_pnf_sfnsf_delta < -1) //printf("VNF-PNF delta - %d", vnf_pnf_sfnslot_delta); - if (vnf_pnf_sfnslot_delta>0 || vnf_pnf_sfnslot_delta < 0) + if (vnf_pnf_sfnslot_delta != 0) { - NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() LARGE SFN/SF DELTA between PNF and VNF delta:%d VNF:%d PNF:%d\n\n\n\n\n\n\n\n\n", __FUNCTION__, vnf_pnf_sfnslot_delta,NFAPI_SFNSLOT2DEC(vnf_p7->p7_connections[0].sfn,vnf_p7->p7_connections[0].slot),NFAPI_SFNSLOT2DEC(ind.last_sfn,ind.last_slot)) ; + NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() LARGE SFN/SLOT DELTA between PNF and VNF. Delta %d. PNF:%d.%d VNF:%d.%d\n\n\n\n\n\n\n\n\n", + __FUNCTION__, vnf_pnf_sfnslot_delta, + ind.last_sfn, ind.last_slot, + vnf_p7->p7_connections[0].sfn, vnf_p7->p7_connections[0].slot); // Panos: Careful here!!! Modification of the original nfapi-code - // vnf_p7->p7_connections[0].sfn = ind.last_sfn; - // vnf_p7->p7_connections[0].slot = ind.last_slot; + vnf_p7->p7_connections[0].sfn = ind.last_sfn; + vnf_p7->p7_connections[0].slot = ind.last_slot; } } } @@ -2248,7 +2248,7 @@ void vnf_handle_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) // validate the input params if(pRecvMsg == NULL || recvMsgLen < 4 || vnf_p7 == NULL) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "vnf_handle_p7_message: invalid input params (%d %d %d)\n", pRecvMsg, recvMsgLen, vnf_p7); + NFAPI_TRACE(NFAPI_TRACE_ERROR, "vnf_handle_p7_message: invalid input params (%p %d %p)\n", pRecvMsg, recvMsgLen, vnf_p7); return; } @@ -2366,7 +2366,7 @@ void vnf_nr_handle_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) // validate the input params if(pRecvMsg == NULL || recvMsgLen < 4 || vnf_p7 == NULL) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "vnf_handle_p7_message: invalid input params (%d %d %d)\n", pRecvMsg, recvMsgLen, vnf_p7); + NFAPI_TRACE(NFAPI_TRACE_ERROR, "vnf_handle_p7_message: invalid input params (%p %d %p)\n", pRecvMsg, recvMsgLen, vnf_p7); return; } @@ -2508,26 +2508,22 @@ int vnf_nr_p7_read_dispatch_message(vnf_p7_t* vnf_p7) } // read the segment - recvfrom_result = recvfrom(vnf_p7->socket, vnf_p7->rx_message_buffer, header.message_length, MSG_WAITALL, (struct sockaddr*)&remote_addr, &remote_addr_size); + recvfrom_result = recvfrom(vnf_p7->socket, vnf_p7->rx_message_buffer, header.message_length, MSG_WAITALL | MSG_TRUNC, (struct sockaddr*)&remote_addr, &remote_addr_size); + NFAPI_TRACE(NFAPI_TRACE_DEBUG, "recvfrom_result = %d from %s():%d\n", recvfrom_result, __FUNCTION__, __LINE__); // todo : how to handle incomplete readfroms, need some sort of buffer/select - if(recvfrom_result == 0) - { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "recvfrom returned 0\n"); - } - else if(recvfrom_result != header.message_length) - { - NFAPI_TRACE(NFAPI_TRACE_NOTE, "did not receive the entire message %d %d\n", recvfrom_result, header.message_length); - - recvfrom_result += recvfrom(vnf_p7->socket, &vnf_p7->rx_message_buffer[recvfrom_result], header.message_length - recvfrom_result, MSG_WAITALL, (struct sockaddr*)&remote_addr, &remote_addr_size); - - } - - - if(recvfrom_result > 0) + if (recvfrom_result > 0) { + if (recvfrom_result != header.message_length) + { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "(%d) Received unexpected number of bytes. %d != %d", + __LINE__, recvfrom_result, header.message_length); + break; + } + NFAPI_TRACE(NFAPI_TRACE_DEBUG, "Calling vnf_nr_handle_p7_message from %d\n", __LINE__); vnf_nr_handle_p7_message(vnf_p7->rx_message_buffer, recvfrom_result, vnf_p7); + return 0; } else { @@ -2592,9 +2588,9 @@ int vnf_p7_read_dispatch_message(vnf_p7_t* vnf_p7) { NFAPI_TRACE(NFAPI_TRACE_ERROR, "recvfrom returned 0\n"); } - else if(recvfrom_result != header.message_length) + else if(recvfrom_result != -1 && recvfrom_result != header.message_length) { - NFAPI_TRACE(NFAPI_TRACE_NOTE, "did not receive the entire message %d %d\n", recvfrom_result, header.message_length); + NFAPI_TRACE(NFAPI_TRACE_ERROR, "Received unexpected number of bytes %d %d\n", recvfrom_result, header.message_length); recvfrom_result += recvfrom(vnf_p7->socket, &vnf_p7->rx_message_buffer[recvfrom_result], header.message_length - recvfrom_result, MSG_WAITALL, (struct sockaddr*)&remote_addr, &remote_addr_size); @@ -2646,10 +2642,11 @@ void vnf_p7_release_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* header) case NFAPI_RX_ULSCH_INDICATION: { nfapi_rx_indication_t* rx_ind = (nfapi_rx_indication_t*)(header); - uint16_t i = 0; - for(i = 0; i < rx_ind->rx_indication_body.number_of_pdus; ++i) + size_t number_of_pdus = rx_ind->rx_indication_body.number_of_pdus; + assert(number_of_pdus <= NFAPI_RX_IND_MAX_PDU); + for(size_t i = 0; i < number_of_pdus; ++i) { - vnf_p7_codec_free(vnf_p7, rx_ind->rx_indication_body.rx_pdu_list[i].data); + vnf_p7_codec_free(vnf_p7, rx_ind->rx_indication_body.rx_pdu_list[i].rx_ind_data); } vnf_p7_codec_free(vnf_p7, rx_ind->rx_indication_body.rx_pdu_list); diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c b/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c index 8cebf2b468..852707fbbd 100644 --- a/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c +++ b/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c @@ -1,12 +1,12 @@ /* * Copyright 2017 Cisco Systems, Inc. - * + * * 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. @@ -45,13 +45,13 @@ nfapi_vnf_p7_config_t* nfapi_vnf_p7_config_create() _this->_public.segment_size = 1400; _this->_public.max_num_segments = 8; _this->_public.checksum_enabled = 1; - + _this->_public.malloc = &malloc; - _this->_public.free = &free; + _this->_public.free = &free; _this->_public.codec_config.allocate = &malloc; _this->_public.codec_config.deallocate = &free; - + return (nfapi_vnf_p7_config_t*)_this; } @@ -81,12 +81,12 @@ struct timespec timespec_add(struct timespec lhs, struct timespec rhs) struct timespec timespec_sub(struct timespec lhs, struct timespec rhs) { struct timespec result; - if ((lhs.tv_nsec-rhs.tv_nsec)<0) + if ((lhs.tv_nsec-rhs.tv_nsec)<0) { result.tv_sec = lhs.tv_sec-rhs.tv_sec-1; result.tv_nsec = 1000000000+lhs.tv_nsec-rhs.tv_nsec; - } - else + } + else { result.tv_sec = lhs.tv_sec-rhs.tv_sec; result.tv_nsec = lhs.tv_nsec-rhs.tv_nsec; @@ -94,7 +94,7 @@ struct timespec timespec_sub(struct timespec lhs, struct timespec rhs) return result; } -// monitor the p7 endpoints and the timing loop and +// monitor the p7 endpoints and the timing loop and // send indications to mac int nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t* config) { @@ -107,9 +107,9 @@ int nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t* config) vnf_p7_t* vnf_p7 = (vnf_p7_t*)config; - // Create p7 receive udp port + // Create p7 receive udp port // todo : this needs updating for Ipv6 - + NFAPI_TRACE(NFAPI_TRACE_INFO, "Initialising VNF P7 port:%u\n", config->port); // open the UDP socket @@ -128,7 +128,7 @@ int nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t* config) NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt (IP_TOS) errno: %d\n", errno); return -1; } - + NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 setsockopt succeeded...\n"); // Create the address structure @@ -168,20 +168,34 @@ int nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t* config) // Add the p7 socket FD_SET(vnf_p7->socket, &rfds); maxSock = vnf_p7->socket; - + struct timespec curr_time; clock_gettime(CLOCK_MONOTONIC, &curr_time); setup_time = curr_time.tv_sec - ref_time.tv_sec; - if(setup_time > 10 && prev_slot != gNB->UL_INFO.slot){ //Give the VNF sufficient time to setup before starting scheduling - - //Call the scheduler + nfapi_nr_slot_indication_scf_t *slot_ind = get_queue(&gnb_slot_ind_queue); + NFAPI_TRACE(NFAPI_TRACE_DEBUG, "This is the slot_ind queue size %ld in %s():%d\n", + gnb_slot_ind_queue.num_items, __FUNCTION__, __LINE__); + if (slot_ind) { pthread_mutex_lock(&gNB->UL_INFO_mutex); - gNB->UL_INFO.module_id = gNB->Mod_id; - gNB->UL_INFO.CC_id = gNB->CC_id; - gNB->if_inst->NR_UL_indication(&gNB->UL_INFO); + gNB->UL_INFO.frame = slot_ind->sfn; + gNB->UL_INFO.slot = slot_ind->slot; + + NFAPI_TRACE(NFAPI_TRACE_DEBUG, "gNB->UL_INFO.frame = %d and slot %d, prev_slot = %d, setup_time = %d\n", + gNB->UL_INFO.frame, gNB->UL_INFO.slot, prev_slot, setup_time); + if (setup_time > 3 && prev_slot != gNB->UL_INFO.slot) { //Give the VNF sufficient time to setup before starting scheduling && prev_slot != gNB->UL_INFO.slot + + //Call the scheduler + gNB->UL_INFO.module_id = gNB->Mod_id; + gNB->UL_INFO.CC_id = gNB->CC_id; + NFAPI_TRACE(NFAPI_TRACE_DEBUG, "Calling NR_UL_indication for gNB->UL_INFO.frame = %d and slot %d\n", + gNB->UL_INFO.frame, gNB->UL_INFO.slot); + gNB->if_inst->NR_UL_indication(&gNB->UL_INFO); + prev_slot = gNB->UL_INFO.slot; + } pthread_mutex_unlock(&gNB->UL_INFO_mutex); - prev_slot = gNB->UL_INFO.slot; + free(slot_ind); + slot_ind = NULL; } selectRetval = pselect(maxSock+1, &rfds, NULL, NULL, &pselect_timeout, NULL); @@ -234,9 +248,9 @@ int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config) vnf_p7_t* vnf_p7 = (vnf_p7_t*)config; - // Create p7 receive udp port + // Create p7 receive udp port // todo : this needs updating for Ipv6 - + NFAPI_TRACE(NFAPI_TRACE_INFO, "Initialising VNF P7 port:%u\n", config->port); // open the UDP socket @@ -255,7 +269,7 @@ int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config) NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt (IP_TOS) errno: %d\n", errno); return -1; } - + NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 setsockopt succeeded...\n"); // Create the address structure @@ -299,7 +313,7 @@ int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config) clock_gettime(CLOCK_MONOTONIC, &sf_start); long millisecond = sf_start.tv_nsec / 1e6; sf_start = timespec_add(sf_start, sf_duration); - NFAPI_TRACE(NFAPI_TRACE_INFO, "next subframe will start at %d.%d\n", sf_start.tv_sec, sf_start.tv_nsec); + NFAPI_TRACE(NFAPI_TRACE_INFO, "next subframe will start at %ld.%ld\n", sf_start.tv_sec, sf_start.tv_nsec); while(vnf_p7->terminate == 0) { @@ -311,7 +325,7 @@ int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config) // Add the p7 socket FD_SET(vnf_p7->socket, &rfds); maxSock = vnf_p7->socket; - + clock_gettime(CLOCK_MONOTONIC, &pselect_start); //long millisecond = pselect_start.tv_nsec / 1e6; @@ -320,7 +334,7 @@ int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config) //NFAPI_TRACE(NFAPI_TRACE_INFO, "pselect_start:%d.%d sf_start:%d.%d\n", pselect_start.tv_sec, pselect_start.tv_nsec, sf_start.tv_sec, sf_start.tv_nsec); - if((pselect_start.tv_sec > sf_start.tv_sec) || + if((pselect_start.tv_sec > sf_start.tv_sec) || ((pselect_start.tv_sec == sf_start.tv_sec) && (pselect_start.tv_nsec > sf_start.tv_nsec))) { // overran the end of the subframe we do not want to wait @@ -343,7 +357,7 @@ int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config) //pselect_timeout.tv_nsec = 1e6 - (pselect_start.tv_nsec % 1000000); //uint8_t underrun_possible =0; - + // if we are not sleeping until the next milisecond due to the // insycn minor adjment flag it so we don't consider it an error //uint8_t underrun_possible =0; @@ -353,7 +367,7 @@ int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config) if(phy && phy->in_sync && phy->insync_minor_adjustment != 0 && phy->insync_minor_adjustment_duration > 0 && pselect_start.tv_nsec != 0) { NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] Subframe minor adjustment %d (%d->%d)\n", phy->insync_minor_adjustment, - pselect_timeout.tv_nsec, pselect_timeout.tv_nsec - (phy->insync_minor_adjustment * 1000)) + pselect_timeout.tv_nsec, pselect_timeout.tv_nsec - (phy->insync_minor_adjustment * 1000)) if(phy->insync_minor_adjustment > 0) { // todo check we don't go below 0 @@ -376,7 +390,7 @@ int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config) } } */ - + //long wraps = pselect_timeout.tv_nsec % 1e9; @@ -389,9 +403,9 @@ int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config) if (selectRetval==-1 && errno == 22) { - NFAPI_TRACE(NFAPI_TRACE_ERROR, "INVAL: pselect_timeout:%d.%ld adj[dur:%d adj:%d], sf_dur:%d.%ld\n", - pselect_timeout.tv_sec, pselect_timeout.tv_nsec, - phy->insync_minor_adjustment_duration, phy->insync_minor_adjustment, + NFAPI_TRACE(NFAPI_TRACE_ERROR, "INVAL: pselect_timeout:%ld.%ld adj[dur:%d adj:%d], sf_dur:%ld.%ld\n", + pselect_timeout.tv_sec, pselect_timeout.tv_nsec, + phy->insync_minor_adjustment_duration, phy->insync_minor_adjustment, sf_duration.tv_sec, sf_duration.tv_nsec); } if(selectRetval == 0) @@ -449,7 +463,7 @@ if (selectRetval==-1 && errno == 22) //phy->insync_minor_adjustment = 0; phy->insync_minor_adjustment_duration--; - NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] AFTER adjustment - Subframe minor adjustment %dus sf_start.tv_nsec:%d duration:%u\n", + NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] AFTER adjustment - Subframe minor adjustment %dus sf_start.tv_nsec:%ld duration:%u\n", phy->insync_minor_adjustment, sf_start.tv_nsec, phy->insync_minor_adjustment_duration); if (phy->insync_minor_adjustment_duration==0) @@ -473,7 +487,7 @@ if (selectRetval==-1 && errno == 22) } last_millisecond = millisecond; */ - + millisecond ++; } } @@ -497,9 +511,7 @@ if (selectRetval==-1 && errno == 22) while(curr != 0) { curr->sfn_sf = increment_sfn_sf(curr->sfn_sf); - vnf_sync(vnf_p7, curr); - curr = curr->next; } @@ -523,7 +535,7 @@ if (selectRetval==-1 && errno == 22) } else { - NFAPI_TRACE(NFAPI_TRACE_INFO, "P7 select failed result %d errno %d timeout:%d.%d orginal:%d.%d last_ms:%ld ms:%ld\n", selectRetval, errno, pselect_timeout.tv_sec, pselect_timeout.tv_nsec, pselect_timeout.tv_sec, pselect_timeout.tv_nsec, last_millisecond, millisecond); + NFAPI_TRACE(NFAPI_TRACE_INFO, "P7 select failed result %d errno %d timeout:%ld.%ld orginal:%ld.%ld last_ms:%ld ms:%ld\n", selectRetval, errno, pselect_timeout.tv_sec, pselect_timeout.tv_nsec, pselect_timeout.tv_sec, pselect_timeout.tv_nsec, last_millisecond, millisecond); // should we exit now? if (selectRetval == -1 && errno == 22) // invalid argument??? not sure about timeout duration { @@ -534,7 +546,7 @@ if (selectRetval==-1 && errno == 22) } - + NFAPI_TRACE(NFAPI_TRACE_INFO, "Closing p7 socket\n"); close(vnf_p7->socket); diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index 1daeb72187..308a059d51 100644 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -106,7 +106,7 @@ void phy_config_request(PHY_Config_t *phy_config) { int Ncp = cfg->subframe_config.dl_cyclic_prefix_type.value; int p_eNB = cfg->rf_config.tx_antenna_ports.value; uint32_t dl_CarrierFreq = cfg->nfapi_config.earfcn.value; - LOG_I(PHY,"Configuring MIB for instance %d, CCid %d : (band %d,N_RB_DL %d, N_RB_UL %d, Nid_cell %d,eNB_tx_antenna_ports %d,Ncp %d,DL freq %u,phich_config.resource %d, phich_config.duration %d)\n", + LOG_A(PHY,"Configuring MIB for instance %d, CCid %d : (band %d,N_RB_DL %d, N_RB_UL %d, Nid_cell %d,eNB_tx_antenna_ports %d,Ncp %d,DL freq %u,phich_config.resource %d, phich_config.duration %d)\n", Mod_id, CC_id, eutra_band, dl_Bandwidth, ul_Bandwidth, Nid_cell, p_eNB,Ncp,dl_CarrierFreq, cfg->phich_config.phich_resource.value, cfg->phich_config.phich_duration.value); diff --git a/openair1/PHY/INIT/lte_init_ue.c b/openair1/PHY/INIT/lte_init_ue.c index b756735816..c3f09fa78c 100644 --- a/openair1/PHY/INIT/lte_init_ue.c +++ b/openair1/PHY/INIT/lte_init_ue.c @@ -548,7 +548,7 @@ void phy_config_dedicated_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id, phy_vars_ue->decode_MIB = 0; } - if(NFAPI_MODE!=NFAPI_UE_STUB_PNF) { + if(NFAPI_MODE!=NFAPI_UE_STUB_PNF && NFAPI_MODE!=NFAPI_MODE_STANDALONE_PNF) { //phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti; if(phy_vars_ue->pdcch_vars[0][eNB_id]->crnti == 0x1234) phy_vars_ue->pdcch_vars[0][eNB_id]->crnti = phy_vars_ue->pdcch_vars[1][eNB_id]->crnti; diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index cd4848ea8c..9e1e472fd6 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -487,7 +487,7 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) { LOG_I(PHY, "DL frequency %lu Hz, UL frequency %lu Hz: band %d, uldl offset %d Hz\n", fp->dl_CarrierFreq, fp->ul_CarrierFreq, fp->nr_band, dlul_offset); fp->threequarter_fs = openair0_cfg[0].threequarter_fs; - LOG_I(PHY,"Configuring MIB for instance %d, : (Nid_cell %d,DL freq %llu, UL freq %llu)\n", + LOG_A(PHY,"Configuring MIB for instance %d, : (Nid_cell %d,DL freq %llu, UL freq %llu)\n", Mod_id, gNB_config->cell_config.phy_cell_id.value, (unsigned long long)fp->dl_CarrierFreq, diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index aba4a464f2..c6b312cc61 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -2921,6 +2921,9 @@ int allocate_REs_in_RB_MCH_khz_1dot25(int32_t **txdataF, uint8_t skip_dc, LTE_DL_FRAME_PARMS *frame_parms) { + if (!qam_table_s) + abort(); + uint32_t tti_offset; uint8_t re,offset; uint8_t qam64_table_offset_re = 0; diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c index 6afd028099..a7054a44d2 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c @@ -370,7 +370,7 @@ int rx_pdsch(PHY_VARS_UE *ue, #if UE_TIMING_TRACE stop_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); - LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d Flag %d type %d: Pilot/Data extraction %5.2f \n",frame,subframe,slot,symbol, + LOG_D(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d Flag %d type %d: Pilot/Data extraction %5.2f \n",frame,subframe,slot,symbol, ue->high_speed_flag,type,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); #endif #if UE_TIMING_TRACE @@ -398,7 +398,7 @@ int rx_pdsch(PHY_VARS_UE *ue, #if UE_TIMING_TRACE stop_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); - LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d: Channel Scale %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); + LOG_D(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d: Channel Scale %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); start_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); #endif @@ -507,7 +507,7 @@ int rx_pdsch(PHY_VARS_UE *ue, #endif #if UE_TIMING_TRACE stop_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); - LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level %5.2f \n",frame,subframe,slot,symbol,first_symbol_flag, + LOG_D(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level %5.2f \n",frame,subframe,slot,symbol,first_symbol_flag, ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); start_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); #endif @@ -731,7 +731,7 @@ int rx_pdsch(PHY_VARS_UE *ue, #if UE_TIMING_TRACE stop_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); - LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d log2_maxh %d Channel Comp %5.2f \n",frame,subframe,slot,symbol,pdsch_vars[eNB_id]->log2_maxh, + LOG_D(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d log2_maxh %d Channel Comp %5.2f \n",frame,subframe,slot,symbol,pdsch_vars[eNB_id]->log2_maxh, ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); start_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); #endif @@ -805,7 +805,7 @@ int rx_pdsch(PHY_VARS_UE *ue, #if UE_TIMING_TRACE stop_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); - LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d: Channel Combine %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); + LOG_D(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d: Channel Combine %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0)); start_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]); #endif //printf("LLR dlsch0_harq->Qm %d rx_type %d cw0 %d cw1 %d symbol %d \n",dlsch0_harq->Qm,rx_type,codeword_TB0,codeword_TB1,symbol); diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c index 26b45eb9f7..2dc21af0c5 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c @@ -32,6 +32,7 @@ */ #include "nr_dlsch.h" +#include "../../../nfapi/oai_integration/vendor_ext.h" extern void set_taus_seed(unsigned int seed_type); diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index b81e655817..8844a530af 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -47,6 +47,7 @@ #include "PHY/NR_REFSIG/nr_refsig.h" #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" +#include "nfapi/oai_integration/vendor_ext.h" #include "nfapi/oai_integration/vendor_ext.h" @@ -88,7 +89,8 @@ void nr_fill_pucch(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_pucch_pdu_t *pucch_pdu) { - + if (NFAPI_MODE == NFAPI_MODE_PNF) + gNB->pucch[0]->active = 0; //check if ture in monolithic mode int id = nr_find_pucch(pucch_pdu->rnti,frame,slot,gNB); AssertFatal( (id>=0) && (idrnti,id); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c index 9c2c5e5746..dff347f7c0 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c @@ -601,11 +601,11 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, #endif nr_downlink_indication_t dl_indication; - fapi_nr_rx_indication_t rx_ind; + fapi_nr_rx_indication_t *rx_ind = calloc(1, sizeof(*rx_ind)); uint16_t number_pdus = 1; - nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, gNB_id); - nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, gNB_id, ue, NULL, NULL, number_pdus, proc); + nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id); + nr_fill_rx_indication(rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, gNB_id, ue, NULL, NULL, number_pdus, proc); if (ue->if_inst && ue->if_inst->dl_indication) ue->if_inst->dl_indication(&dl_indication, NULL); diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c index 303ec5121d..44adf02f57 100644 --- a/openair1/PHY/TOOLS/nr_phy_scope.c +++ b/openair1/PHY/TOOLS/nr_phy_scope.c @@ -240,7 +240,7 @@ static void genericWaterFall (OAIgraph_t *graph, scopeSample_t *values, const in for (int pix=0; pixw; pix++) { scopeSample_t *end=values+(pix+1)*samplesPerPixel; end-=2; - AssertFatal(end <= values+datasize,"diff : %ld", end-values+datasize); + AssertFatal(end <= values+datasize,"diff : %tu", end-values+datasize); double val=0; for (scopeSample_t *s=values+(pix)*samplesPerPixel; diff --git a/openair1/PHY/phy_vars.h b/openair1/PHY/phy_vars.h index 5879784827..9fd186ec4f 100644 --- a/openair1/PHY/phy_vars.h +++ b/openair1/PHY/phy_vars.h @@ -24,6 +24,7 @@ #include "PHY/types.h" #include "PHY/defs_eNB.h" +#include "PHY/defs_gNB.h" #include "PHY/defs_UE.h" char* namepointer_chMag ; @@ -42,6 +43,7 @@ char* namepointer_log2; PHY_VARS_UE ***PHY_vars_UE_g; UL_RCC_IND_t UL_RCC_INFO; +NR_UL_IND_t UL_INFO; unsigned short rev[2048],rev_times4[8192],rev_half[1024]; unsigned short rev256[256],rev512[512],rev1024[1024],rev4096[4096],rev2048[2048],rev8192[8192]; @@ -81,7 +83,7 @@ const double sinr_to_cqi[4][16]= { {-2.5051, -2.5051, -1.7451, -0.3655, 1.0812, }; //int cqi_to_mcs[16]={0, 0, 1, 3, 5, 7, 9, 13, 15, 16, 20, 23, 25, 27, 27, 27}; -const int cqi_to_mcs[16]= {0, 0, 1, 2, 4, 6, 8, 11, 13, 16, 18, 20, 23, 25, 27, 28}; +const int cqi_to_mcs[16]= {0, 0, 1, 2, 4, 6, 8, 11, 13, 16, 18, 20, 23, 25, 27, 27}; //for SNR to MI conversion 7 th order Polynomial coeff const double q_qam16[8]= {3.21151853033897e-10,5.55435952230651e-09,-2.30760065362117e-07,-6.25587743817859e-06,4.62251036452795e-06,0.00224150813158937,0.0393723140344367,0.245486379182639}; diff --git a/openair1/PHY/phy_vars_nr_ue.h b/openair1/PHY/phy_vars_nr_ue.h index cfdfbeb49d..303853add2 100644 --- a/openair1/PHY/phy_vars_nr_ue.h +++ b/openair1/PHY/phy_vars_nr_ue.h @@ -84,7 +84,7 @@ const double sinr_to_cqi[4][16]= { {-2.5051, -2.5051, -1.7451, -0.3655, 1.0812, }; //int cqi_to_mcs[16]={0, 0, 1, 3, 5, 7, 9, 13, 15, 16, 20, 23, 25, 27, 27, 27}; -const int cqi_to_mcs[16]= {0, 0, 1, 2, 4, 6, 8, 11, 13, 16, 18, 20, 23, 25, 27, 28}; +const int cqi_to_mcs[16]= {0, 0, 1, 2, 4, 6, 8, 11, 13, 16, 18, 20, 23, 25, 27, 27}; //for SNR to MI conversion 7 th order Polynomial coeff const double q_qam16[8]= {3.21151853033897e-10,5.55435952230651e-09,-2.30760065362117e-07,-6.25587743817859e-06,4.62251036452795e-06,0.00224150813158937,0.0393723140344367,0.245486379182639}; diff --git a/openair1/PHY/phy_vars_ue.h b/openair1/PHY/phy_vars_ue.h index ca35ab6629..2c1334b80b 100644 --- a/openair1/PHY/phy_vars_ue.h +++ b/openair1/PHY/phy_vars_ue.h @@ -73,7 +73,7 @@ const double sinr_to_cqi[4][16]= { {-2.5051, -2.5051, -1.7451, -0.3655, 1.0812, }; //int cqi_to_mcs[16]={0, 0, 1, 3, 5, 7, 9, 13, 15, 16, 20, 23, 25, 27, 27, 27}; -const int cqi_to_mcs[16]= {0, 0, 1, 2, 4, 6, 8, 11, 13, 16, 18, 20, 23, 25, 27, 28}; +const int cqi_to_mcs[16]= {0, 0, 1, 2, 4, 6, 8, 11, 13, 16, 18, 20, 23, 25, 27, 27}; //for SNR to MI conversion 7 th order Polynomial coeff const double q_qam16[8]= {3.21151853033897e-10,5.55435952230651e-09,-2.30760065362117e-07,-6.25587743817859e-06,4.62251036452795e-06,0.00224150813158937,0.0393723140344367,0.245486379182639}; diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 973c921d23..569d2a464a 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -755,6 +755,7 @@ void fill_sr_indication(int UEid, PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int pthread_mutex_lock(&eNB->UL_INFO_mutex); nfapi_sr_indication_t *sr_ind = &eNB->UL_INFO.sr_ind; nfapi_sr_indication_body_t *sr_ind_body = &sr_ind->sr_indication_body; + assert(sr_ind_body->number_of_srs <= NFAPI_SR_IND_MAX_PDU); nfapi_sr_indication_pdu_t *pdu = &sr_ind_body->sr_pdu_list[sr_ind_body->number_of_srs]; sr_ind->sfn_sf = frame<<4|subframe; sr_ind->header.message_id = NFAPI_RX_SR_INDICATION; @@ -1580,6 +1581,7 @@ void fill_rx_indication(PHY_VARS_eNB *eNB, pthread_mutex_lock(&eNB->UL_INFO_mutex); eNB->UL_INFO.rx_ind.sfn_sf = frame<<4| subframe; eNB->UL_INFO.rx_ind.rx_indication_body.tl.tag = NFAPI_RX_INDICATION_BODY_TAG; + assert(eNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus <= NFAPI_RX_IND_MAX_PDU); pdu = &eNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list[eNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus]; // pdu->rx_ue_information.handle = eNB->ulsch[ULSCH_id]->handle; pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; @@ -1587,7 +1589,11 @@ void fill_rx_indication(PHY_VARS_eNB *eNB, pdu->rx_indication_rel8.tl.tag = NFAPI_RX_INDICATION_REL8_TAG; pdu->rx_indication_rel8.length = eNB->ulsch[ULSCH_id]->harq_processes[harq_pid]->TBS>>3; pdu->rx_indication_rel8.offset = 1; // DJP - I dont understand - but broken unless 1 ???? 0; // filled in at the end of the UL_INFO formation - pdu->data = eNB->ulsch[ULSCH_id]->harq_processes[harq_pid]->decodedBytes; + assert(pdu->rx_indication_rel8.length <= NFAPI_RX_IND_DATA_MAX); + memcpy(pdu->rx_ind_data, + eNB->ulsch[ULSCH_id]->harq_processes[harq_pid]->decodedBytes, + pdu->rx_indication_rel8.length); + // estimate timing advance for MAC sync_pos = lte_est_timing_advance_pusch(&eNB->frame_parms, eNB->pusch_vars[ULSCH_id]->drs_ch_estimates_time); timing_advance_update = sync_pos; @@ -1832,6 +1838,7 @@ int getM(PHY_VARS_eNB *eNB,int frame,int subframe) { void fill_ulsch_cqi_indication (PHY_VARS_eNB *eNB, uint16_t frame, uint8_t subframe, LTE_UL_eNB_HARQ_t *ulsch_harq, uint16_t rnti) { pthread_mutex_lock (&eNB->UL_INFO_mutex); + assert(eNB->UL_INFO.cqi_ind.cqi_indication_body.number_of_cqis <= NFAPI_CQI_IND_MAX_PDU); nfapi_cqi_indication_pdu_t *pdu = &eNB->UL_INFO.cqi_ind.cqi_indication_body.cqi_pdu_list[eNB->UL_INFO.cqi_ind.cqi_indication_body.number_of_cqis]; nfapi_cqi_indication_raw_pdu_t *raw_pdu = &eNB->UL_INFO.cqi_ind.cqi_indication_body.cqi_raw_pdu_list[eNB->UL_INFO.cqi_ind.cqi_indication_body.number_of_cqis]; pdu->instance_length = 0; @@ -1878,6 +1885,7 @@ void fill_ulsch_harq_indication (PHY_VARS_eNB *eNB, LTE_UL_eNB_HARQ_t *ulsch_har //AssertFatal(DLSCH_id>=0,"DLSCH_id doesn't exist\n"); pthread_mutex_lock(&eNB->UL_INFO_mutex); + assert(eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs <= NFAPI_HARQ_IND_MAX_PDU); nfapi_harq_indication_pdu_t *pdu = &eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list[eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs]; int M; int i; @@ -1948,6 +1956,7 @@ void fill_uci_harq_indication (int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, in pthread_mutex_lock(&eNB->UL_INFO_mutex); nfapi_harq_indication_t *ind = &eNB->UL_INFO.harq_ind; nfapi_harq_indication_body_t *body = &ind->harq_indication_body; + assert(eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs <= NFAPI_HARQ_IND_MAX_PDU); nfapi_harq_indication_pdu_t *pdu = &body->harq_pdu_list[eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs]; ind->sfn_sf = frame<<4|subframe; ind->header.message_id = NFAPI_HARQ_INDICATION; @@ -2124,6 +2133,7 @@ void fill_uci_harq_indication (int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, in void fill_crc_indication (PHY_VARS_eNB *eNB, int ULSCH_id, int frame, int subframe, uint8_t crc_flag) { pthread_mutex_lock(&eNB->UL_INFO_mutex); + assert(eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs <= NFAPI_CRC_IND_MAX_PDU); nfapi_crc_indication_pdu_t *pdu = &eNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list[eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs]; eNB->UL_INFO.crc_ind.sfn_sf = frame<<4 | subframe; eNB->UL_INFO.crc_ind.header.message_id = NFAPI_CRC_INDICATION; diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c index 8f315ba214..782c707857 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.c +++ b/openair1/SCHED_NR/fapi_nr_l1.c @@ -149,16 +149,15 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ gNB = RC.gNB[Mod_id]; - notifiedFIFO_elt_t *res; - res = pullTpool(gNB->resp_L1_tx, gNB->threadPool); - processingData_L1tx_t *msgTx = (processingData_L1tx_t *)NotifiedFifoData(res); - uint8_t number_dl_pdu = (DL_req==NULL) ? 0 : DL_req->dl_tti_request_body.nPDUs; uint8_t number_ul_dci_pdu = (UL_dci_req==NULL) ? 0 : UL_dci_req->numPdus; uint8_t number_ul_tti_pdu = (UL_tti_req==NULL) ? 0 : UL_tti_req->n_pdus; uint8_t number_tx_data_pdu = (TX_req == NULL) ? 0 : TX_req->Number_of_PDUs; if (NFAPI_MODE == NFAPI_MONOLITHIC){ + notifiedFIFO_elt_t *res; + res = pullTpool(gNB->resp_L1_tx, gNB->threadPool); + processingData_L1tx_t *msgTx = (processingData_L1tx_t *)NotifiedFifoData(res); if (DL_req != NULL && TX_req!=NULL && (number_dl_pdu > 0 || number_ul_dci_pdu > 0 || number_ul_tti_pdu > 0)) LOG_D(PHY,"NFAPI: Sched_INFO:SFN/SLOT:%04d/%d DL_req:SFN/SLO:%04d/%d:dl_pdu:%d tx_req:SFN/SLOT:%04d/%d:pdus:%d;ul_dci %d ul_tti %d\n", frame,slot, @@ -241,12 +240,12 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ if (number_ul_dci_pdu>0) oai_nfapi_ul_dci_req(UL_dci_req); - if (number_dl_pdu>0) - oai_nfapi_dl_tti_req(DL_req); - if (number_tx_data_pdu>0) oai_nfapi_tx_data_req(TX_req); - } + if (number_dl_pdu>0) + oai_nfapi_dl_tti_req(DL_req); + } + } diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 792667d510..9e5a8a536b 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -456,6 +456,7 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, if (0/*pusch_pdu->mcs_index == 9*/) { + __attribute__((unused)) #ifdef __AVX2__ int off = ((pusch_pdu->rb_size&1) == 1)? 4:0; #else @@ -660,6 +661,8 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { for (int i=0;ipucch[i]; if (pucch) { + if (NFAPI_MODE == NFAPI_MODE_PNF) + pucch->frame = frame_rx; if ((pucch->active == 1) && (pucch->frame == frame_rx) && (pucch->slot == slot_rx) ) { diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index 6848101a27..f67c84a07c 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -39,11 +39,176 @@ #include "PHY/defs_nr_UE.h" #include "PHY/impl_defs_nr.h" +#include "utils.h" extern PHY_VARS_NR_UE ***PHY_vars_UE_g; const char *dl_pdu_type[]={"DCI", "DLSCH", "RA_DLSCH", "SI_DLSCH", "P_DLSCH"}; const char *ul_pdu_type[]={"PRACH", "PUCCH", "PUSCH", "SRS"}; +queue_t nr_rx_ind_queue; +queue_t nr_crc_ind_queue; +queue_t nr_uci_ind_queue; + +int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response) { + + if(scheduled_response != NULL) + { + if (scheduled_response->ul_config != NULL) + { + fapi_nr_ul_config_request_t *ul_config = scheduled_response->ul_config; + AssertFatal(ul_config->number_pdus < sizeof(ul_config->ul_config_list) / sizeof(ul_config->ul_config_list[0]), + "Too many ul_config pdus %d", ul_config->number_pdus); + for (int i = 0; i < ul_config->number_pdus; ++i) + { + LOG_I(PHY, "In %s: processing type %d PDU of %d total UL PDUs (ul_config %p) \n", + __FUNCTION__, ul_config->ul_config_list[i].pdu_type, ul_config->number_pdus, ul_config); + + uint8_t pdu_type = ul_config->ul_config_list[i].pdu_type; + switch (pdu_type) + { + case (FAPI_NR_UL_CONFIG_TYPE_PUSCH): + { + nfapi_nr_rx_data_indication_t *rx_ind = CALLOC(1, sizeof(*rx_ind)); + nfapi_nr_crc_indication_t *crc_ind = CALLOC(1, sizeof(*crc_ind)); + nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[i].pusch_config_pdu; + if (scheduled_response->tx_request) + { + AssertFatal(scheduled_response->tx_request->number_of_pdus < + sizeof(scheduled_response->tx_request->tx_request_body) / sizeof(scheduled_response->tx_request->tx_request_body[0]), + "Too many tx_req pdus %d", scheduled_response->tx_request->number_of_pdus); + rx_ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION; + rx_ind->sfn = scheduled_response->ul_config->sfn; + rx_ind->slot = scheduled_response->ul_config->slot; + rx_ind->number_of_pdus = scheduled_response->tx_request->number_of_pdus; + rx_ind->pdu_list = CALLOC(rx_ind->number_of_pdus, sizeof(*rx_ind->pdu_list)); + for (int j = 0; j < rx_ind->number_of_pdus; j++) + { + fapi_nr_tx_request_body_t *tx_req_body = &scheduled_response->tx_request->tx_request_body[j]; + rx_ind->pdu_list[j].handle = pusch_config_pdu->handle; + rx_ind->pdu_list[j].harq_id = pusch_config_pdu->pusch_data.harq_process_id; + rx_ind->pdu_list[j].pdu_length = tx_req_body->pdu_length; + rx_ind->pdu_list[j].pdu = CALLOC(tx_req_body->pdu_length, sizeof(*rx_ind->pdu_list[j].pdu)); + memcpy(rx_ind->pdu_list[j].pdu, tx_req_body->pdu, tx_req_body->pdu_length * sizeof(*rx_ind->pdu_list[j].pdu)); + rx_ind->pdu_list[j].rnti = pusch_config_pdu->rnti; + rx_ind->pdu_list[j].timing_advance = scheduled_response->tx_request->tx_config.timing_advance; + rx_ind->pdu_list[j].ul_cqi = scheduled_response->tx_request->tx_config.ul_cqi; + char buffer[1024]; + hexdump(rx_ind->pdu_list[j].pdu, rx_ind->pdu_list[j].pdu_length, buffer, sizeof(buffer)); + LOG_D(NR_MAC, "Hexdump of pdu %s before queuing rx_ind\n", + buffer); + } + + crc_ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION; + crc_ind->number_crcs = scheduled_response->ul_config->number_pdus; + crc_ind->sfn = scheduled_response->ul_config->sfn; + crc_ind->slot = scheduled_response->ul_config->slot; + crc_ind->crc_list = CALLOC(crc_ind->number_crcs, sizeof(*crc_ind->crc_list)); + for (int j = 0; j < crc_ind->number_crcs; j++) + { + crc_ind->crc_list[j].handle = pusch_config_pdu->handle; + crc_ind->crc_list[j].harq_id = pusch_config_pdu->pusch_data.harq_process_id; + LOG_D(NR_MAC, "This is the harq pid %d for crc_list[%d]\n", crc_ind->crc_list[j].harq_id, j); + LOG_D(NR_MAC, "This is sched sfn/sl [%d %d] and crc sfn/sl [%d %d]\n", + scheduled_response->frame, scheduled_response->slot, crc_ind->sfn, crc_ind->slot); + crc_ind->crc_list[j].num_cb = pusch_config_pdu->pusch_data.num_cb; + crc_ind->crc_list[j].rnti = pusch_config_pdu->rnti; + crc_ind->crc_list[j].tb_crc_status = 0; + crc_ind->crc_list[j].timing_advance = scheduled_response->tx_request->tx_config.timing_advance; + crc_ind->crc_list[j].ul_cqi = 255; + } + + if (!put_queue(&nr_rx_ind_queue, rx_ind)) + { + LOG_E(NR_MAC, "Put_queue failed for rx_ind\n"); + for (int i = 0; i < rx_ind->number_of_pdus; i++) + { + free(rx_ind->pdu_list[i].pdu); + rx_ind->pdu_list[i].pdu = NULL; + } + + free(rx_ind->pdu_list); + rx_ind->pdu_list = NULL; + free(rx_ind); + rx_ind = NULL; + } + if (!put_queue(&nr_crc_ind_queue, crc_ind)) + { + LOG_E(NR_MAC, "Put_queue failed for crc_ind\n"); + free(crc_ind->crc_list); + crc_ind->crc_list = NULL; + free(crc_ind); + crc_ind = NULL; + } + + LOG_D(PHY, "In %s: Filled queue rx/crc_ind which was filled by ulconfig. \n", __FUNCTION__); + + scheduled_response->tx_request->number_of_pdus = 0; + } + break; + } + + default: + LOG_I(NR_MAC, "Unknown ul_config->pdu_type %d\n", pdu_type); + break; + } + } + scheduled_response->ul_config->number_pdus = 0; + } + + if (scheduled_response->dl_config != NULL) + { + fapi_nr_dl_config_request_t *dl_config = scheduled_response->dl_config; + AssertFatal(dl_config->number_pdus < sizeof(dl_config->dl_config_list) / sizeof(dl_config->dl_config_list[0]), + "Too many dl_config pdus %d", dl_config->number_pdus); + for (int i = 0; i < dl_config->number_pdus; ++i) + { + LOG_D(PHY, "In %s: processing %s PDU of %d total DL PDUs (dl_config %p) \n", + __FUNCTION__, dl_pdu_type[dl_config->dl_config_list[i].pdu_type - 1], dl_config->number_pdus, dl_config); + + uint8_t pdu_type = dl_config->dl_config_list[i].pdu_type; + switch (pdu_type) + { + case (FAPI_NR_DL_CONFIG_TYPE_DLSCH): + { + nfapi_nr_uci_indication_t *uci_ind = CALLOC(1, sizeof(*uci_ind)); + uci_ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION; + uci_ind->sfn = scheduled_response->frame; + uci_ind->slot = scheduled_response->slot; + uci_ind->num_ucis = 1; + uci_ind->uci_list = CALLOC(uci_ind->num_ucis, sizeof(*uci_ind->uci_list)); + for (int j = 0; j < uci_ind->num_ucis; j++) + { + nfapi_nr_uci_pucch_pdu_format_0_1_t *pdu_0_1 = &uci_ind->uci_list[j].pucch_pdu_format_0_1; + uci_ind->uci_list[j].pdu_type = NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE; + uci_ind->uci_list[j].pdu_size = sizeof(nfapi_nr_uci_pucch_pdu_format_0_1_t); + memset(pdu_0_1, 0, sizeof(*pdu_0_1)); + pdu_0_1->handle = 0; + pdu_0_1->rnti = dl_config->dl_config_list[i].dlsch_config_pdu.rnti; + pdu_0_1->pucch_format = 1; + pdu_0_1->ul_cqi = 255; + pdu_0_1->timing_advance = 0; + pdu_0_1->rssi = 0; + } + + LOG_I(NR_PHY, "In %s: Filled queue uci_ind which was filled by dlconfig.\n" + "uci_num %d, SFN/SLOT: [%d, %d]\n", + __FUNCTION__, uci_ind->num_ucis, uci_ind->sfn, uci_ind->slot); + + if (!put_queue(&nr_uci_ind_queue, uci_ind)) + { + LOG_E(NR_MAC, "Put_queue failed for uci_ind\n"); + free(uci_ind->uci_list); + free(uci_ind); + } + break; + } + } + } + } + + } + return 0; +} int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.h b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.h index 0cd882a9b5..a0b0b805af 100755 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.h +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.h @@ -34,11 +34,15 @@ #define __FAPI_NR_UE_L1_H__ #include "NR_IF_Module.h" +#include "openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h" +#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h" /**\brief NR UE FAPI-like P7 messages, scheduled response from L2 indicating L1 \param scheduled_response including transmission config(dl_config, ul_config) and data transmission (tx_req)*/ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response); +int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response); + /**\brief NR UE FAPI-like P5 message, physical configuration from L2 to configure L1 \param scheduled_response including transmission config(dl_config, ul_config) and data transmission (tx_req)*/ int8_t nr_ue_phy_config_request(nr_phy_config_t *phy_config); diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index ca3a09c919..e403c7410b 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -489,7 +489,7 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, int frame_rx = proc->frame_rx; int nr_slot_rx = proc->nr_slot_rx; unsigned int dci_cnt=0; - fapi_nr_dci_indication_t dci_ind = {0}; + fapi_nr_dci_indication_t *dci_ind = calloc(1, sizeof(*dci_ind)); nr_downlink_indication_t dl_indication; NR_UE_PDCCH *pdcch_vars = ue->pdcch_vars[proc->thread_id][gNB_id]; @@ -688,7 +688,7 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, n_ss); #endif - dci_cnt = nr_dci_decoding_procedure(ue, proc, &dci_ind, rel15); + dci_cnt = nr_dci_decoding_procedure(ue, proc, dci_ind, rel15); #ifdef NR_PDCCH_SCHED_DEBUG LOG_I(PHY,"<-NR_PDCCH_PHY_PROCEDURES_LTE_UE (nr_ue_pdcch_procedures)-> Ending function nr_dci_decoding_procedure() -> dci_cnt=%u\n",dci_cnt); @@ -702,12 +702,12 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, ue->Mod_id,frame_rx%1024,nr_slot_rx,nr_mode_string[ue->UE_mode[gNB_id]], i + 1, dci_cnt, - dci_ind.dci_list[i].rnti, - dci_ind.dci_list[i].dci_format); + dci_ind->dci_list[i].rnti, + dci_ind->dci_list[i].dci_format); } ue->pdcch_vars[proc->thread_id][gNB_id]->dci_received += dci_cnt; - dci_ind.number_of_dcis = dci_cnt; + dci_ind->number_of_dcis = dci_cnt; /* for (int i=0; iif_inst->dl_indication(&dl_indication, NULL); @@ -884,7 +884,7 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, NR_UE_PDSCH *pdsch_vars; uint16_t dmrs_len = get_num_dmrs(dlsch0->harq_processes[dlsch0->current_harq_pid]->dlDmrsSymbPos); nr_downlink_indication_t dl_indication; - fapi_nr_rx_indication_t rx_ind; + fapi_nr_rx_indication_t *rx_ind = calloc(1, sizeof(*rx_ind)); uint16_t number_pdus = 1; // params for UL time alignment procedure NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &ue->ul_time_alignment[gNB_id]; @@ -1013,17 +1013,17 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, switch (pdsch) { case RA_PDSCH: - nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, gNB_id); - nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_RAR, gNB_id, ue, dlsch0, NULL, number_pdus, proc); + nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id); + nr_fill_rx_indication(rx_ind, FAPI_NR_RX_PDU_TYPE_RAR, gNB_id, ue, dlsch0, NULL, number_pdus, proc); ue->UE_mode[gNB_id] = RA_RESPONSE; break; case PDSCH: - nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, gNB_id); - nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_DLSCH, gNB_id, ue, dlsch0, NULL, number_pdus, proc); + nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id); + nr_fill_rx_indication(rx_ind, FAPI_NR_RX_PDU_TYPE_DLSCH, gNB_id, ue, dlsch0, NULL, number_pdus, proc); break; case SI_PDSCH: - nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, gNB_id); - nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SIB, gNB_id, ue, dlsch0, NULL, number_pdus, proc); + nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id); + nr_fill_rx_indication(rx_ind, FAPI_NR_RX_PDU_TYPE_SIB, gNB_id, ue, dlsch0, NULL, number_pdus, proc); break; default: break; diff --git a/openair1/SCHED_UE/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c index 5f8269c513..4635f2b741 100644 --- a/openair1/SCHED_UE/phy_procedures_lte_ue.c +++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c @@ -3193,7 +3193,7 @@ void ue_pdsch_procedures(PHY_VARS_UE *ue, slot = 1; stop_meas(&ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot]); - LOG_I(PHY, "[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",proc->frame_rx,subframe_rx,m,ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot].p_time/(cpuf*1000.0)); + LOG_D(PHY, "[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",proc->frame_rx,subframe_rx,m,ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot].p_time/(cpuf*1000.0)); } if(first_symbol_flag) { @@ -3686,6 +3686,7 @@ void *UE_thread_slot1_dl_processing(void *arg) { if ( (proc->sub_frame_start+1)%RX_NB_TH == 1 && threads.slot1_proc_two != -1 ) CPU_SET(threads.slot1_proc_two, &cpuset); + // cppcheck-suppress moduloAlwaysTrueFalse if ( (proc->sub_frame_start+1)%RX_NB_TH == 2 && threads.slot1_proc_three != -1 ) CPU_SET(threads.slot1_proc_three, &cpuset); @@ -3825,7 +3826,7 @@ void *UE_thread_slot1_dl_processing(void *arg) { if ( LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1]); - LOG_I(PHY, "[AbsSFN %d.%d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0)); + LOG_D(PHY, "[AbsSFN %d.%d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0)); } //wait until pdcch is decoded @@ -3919,7 +3920,7 @@ void *UE_thread_slot1_dl_processing(void *arg) { if ( LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][1]); - LOG_I(PHY, "[AbsSFN %d.%d] Slot1: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0)); + LOG_D(PHY, "[AbsSFN %d.%d] Slot1: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0)); } if (pthread_mutex_lock(&proc->mutex_slot1_dl_processing) != 0) { @@ -4145,7 +4146,7 @@ int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue, LOG_E(PHY,"[UE %d] Frame %d, subframe %d: Error in pdcch procedures\n",ue->Mod_id,frame_rx,subframe_rx); if (LOG_DEBUGFLAG(UE_TIMING)) { - LOG_I(PHY, "[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); + LOG_D(PHY, "[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); } //proc->dci_slot0_available = 1; @@ -4155,7 +4156,7 @@ int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue, //proc->dci_slot0_available=1; if (LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]]); - LOG_I(PHY, "[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); + LOG_D(PHY, "[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); } } @@ -4164,7 +4165,7 @@ int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue, // first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH) if (LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0]); - LOG_I(PHY, "[AbsSFN %d.%d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",frame_rx,subframe_rx, + LOG_D(PHY, "[AbsSFN %d.%d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",frame_rx,subframe_rx, ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0)); } @@ -4178,7 +4179,7 @@ int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue, if (LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->ue_front_end_stat[ue->current_thread_id[subframe_rx]]); - LOG_I(PHY, "[AbsSFN %d.%d] FULL FE Processing %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0)); + LOG_D(PHY, "[AbsSFN %d.%d] FULL FE Processing %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0)); } /**** End Subframe FE Processing ****/ @@ -4266,7 +4267,7 @@ int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue, if (LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0]); - LOG_I(PHY, "[AbsSFN %d.%d] Slot0: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0)); + LOG_D(PHY, "[AbsSFN %d.%d] Slot0: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0)); } //wait until LLR Slot1 is done @@ -4279,7 +4280,7 @@ int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue, if (LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]); - LOG_I(PHY, "[AbsSFN %d.%d] Full LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); + LOG_D(PHY, "[AbsSFN %d.%d] Full LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); } //=====================================================================// @@ -4351,7 +4352,7 @@ int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue, if (LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]); - LOG_I(PHY, "[AbsSFN %d.%d] Channel Decoder: %5.2f \n",frame_rx,subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); + LOG_D(PHY, "[AbsSFN %d.%d] Channel Decoder: %5.2f \n",frame_rx,subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); } // duplicate harq structure diff --git a/openair1/SCHED_UE/pusch_pc.c b/openair1/SCHED_UE/pusch_pc.c index 503d73005f..55c8c7c547 100644 --- a/openair1/SCHED_UE/pusch_pc.c +++ b/openair1/SCHED_UE/pusch_pc.c @@ -115,7 +115,7 @@ void pusch_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_ } int8_t get_PHR(uint8_t Mod_id, uint8_t CC_id,uint8_t eNB_index) { - if(NFAPI_MODE!=NFAPI_UE_STUB_PNF) + if(NFAPI_MODE!=NFAPI_UE_STUB_PNF && NFAPI_MODE!=NFAPI_MODE_STANDALONE_PNF) return PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->PHR; else return 40; // l1l2 simulator => ideal conditions diff --git a/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c b/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c index 481f5ee0dd..5337447678 100644 --- a/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c +++ b/openair1/SIMULATION/ETH_TRANSPORT/netlink_init.c @@ -56,7 +56,7 @@ struct nlmsghdr *nas_nlh_rx = NULL; struct iovec nas_iov_tx; struct iovec nas_iov_rx = {nl_rx_buf, sizeof(nl_rx_buf)}; -int nas_sock_fd[MAX_MOBILES_PER_ENB]; +int nas_sock_fd[MAX_MOBILES_PER_ENB*2]; //Allocated for both LTE UE and NR UE. int nas_sock_mbms_fd; @@ -95,11 +95,16 @@ static int tun_alloc(char *dev) { } -int netlink_init_mbms_tun(char *ifprefix) { +int netlink_init_mbms_tun(char *ifprefix, int id) {//for UE, id = 1, 2, ..., int ret; char ifname[64]; - sprintf(ifname, "oaitun_%.3s1",ifprefix); // added "1": for historical reasons + if (id > 0) { + sprintf(ifname, "oaitun_%.3s%d", ifprefix, id-1); + } + else { + sprintf(ifname, "oaitun_%.3s1", ifprefix); // added "1": for historical reasons + } nas_sock_mbms_fd = tun_alloc(ifname); if (nas_sock_mbms_fd == -1) { @@ -123,14 +128,17 @@ int netlink_init_mbms_tun(char *ifprefix) { nas_src_addr.nl_pid = 1;//getpid(); /* self pid */ nas_src_addr.nl_groups = 0; /* not in mcast groups */ ret = bind(nas_sock_mbms_fd, (struct sockaddr *)&nas_src_addr, sizeof(nas_src_addr)); + return 1; } -int netlink_init_tun(char *ifprefix, int num_if) { +int netlink_init_tun(char *ifprefix, int num_if, int id) {//for UE, id = 1, 2, ..., int ret; char ifname[64]; - for (int i = 0; i < num_if; i++) { + int begx = (id == 0) ? 0 : id - 1; + int endx = (id == 0) ? num_if : id; + for (int i = begx; i < endx; i++) { sprintf(ifname, "oaitun_%.3s%d",ifprefix,i+1); nas_sock_fd[i] = tun_alloc(ifname); @@ -189,6 +197,7 @@ int netlink_init(void) { nas_dest_addr.nl_pid = 0; /* For Linux Kernel */ nas_dest_addr.nl_groups = 0; /* unicast */ // TX PART + free(nas_nlh_tx); nas_nlh_tx=(struct nlmsghdr *)malloc(NLMSG_SPACE(NL_MAX_PAYLOAD)); memset(nas_nlh_tx, 0, NLMSG_SPACE(NL_MAX_PAYLOAD)); /* Fill the netlink message header */ @@ -211,3 +220,8 @@ int netlink_init(void) { return(nas_sock_fd[0]); } +void netlink_cleanup(void) +{ + free(nas_nlh_tx); + nas_nlh_tx = NULL; +} diff --git a/openair1/SIMULATION/ETH_TRANSPORT/proto.h b/openair1/SIMULATION/ETH_TRANSPORT/proto.h index e6159199d4..bc6990ac3e 100644 --- a/openair1/SIMULATION/ETH_TRANSPORT/proto.h +++ b/openair1/SIMULATION/ETH_TRANSPORT/proto.h @@ -62,7 +62,8 @@ int multicast_link_read_data_from_sock(uint8_t eNB_flag); void clear_eNB_transport_info(uint8_t); void clear_UE_transport_info(uint8_t); int netlink_init(void); -int netlink_init_tun(char *ifsuffix, int num_if); -int netlink_init_mbms_tun(char *ifsuffix); +int netlink_init_tun(char *ifsuffix, int num_if, int id); +int netlink_init_mbms_tun(char *ifsuffix, int id); +void netlink_cleanup(void); #endif /* EMU_PROTO_H_ */ diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index 1169b8ecd8..2413a86912 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -193,6 +193,7 @@ int main(int argc, char **argv) int frame=0; int frame_length_complex_samples; + __attribute__((unused)) int frame_length_complex_samples_no_prefix; NR_DL_FRAME_PARMS *frame_parms; diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 380189776a..db8d54f86d 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -1281,8 +1281,10 @@ int main(int argc, char **argv) if (n_trials == 1 && round==0) { #ifdef __AVX2__ + __attribute__((unused)) int off = ((nb_rb&1) == 1)? 4:0; #else + __attribute__((unused)) int off = 0; #endif diff --git a/openair1/SIMULATION/TOOLS/taus.c b/openair1/SIMULATION/TOOLS/taus.c index cdd4aebec3..a9d2750c06 100644 --- a/openair1/SIMULATION/TOOLS/taus.c +++ b/openair1/SIMULATION/TOOLS/taus.c @@ -21,10 +21,12 @@ #include #include +#include +#include //#include "SIMULATION/TOOLS/sim.h" -unsigned int s0, s1, s2, b; +static unsigned int s0, s1, s2; //---------------------------------------------- // @@ -34,7 +36,7 @@ unsigned int s0, s1, s2, b; unsigned int taus(void) { - b = (((s0 << 13) ^ s0) >> 19); + unsigned int b = (((s0 << 13) ^ s0) >> 19); s0 = (((s0 & 0xFFFFFFFE) << 12)^ b); b = (((s1 << 2) ^ s1) >> 25); s1 = (((s1 & 0xFFFFFFF8) << 4)^ b); @@ -50,9 +52,20 @@ void set_taus_seed(unsigned int seed_init) unsigned long result = 0; if (seed_init == 0) { - s0 = (unsigned int)time(NULL); - s1 = (unsigned int)time(NULL); - s2 = (unsigned int)time(NULL); + unsigned int data[3]; + int fd = open("/dev/urandom", O_RDONLY); + if (fd == -1) + { + abort(); + } + if (read(fd, data, sizeof(data)) != sizeof(data)) + { + abort(); + } + close(fd); + s0 = data[0]; + s1 = data[1]; + s2 = data[2]; } else { /* Use reentrant version of rand48 to ensure that no conflicts with other generators occur */ srand48_r((long int)seed_init, &buffer); diff --git a/openair2/COMMON/as_message.h b/openair2/COMMON/as_message.h index 829c3c9e33..b0ca06daec 100644 --- a/openair2/COMMON/as_message.h +++ b/openair2/COMMON/as_message.h @@ -219,6 +219,10 @@ typedef struct kenb_refresh_req_s { Byte_t kenb[32]; } kenb_refresh_req_t; +typedef struct nsa_oai_tun_nsa_s { + uint8_t buffer[500]; +} nas_oai_tun_nsa_t; + /* * NAS->AS - Cell Information request * NAS request AS to search for a suitable cell belonging to the selected diff --git a/openair2/COMMON/pdcp_messages_def.h b/openair2/COMMON/pdcp_messages_def.h index 59d47eb81b..5392c9e04d 100644 --- a/openair2/COMMON/pdcp_messages_def.h +++ b/openair2/COMMON/pdcp_messages_def.h @@ -31,6 +31,8 @@ MESSAGE_DEF(RRC_DCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcDcchDataReq, rrc_dcch_data_req) MESSAGE_DEF(RRC_DCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, RrcDcchDataInd, rrc_dcch_data_ind) MESSAGE_DEF(RRC_PCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcPcchDataReq, rrc_pcch_data_req) +MESSAGE_DEF(RRC_NRUE_CAP_INFO_IND, MESSAGE_PRIORITY_MED_PLUS, RrcDcchDataInd, rrc_nrue_cap_info_ind) +MESSAGE_DEF(RRC_DCCH_DATA_COPY_IND, MESSAGE_PRIORITY_MED_PLUS, RrcDcchDataInd, rrc_dcch_data_copy_ind) // gNB MESSAGE_DEF(NR_RRC_DCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, NRRrcDcchDataReq, nr_rrc_dcch_data_req) diff --git a/openair2/COMMON/pdcp_messages_types.h b/openair2/COMMON/pdcp_messages_types.h index 0390fd80f4..d7c84a24a1 100644 --- a/openair2/COMMON/pdcp_messages_types.h +++ b/openair2/COMMON/pdcp_messages_types.h @@ -34,6 +34,8 @@ #define RRC_DCCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_dcch_data_req #define RRC_DCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_dcch_data_ind #define RRC_PCCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_pcch_data_req +#define RRC_NRUE_CAP_INFO_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_nrue_cap_info_ind +#define RRC_DCCH_DATA_COPY_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_dcch_data_copy_ind // gNB #define NR_RRC_DCCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.nr_rrc_dcch_data_req @@ -65,6 +67,13 @@ typedef struct RrcDcchDataInd_s { uint8_t eNB_index; // LG: needed in UE } RrcDcchDataInd; +typedef struct RrcDcchDataCopyInd_s { + uint8_t dcch_index; + uint32_t sdu_size; + uint8_t *sdu_p; + uint8_t eNB_index; +} RrcDcchDataCopyInd; + typedef struct NRRrcDcchDataReq_s { uint32_t frame; uint8_t gnb_flag; diff --git a/openair2/COMMON/platform_constants.h b/openair2/COMMON/platform_constants.h index 355f56f9c9..d409650528 100644 --- a/openair2/COMMON/platform_constants.h +++ b/openair2/COMMON/platform_constants.h @@ -75,9 +75,9 @@ #define MAX_eNB 2 #define MAX_gNB 2 #else - #define MAX_MOBILES_PER_ENB 4 - #define MAX_MOBILES_PER_ENB_NB_IoT 4 - #define MAX_MOBILES_PER_GNB 4//16 + #define MAX_MOBILES_PER_ENB 40 + #define MAX_MOBILES_PER_ENB_NB_IoT 40 + #define MAX_MOBILES_PER_GNB 16 #define MAX_eNB 2 #define MAX_gNB 2 #endif diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h index 7f8e4ee568..c24291de64 100644 --- a/openair2/COMMON/platform_types.h +++ b/openair2/COMMON/platform_types.h @@ -212,6 +212,14 @@ typedef enum config_action_e { CONFIG_ACTION_MBMS_MODIFY = 11 } config_action_t; +/* Maximum size of any message we might send or receive (e.g., via a socket) */ +#define MAX_MESSAGE_SIZE 8192 + +typedef struct nsa_msg_t { + uint8_t msg_type; + uint8_t msg_buffer[MAX_MESSAGE_SIZE]; +} nsa_msg_t; + //----------------------------------------------------------------------------- // GTPV1U TYPES //----------------------------------------------------------------------------- diff --git a/openair2/COMMON/rrc_messages_def.h b/openair2/COMMON/rrc_messages_def.h index 81df5fdcbf..35caf3c342 100644 --- a/openair2/COMMON/rrc_messages_def.h +++ b/openair2/COMMON/rrc_messages_def.h @@ -65,6 +65,8 @@ MESSAGE_DEF(NAS_UPLINK_DATA_REQ, MESSAGE_PRIORITY_MED, NasUlDataReq MESSAGE_DEF(NAS_RAB_ESTABLI_RSP, MESSAGE_PRIORITY_MED, NasRabEstRsp, nas_rab_est_rsp) +MESSAGE_DEF(NAS_OAI_TUN_NSA, MESSAGE_PRIORITY_MED, NasOaiTunNsa, nas_oai_tun_nsa) + // UE: RRC -> NAS messages MESSAGE_DEF(NAS_CELL_SELECTION_CNF, MESSAGE_PRIORITY_MED, NasCellSelectionCnf, nas_cell_selection_cnf) MESSAGE_DEF(NAS_CELL_SELECTION_IND, MESSAGE_PRIORITY_MED, NasCellSelectionInd, nas_cell_selection_ind) diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index d4001667a8..63a581b37b 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -91,6 +91,8 @@ #define RLC_SDU_INDICATION(mSGpTR) (mSGpTR)->ittiMsg.rlc_sdu_indication #define NRDuDlReq(mSGpTR) (mSGpTR)->ittiMsg.nr_du_dl_req +#define NAS_OAI_TUN_NSA(mSGpTR) (mSGpTR)->ittiMsg.nas_oai_tun_nsa + //-------------------------------------------------------------------------------------------// typedef struct RrcStateInd_s { Rrc_State_t state; @@ -433,6 +435,8 @@ typedef ul_info_transfer_req_t NasUlDataReq; typedef rab_establish_rsp_t NasRabEstRsp; +typedef nas_oai_tun_nsa_t NasOaiTunNsa; + // UE: RRC -> NAS messages typedef cell_info_cnf_t NasCellSelectionCnf; typedef cell_info_ind_t NasCellSelectionInd; diff --git a/openair2/GNB_APP/gnb_app.c b/openair2/GNB_APP/gnb_app.c index fa721b67a7..9090761242 100644 --- a/openair2/GNB_APP/gnb_app.c +++ b/openair2/GNB_APP/gnb_app.c @@ -51,6 +51,7 @@ #include "f1ap_du_task.h" #include "nfapi/oai_integration/vendor_ext.h" #include +#include "openair2/LAYER2/PDCP_v10.1.0/pdcp.h" extern unsigned char NB_gNB_INST; extern RAN_CONTEXT_t RC; @@ -144,7 +145,7 @@ static void init_pdcp(void) { pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT; } - pdcp_module_init(pdcp_initmask); + nr_pdcp_module_init(pdcp_initmask, 0); if (NODE_IS_CU(RC.nrrrc[0]->node_type)) { LOG_I(PDCP, "node is CU, pdcp send rlc_data_req by proto_agent \n"); @@ -181,6 +182,8 @@ void *gNB_app_task(void *args_p) LOG_I(PHY, "%s() Task ready initialize structures\n", __FUNCTION__); + RCconfig_NR_L1(); + if (RC.nb_nr_macrlc_inst>0) RCconfig_nr_macrlc(); LOG_I(PHY, "%s() RC.nb_nr_L1_inst:%d\n", __FUNCTION__, RC.nb_nr_L1_inst); @@ -202,7 +205,7 @@ void *gNB_app_task(void *args_p) configure_nr_rrc(gnb_id); } - if (RC.nb_nr_inst > 0) { + if (RC.nb_nr_inst > 0 && !get_softmodem_params()->nsa) { init_pdcp(); } diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index 8d4a53da6c..209275acb3 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -799,7 +799,7 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP, RC.mac[Mod_idP]->common_channels[CC_idP].Ncp = Ncp; RC.mac[Mod_idP]->common_channels[CC_idP].eutra_band = eutra_band; RC.mac[Mod_idP]->common_channels[CC_idP].dl_CarrierFreq = dl_CarrierFreq; - LOG_I(MAC, + LOG_A(MAC, "Configuring MIB for instance %d, CCid %d : (band %d,N_RB_DL %d,Nid_cell %d,p %d,DL freq %u,phich_config.resource %d, phich_config.duration %d)\n", Mod_idP, CC_idP, @@ -1067,7 +1067,7 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP, while(RC.mac[Mod_idP]->if_inst->PHY_config_req == NULL) { // DJP AssertFatal(RC.mac[Mod_idP]->if_inst->PHY_config_req != NULL,"if_inst->phy_config_request is null\n"); usleep(100 * 1000); - printf("Waiting for PHY_config_req\n"); + LOG_I(MAC, "Waiting for PHY_config_req\n"); } } diff --git a/openair2/LAYER2/MAC/config_ue.c b/openair2/LAYER2/MAC/config_ue.c index f5c12e710d..3cfc725fdb 100644 --- a/openair2/LAYER2/MAC/config_ue.c +++ b/openair2/LAYER2/MAC/config_ue.c @@ -200,7 +200,7 @@ rrc_mac_config_req_ue(module_id_t Mod_idP, LTE_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; } - if(NFAPI_MODE != NFAPI_UE_STUB_PNF) + if(NFAPI_MODE!=NFAPI_UE_STUB_PNF && NFAPI_MODE!=NFAPI_MODE_STANDALONE_PNF) phy_config_harq_ue(Mod_idP, 0, eNB_index, UE_mac_inst[Mod_idP].scheduling_info.maxHARQ_Tx); if (mac_MainConfig->ul_SCH_Config->retxBSR_Timer) { @@ -308,7 +308,7 @@ rrc_mac_config_req_ue(module_id_t Mod_idP, } if (physicalConfigDedicated != NULL) { - if(NFAPI_MODE != NFAPI_UE_STUB_PNF) + if(NFAPI_MODE != NFAPI_UE_STUB_PNF && NFAPI_MODE != NFAPI_MODE_STANDALONE_PNF) phy_config_dedicated_ue(Mod_idP, 0, eNB_index, physicalConfigDedicated); diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index 9d07018e2f..d647eff7cb 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -313,6 +313,7 @@ schedule_SR (module_id_t module_idP, nfapi_ul_config_request_body_t *ul_req_body = NULL; LTE_SchedulingRequestConfig_t *SRconfig = NULL; nfapi_ul_config_sr_information sr; + memset(&sr, 0, sizeof(sr)); for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { eNB->UL_req[CC_id].sfn_sf = (frameP << 4) + subframeP; @@ -573,6 +574,27 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, UE_sched_ctrl_t *UE_scheduling_control = NULL; start_meas(&(eNB->eNB_scheduler)); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER, VCD_FUNCTION_IN); + // TODO: Better solution needed this is the first + // 3 indications of this function on startup + // 1303275.278188 [MAC] XXX 0.0 -> 0.4 = 4 + // 1303275.279443 [MAC] XXX 0.4 -> 639.5 = 6391 + // 1303275.348686 [MAC] XXX 646.3 -> 646.3 = 0 + int delta = (frameP * 10 + subframeP) - (eNB->frame * 10 + eNB->subframe); + if (delta < 0) + { + delta += 10240; // sfn_sf decimal values range from 0 to 10239 + } + // If we ever see a difference this big something is very wrong + // This threshold is arbitrary + if (delta > 8500 || delta == 0) // 850 frames + { + LOG_I(MAC, "scheduler ignoring outerspace %d.%d -> %d.%d = %d\n", + eNB->frame, eNB->subframe, frameP, subframeP, delta); + return; + } + LOG_D(MAC, "Entering dlsch_ulsch scheduler %d.%d -> %d.%d = %d\n", + eNB->frame, eNB->subframe, frameP, subframeP, delta); + eNB->frame = frameP; eNB->subframe = subframeP; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c index 8a400af1f3..e62978782c 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c @@ -918,7 +918,7 @@ generate_Msg4(module_id_t module_idP, module_idP, CC_idP, frameP, subframeP, UE_id, rrc_sdu_length); // AssertFatal(rrc_sdu_length > 0, // "[MAC][eNB Scheduler] CCCH not allocated, rrc_sdu_length: %d\n", rrc_sdu_length); - LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 with RRC Piggyback (RNTI %x)\n", + LOG_A(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 with RRC Piggyback (RNTI %x)\n", module_idP, CC_idP, frameP, subframeP, ra->rnti); /// Choose first 4 RBs for Msg4, should really check that these are free! first_rb = 0; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c index b115517091..6bcbd2d443 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c @@ -1018,8 +1018,8 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, UE_id, CC_id, N_RBG[CC_id], - (uint16_t(*)[NUMBER_OF_UE_MAX])nb_rbs_required, - (uint16_t(*)[NUMBER_OF_UE_MAX])nb_rbs_required_remaining, + nb_rbs_required, + nb_rbs_required_remaining, rballoc_sub); temp_total_rbs_count -= ue_sched_ctl->pre_nb_available_rbs[CC_id]; temp_total_ue_count--; diff --git a/openair2/LAYER2/MAC/main_ue.c b/openair2/LAYER2/MAC/main_ue.c index 2140d66a10..5ea2d26abd 100644 --- a/openair2/LAYER2/MAC/main_ue.c +++ b/openair2/LAYER2/MAC/main_ue.c @@ -41,10 +41,12 @@ #include "common/utils/LOG/log.h" #include "nfapi/oai_integration/vendor_ext.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" - - +#include "PHY_INTERFACE/phy_stub_UE.h" #include "common/ran_context.h" #include + +extern void openair_rrc_top_init_ue( int eMBMS_active, char *uecap_xer, uint8_t cba_group_active, uint8_t HO_active); + void dl_phy_sync_success(module_id_t module_idP, frame_t frameP, unsigned char eNB_index, uint8_t first_sync) { //init as MR LOG_D(MAC, "[UE %d] Frame %d: PHY Sync to eNB_index %d successful \n", module_idP, frameP, eNB_index); @@ -88,6 +90,16 @@ mac_top_init_ue(int eMBMS_active, char *uecap_xer, UE_mac_inst = NULL; } + // mutex below are used for multiple UE's L2 FAPI simulation. + if (NFAPI_MODE == NFAPI_UE_STUB_PNF || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF) { + pthread_mutex_init(&fill_ul_mutex.rx_mutex,NULL); + pthread_mutex_init(&fill_ul_mutex.crc_mutex,NULL); + pthread_mutex_init(&fill_ul_mutex.sr_mutex,NULL); + pthread_mutex_init(&fill_ul_mutex.harq_mutex,NULL); + pthread_mutex_init(&fill_ul_mutex.cqi_mutex,NULL); + pthread_mutex_init(&fill_ul_mutex.rach_mutex,NULL); + } + LOG_I(MAC, "[MAIN] calling RRC\n"); openair_rrc_top_init_ue(eMBMS_active, uecap_xer, cba_group_active, HO_active); diff --git a/openair2/LAYER2/MAC/ra_procedures.c b/openair2/LAYER2/MAC/ra_procedures.c index 0d1afdf2a2..1aa959e103 100644 --- a/openair2/LAYER2/MAC/ra_procedures.c +++ b/openair2/LAYER2/MAC/ra_procedures.c @@ -287,9 +287,12 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP, int CC_id, sub_frame_t subframeP) { uint8_t Size = 0; UE_MODE_t UE_mode; - + protocol_ctxt_t ctxt; + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_NO, + UE_mac_inst[module_idP].crnti, frameP, + subframeP, eNB_indexP); // Modification for phy_stub_ue operation - if(NFAPI_MODE == NFAPI_UE_STUB_PNF) { // phy_stub_ue mode + if(NFAPI_MODE == NFAPI_UE_STUB_PNF || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF) { // phy_stub_ue mode UE_mode = UE_mac_inst[module_idP].UE_mode[0]; LOG_D(MAC, "ue_get_rach , UE_mode: %d", UE_mode); } else { // Full stack mode @@ -320,6 +323,18 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP, int CC_id, if (UE_mac_inst[module_idP].RA_active == 0) { LOG_I(MAC, "RA not active\n"); + if (UE_rrc_inst[module_idP].Info[eNB_indexP].T300_cnt + != T300[UE_rrc_inst[module_idP].sib2[eNB_indexP]->ue_TimersAndConstants.t300]) { + /* Calling rrc_ue_generate_RRCConnectionRequest here to ensure that + every time we fill the UE_mac_inst context we generate new random + values in msg3. When the T300 timer has expired, rrc_common.c will + call rrc_ue_generate_RRCConnectionRequest, so we do not want to call + when UE_rrc_inst[module_idP].Info[eNB_indexP].T300_cnt == + T300[UE_rrc_inst[module_idP].sib2[eNB_indexP]->ue_TimersAndConstants.t300. */ + UE_rrc_inst[module_idP].Srb0[eNB_indexP].Tx_buffer.payload_size = 0; + rrc_ue_generate_RRCConnectionRequest(&ctxt, eNB_indexP); + } + // check if RRC is ready to initiate the RA procedure Size = mac_rrc_data_req_ue(module_idP, CC_id, diff --git a/openair2/LAYER2/MAC/rar_tools_ue.c b/openair2/LAYER2/MAC/rar_tools_ue.c index 611aaf865b..9af5baec39 100644 --- a/openair2/LAYER2/MAC/rar_tools_ue.c +++ b/openair2/LAYER2/MAC/rar_tools_ue.c @@ -67,6 +67,7 @@ uint16_t ue_process_rar(const module_id_t module_idP, const int CC_id, const fra LOG_D(PHY, "Found RAR with the intended RAPID %d\n", rarh->RAPID); rar = (uint8_t *) (dlsch_buffer + n_rarh + (n_rarpy - 1) * 6); + UE_mac_inst[module_idP].UE_mode[0] = RA_RESPONSE; break; } @@ -77,9 +78,10 @@ uint16_t ue_process_rar(const module_id_t module_idP, const int CC_id, const fra } if (rarh->E == 0) { - LOG_I(PHY, + LOG_I(MAC, "No RAR found with the intended RAPID. The closest RAPID in all RARs is %d\n", best_rx_rapid); + UE_mac_inst[module_idP].UE_mode[0] = PRACH; break; } else { rarh++; @@ -94,7 +96,7 @@ uint16_t ue_process_rar(const module_id_t module_idP, const int CC_id, const fra return (0xffff); } - LOG_I(MAC, + LOG_A(MAC, "[UE %d][RAPROC] Frame %d Received RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for preamble %d/%d\n", module_idP, frameP, *(uint8_t *) rarh, rar[0], rar[1], rar[2], rar[3], rar[4], rar[5], rarh->RAPID, preamble_index); @@ -130,7 +132,7 @@ uint16_t ue_process_rar(const module_id_t module_idP, const int CC_id, const fra } // move the selected RAR to the front of the RA_PDSCH buffer - memcpy(selected_rar_buffer + 0, (uint8_t *) rarh, 1); - memcpy(selected_rar_buffer + 1, (uint8_t *) rar, 6); + memmove(selected_rar_buffer + 0, (uint8_t *) rarh, 1); + memmove(selected_rar_buffer + 1, (uint8_t *) rar, 6); return ret; } diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index 21d349ea52..926c44381c 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -149,15 +149,13 @@ void ue_init_mac(module_id_t module_idP) { UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[i] = 0; } - if(NFAPI_MODE==NFAPI_UE_STUB_PNF) { + if(NFAPI_MODE==NFAPI_UE_STUB_PNF || NFAPI_MODE==NFAPI_MODE_STANDALONE_PNF) { pthread_mutex_init(&UE_mac_inst[module_idP].UL_INFO_mutex,NULL); - UE_mac_inst[module_idP].UE_mode[0] = NOT_SYNCHED; //PRACH; + UE_mac_inst[module_idP].UE_mode[0] = PRACH; //NOT_SYNCHED; UE_mac_inst[module_idP].first_ULSCH_Tx =0; UE_mac_inst[module_idP].SI_Decoded = 0; next_ra_frame = 0; next_Mod_id = 0; - tx_request_pdu_list = NULL; - tx_req_num_elems = 0; } } @@ -411,7 +409,7 @@ ue_send_sdu(module_id_t module_idP, if (payload_ptr != NULL) { for (i = 0; i < num_ce; i++) { - // printf("ce %d : %d\n",i,rx_ces[i]); + LOG_I(MAC, "ce %d : %d\n",i,rx_ces[i]); switch (rx_ces[i]) { case UE_CONT_RES: LOG_I(MAC, @@ -436,7 +434,7 @@ ue_send_sdu(module_id_t module_idP, "[UE %d][RAPROC] Contention detected, RA failed\n", module_idP); - if(NFAPI_MODE==NFAPI_UE_STUB_PNF) { // phy_stub mode + if(NFAPI_MODE==NFAPI_UE_STUB_PNF || NFAPI_MODE==NFAPI_MODE_STANDALONE_PNF) { // phy_stub mode // Modification for phy_stub mode operation here. We only need to make sure that the ue_mode is back to // PRACH state. LOG_I(MAC, "nfapi_mode3: Setting UE_mode BACK to PRACH 1\n"); @@ -462,7 +460,7 @@ ue_send_sdu(module_id_t module_idP, [module_idP]. RA_contention_resolution_timer_active = 0; - if(NFAPI_MODE==NFAPI_UE_STUB_PNF) { // phy_stub mode + if(NFAPI_MODE==NFAPI_UE_STUB_PNF || NFAPI_MODE==NFAPI_MODE_STANDALONE_PNF) { // phy_stub mode // Modification for phy_stub mode operation here. We only need to change the ue_mode to PUSCH UE_mac_inst[module_idP].UE_mode[eNB_index] = PUSCH; } else { // Full stack mode @@ -480,7 +478,7 @@ ue_send_sdu(module_id_t module_idP, #endif // Eliminate call to process_timing_advance for the phy_stub UE operation mode. Is this correct? - if (NFAPI_MODE!=NFAPI_UE_STUB_PNF) { + if (NFAPI_MODE!=NFAPI_UE_STUB_PNF && NFAPI_MODE!=NFAPI_MODE_STANDALONE_PNF) { process_timing_advance(module_idP,CC_id,payload_ptr[0]); } @@ -2508,6 +2506,7 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, scheduling_info.BSR_bytes[UE_mac_inst[module_idP]. scheduling_info.LCGID [lcid]]); + AssertFatal(num_sdus < sizeof(sdu_lengths) / sizeof(sdu_lengths[0]), "num_sdus %d > num sdu_length elements\n", num_sdus); sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, UE_mac_inst [module_idP]. @@ -2639,7 +2638,7 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, // build PHR and update the timers if (phr_ce_len == sizeof(POWER_HEADROOM_CMD)) { - if(NFAPI_MODE==NFAPI_UE_STUB_PNF) { + if(NFAPI_MODE==NFAPI_UE_STUB_PNF || NFAPI_MODE==NFAPI_MODE_STANDALONE_PNF) { //Substitute with a static value for the MAC layer abstraction (phy_stub mode) phr_p->PH = 60; } else { @@ -3090,7 +3089,7 @@ ue_scheduler(const module_id_t module_idP, "Module id %u Contention resolution timer expired, RA failed\n", module_idP); - if(NFAPI_MODE==NFAPI_UE_STUB_PNF) { // phy_stub mode + if(NFAPI_MODE==NFAPI_UE_STUB_PNF || NFAPI_MODE==NFAPI_MODE_STANDALONE_PNF) { // phy_stub mode // Modification for phy_stub mode operation here. We only need to make sure that the ue_mode is back to // PRACH state. LOG_I(MAC, "nfapi_mode3: Setting UE_mode to PRACH 2 \n"); diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index 4ef0a55c6b..ba3128923f 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -264,6 +264,16 @@ typedef struct { uint8_t nbits; } dci_field_t; +typedef struct { + bool expected_sib; + bool index_has_sib[16]; + bool expected_rar; + bool index_has_rar[16]; + bool expected_dci; + bool index_has_dci[16]; + int active_harq_sfn_slot; +} nr_emulated_l1_t; + typedef struct { uint8_t format_indicator; //1 bit diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h index 5def748d42..4b37c19dff 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h @@ -39,6 +39,8 @@ extern const uint8_t nr_slots_per_frame[5]; +extern dci_pdu_rel15_t *def_dci_pdu_rel15; + /* extern const uint32_t BSR_TABLE[BSR_TABLE_SIZE]; extern const uint32_t Extended_BSR_TABLE[BSR_TABLE_SIZE]; extern const uint8_t cqi2fmt0_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE]; diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 764c92ecb7..b03c8fa55f 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -627,7 +627,8 @@ int nr_rrc_mac_config_req_ue( pthread_mutex_init(&(mac->ul_config_request[i].mutex_ul_config), NULL); // Setup the SSB to Rach Occasions mapping according to the config build_ssb_to_ro_map(mac);//->scc, mac->phy_config.config_req.cell_config.frame_duplex_type); - mac->if_module->phy_config_request(&mac->phy_config); + if (!get_softmodem_params()->emulate_l1) + mac->if_module->phy_config_request(&mac->phy_config); mac->common_configuration_complete = 1; } if(scell_group_config != NULL ){ @@ -654,7 +655,16 @@ int nr_rrc_mac_config_req_ue( else if (cell_group_config != NULL ){ LOG_I(MAC,"Applying CellGroupConfig from gNodeB\n"); mac->cg = cell_group_config; - mac->servCellIndex = cell_group_config->spCellConfig->servCellIndex ? *cell_group_config->spCellConfig->servCellIndex : 0; + if (cell_group_config->spCellConfig) { + mac->servCellIndex = cell_group_config->spCellConfig->servCellIndex ? *cell_group_config->spCellConfig->servCellIndex : 0; + mac->DL_BWP_Id=mac->cg->spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id ? *mac->cg->spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id : 0; + mac->UL_BWP_Id=mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id ? *mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id : 0; + } + else { + mac->servCellIndex = 0; + mac->DL_BWP_Id = 0; + mac->UL_BWP_Id = 0; + } mac->scheduling_info.periodicBSR_SF = MAC_UE_BSR_TIMER_NOT_RUNNING; @@ -667,7 +677,26 @@ int nr_rrc_mac_config_req_ue( mac->scheduling_info.retxBSR_SF); config_control_ue(mac); - //config_common_ue(mac,module_id,cc_idP); + if (get_softmodem_params()->nsa) { + if (cell_group_config->spCellConfig && cell_group_config->spCellConfig->reconfigurationWithSync) { + if (cell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated) { + ra->rach_ConfigDedicated = cell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink; + } + mac->scc = cell_group_config->spCellConfig->reconfigurationWithSync->spCellConfigCommon; + int num_slots = mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots; + if (mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols > 0) { + num_slots++; + } + mac->ul_config_request = calloc(num_slots, sizeof(*mac->ul_config_request)); + config_common_ue(mac,module_id,cc_idP); + mac->crnti = cell_group_config->spCellConfig->reconfigurationWithSync->newUE_Identity; + LOG_I(MAC,"Configuring CRNTI %x\n",mac->crnti); + } + + // Setup the SSB to Rach Occasions mapping according to the config + build_ssb_to_ro_map(mac); + } + /* if(mac_cell_group_configP != NULL){ if(mac_cell_group_configP->drx_Config != NULL ){ diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index edfd37c3a0..ad86b1385d 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -430,8 +430,14 @@ typedef struct { dci_pdu_rel15_t def_dci_pdu_rel15[8]; + // Defined for abstracted mode + nr_downlink_indication_t dl_info; NR_UE_HARQ_STATUS_t dl_harq_info[16]; + nr_emulated_l1_t nr_ue_emul_l1; + + pthread_mutex_t mutex_dl_info; + } NR_UE_MAC_INST_t; typedef enum seach_space_mask_e { diff --git a/openair2/LAYER2/NR_MAC_UE/mac_extern.h b/openair2/LAYER2/NR_MAC_UE/mac_extern.h index e551790f7a..7fd63666f0 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_extern.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_extern.h @@ -68,8 +68,6 @@ extern const uint16_t table_7_2_1[16]; extern dci_pdu_rel15_t *def_dci_pdu_rel15; -extern dci_pdu_rel15_t *def_dci_pdu_rel15; - extern void mac_rlc_data_ind(const module_id_t module_idP, const rnti_t rntiP, const eNB_index_t eNB_index, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 2d059783fe..3851ee011d 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -595,7 +595,9 @@ void nr_get_prach_resources(module_id_t mod_id, LOG_D(MAC, "In %s: selected RA preamble index %d for contention-free random access procedure for SSB with Id %d\n", __FUNCTION__, prach_resources->ra_PreambleIndex, cfra_ssb_resource_idx); } } else { - int16_t dl_pathloss = get_nr_PL(mod_id, CC_id, gNB_id); + /* TODO: This controls the tx_power of UE and the ramping procedure of RA of UE. Later we + can abstract this, perhaps in the proxy. But for the time being lets leave it as below. */ + int16_t dl_pathloss = !get_softmodem_params()->emulate_l1 ? get_nr_PL(mod_id, CC_id, gNB_id) : 0; ssb_rach_config(ra, prach_resources, nr_rach_ConfigCommon, prach_pdu); ra_preambles_config(prach_resources, mac, dl_pathloss); LOG_D(MAC, "[RAPROC] - Selected RA preamble index %d for contention-based random access procedure... \n", prach_resources->ra_PreambleIndex); @@ -674,7 +676,8 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, // Delay init RA procedure to allow the convergence of the IIR filter on PRACH noise measurements at gNB side if (!prach_resources->init_msg1) { - if ( (mac->common_configuration_complete>0 || get_softmodem_params()->do_ra==1) && ((MAX_FRAME_NUMBER+frame-prach_resources->sync_frame)%MAX_FRAME_NUMBER)>150 ){ + if ((mac->common_configuration_complete > 0 || get_softmodem_params()->do_ra || get_softmodem_params()->nsa) && + ((MAX_FRAME_NUMBER + frame - prach_resources->sync_frame) % MAX_FRAME_NUMBER) > 150) { prach_resources->init_msg1 = 1; } else { LOG_D(NR_MAC,"PRACH Condition not met: frame %d, prach_resources->sync_frame %d\n",frame,prach_resources->sync_frame); @@ -738,6 +741,30 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, pdu -= sh_size; } + } else if (get_softmodem_params()->nsa) { + + uint8_t mac_sdus[MAX_NR_ULSCH_PAYLOAD_BYTES]; + uint16_t sdu_lengths[NB_RB_MAX] = {0}; + int TBS_bytes = 848; + int mac_ce_len = 0; + int header_length_total=0; + unsigned short post_padding = 1; + + // fill ulsch_buffer with random data + for (int i = 0; i < TBS_bytes; i++){ + mac_sdus[i] = (unsigned char) (lrand48()&0xff); + } + //Sending SDUs with size 1 + //Initialize elements of sdu_lengths + sdu_lengths[0] = TBS_bytes - 3 - post_padding - mac_ce_len; + header_length_total += 2 + (sdu_lengths[0] >= 128); + size_sdu += sdu_lengths[0]; + + if (size_sdu > 0) { + memcpy(ra->cont_res_id, mac_sdus, sizeof(uint8_t) * 6); + ra->Msg3_size = size_sdu + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); + } + } else { size_sdu = nr_write_ce_ulsch_pdu(pdu, mac, 0, &(mac->crnti), NULL, NULL, NULL); @@ -746,19 +773,20 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, } - if (size_sdu > 0 && ra->generate_nr_prach == GENERATE_PREAMBLE) { + if (size_sdu > 0 && (ra->generate_nr_prach == GENERATE_PREAMBLE || get_softmodem_params()->nsa)) { LOG_D(NR_MAC, "In %s: [UE %d][%d.%d]: starting initialisation Random Access Procedure...\n", __FUNCTION__, mod_id, frame, nr_slot_tx); - AssertFatal(TBS_max > ra->Msg3_size, "In %s: allocated resources are not enough for Msg3!\n", __FUNCTION__); // Init RA procedure init_RA(mod_id, prach_resources, setup, rach_ConfigGeneric, rach_ConfigDedicated); nr_get_RA_window(mac); // Fill in preamble and PRACH resources - nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, prach_pdu, rach_ConfigDedicated); + if (ra->generate_nr_prach == GENERATE_PREAMBLE) + nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, prach_pdu, rach_ConfigDedicated); // Padding: fill remainder with 0 if (TBS_max - ra->Msg3_size > 0) { + AssertFatal(TBS_max > ra->Msg3_size, "In %s: allocated resources are not enough for Msg3!\n", __FUNCTION__); LOG_D(NR_MAC, "In %s: remaining %d bytes, filling with padding\n", __FUNCTION__, TBS_max - ra->Msg3_size); ((NR_MAC_SUBHEADER_FIXED *) pdu)->R = 0; ((NR_MAC_SUBHEADER_FIXED *) pdu)->LCID = UL_SCH_LCID_PADDING; @@ -777,8 +805,10 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, // Msg3 was initialized with TBS_max bytes because the RA_Msg3_size will only be known after // receiving Msg2 (which contains the Msg3 resource reserve). // Msg3 will be transmitted with RA_Msg3_size bytes, removing unnecessary 0s. - mac->ulsch_pdu.Pdu_size = TBS_max; - memcpy(mac->ulsch_pdu.payload, payload, TBS_max); + if (!get_softmodem_params()->nsa) { + mac->ulsch_pdu.Pdu_size = TBS_max; + memcpy(mac->ulsch_pdu.payload, payload, TBS_max); + } } else { return 0; @@ -936,7 +966,7 @@ void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot){ } else { - LOG_I(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CB-RA: Contention Resolution is successful.\n", mod_id, frame, slot); + LOG_A(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CB-RA: Contention Resolution is successful.\n", mod_id, frame, slot); ra->RA_contention_resolution_timer_active = 0; mac->crnti = ra->t_crnti; 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 ad82161fb9..3453e071b1 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -428,7 +428,8 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl NR_SetupRelease_PDCCH_ConfigCommon_t *pdcch_ConfigCommon = bwp_Common->pdcch_ConfigCommon; if (pdcch_ConfigCommon && - pdcch_ConfigCommon->choice.setup->searchSpaceSIB1){ + pdcch_ConfigCommon->choice.setup->searchSpaceSIB1 && + !get_softmodem_params()->nsa) { NR_SearchSpace_t *ss0 = mac->search_space_zero; fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15; @@ -442,7 +443,7 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl } } } - else { // use coreset0/ss0 + else if (!get_softmodem_params()->nsa) { // use coreset0/ss0 NR_SearchSpace_t *ss0 = mac->search_space_zero; if(ss0) { fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &dl_config->dl_config_list[0].dci_config_pdu.dci_config_rel15; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 2f4ceb48ec..8884ee9f68 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -608,7 +608,6 @@ int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_in def_dci_pdu_rel15 = &mac->def_dci_pdu_rel15[dci->dci_format]; } int8_t ret_proc = nr_ue_process_dci(module_id, cc_id, gNB_index, frame, slot, def_dci_pdu_rel15, dci); - memset(def_dci_pdu_rel15, 0, sizeof(dci_pdu_rel15_t)); return ret_proc; } @@ -728,6 +727,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr LOG_W(MAC, "In %s: ul_config request is NULL. Probably due to unexpected UL DCI in frame.slot %d.%d. Ignoring DCI!\n", __FUNCTION__, frame, slot); return -1; } + ul_config->number_pdus = 0; pthread_mutex_lock(&ul_config->mutex_ul_config); AssertFatal(ul_config->number_pdusnumber_pdus %d out of bounds\n",ul_config->number_pdus); @@ -868,7 +868,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr /* dmrs symbol positions*/ dlsch_config_pdu_1_0->dlDmrsSymbPos = fill_dmrs_mask(pdsch_config, - mac->mib->dmrs_TypeA_Position, + (get_softmodem_params()->nsa) ? mac->scc->dmrs_TypeA_Position : mac->mib->dmrs_TypeA_Position, dlsch_config_pdu_1_0->number_symbols, dlsch_config_pdu_1_0->start_symbol, mappingtype); @@ -1333,8 +1333,10 @@ void set_harq_status(NR_UE_MAC_INST_t *mac, // FIXME k0 != 0 currently not taken into consideration current_harq->dl_frame = frame; current_harq->dl_slot = slot; + mac->nr_ue_emul_l1.active_harq_sfn_slot = NFAPI_SFNSLOT2HEX(frame, (slot + data_toul_fb)); - LOG_D(PHY,"Setting harq_status for harq_id %d, dl %d.%d\n",harq_id,frame,slot); + LOG_D(NR_PHY,"Setting harq_status for harq_id %d, dl %d.%d, sched ul %d.%d\n", + harq_id, frame, slot, frame, (slot + data_toul_fb)); } @@ -2837,7 +2839,7 @@ uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, // check BWP id if (mac->DLbwp[0]) N_RB=NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); else N_RB=mac->type0_PDCCH_CSS_config.num_rbs; -; + // indicating a DL DCI format 1bit pos++; @@ -3331,6 +3333,9 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, mac_subheader_len = 2; } + AssertFatal(pdu_len > mac_sdu_len, "The mac_sdu_len (%d) has an invalid size. PDU len = %d! \n", + mac_sdu_len, pdu_len); + // Check if it is a valid CCCH message, we get all 00's messages very often int i = 0; for(i=0; i<(mac_subheader_len+mac_sdu_len); i++) { @@ -3496,47 +3501,56 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, case DL_SCH_LCID_DCCH1: // check if LCID is valid at current time. default: - // check if LCID is valid at current time. - if(((NR_MAC_SUBHEADER_SHORT *)pduP)->F){ - //mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8; - mac_subheader_len = 3; - mac_sdu_len = ((uint16_t)(((NR_MAC_SUBHEADER_LONG *) pduP)->L1 & 0x7f) << 8) - | ((uint16_t)((NR_MAC_SUBHEADER_LONG *) pduP)->L2 & 0xff); + { + // check if LCID is valid at current time. + if (pdu_len < sizeof(NR_MAC_SUBHEADER_SHORT)) + return; + NR_MAC_SUBHEADER_SHORT *shs = (NR_MAC_SUBHEADER_SHORT *)pduP; + if (shs->F) { + //mac_sdu_len |= (uint16_t)(((NR_MAC_SUBHEADER_LONG *)pduP)->L2)<<8; + mac_subheader_len = 3; + if (pdu_len < sizeof(NR_MAC_SUBHEADER_LONG)) + return; + NR_MAC_SUBHEADER_LONG *shl = (NR_MAC_SUBHEADER_LONG *)pduP; + mac_sdu_len = ((uint16_t)(shl->L1 & 0x7f) << 8) | (uint16_t)(shl->L2 & 0xff); + } else { + if (pdu_len < sizeof(NR_MAC_SUBHEADER_SHORT)) + return; + mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L; + mac_subheader_len = 2; + } - } else { - mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pduP)->L; - mac_subheader_len = 2; - } + LOG_D(NR_MAC, "[UE %d] Frame %d : DLSCH -> DL-DTCH %d (gNB %d, %d bytes)\n", module_idP, frameP, rx_lcid, gNB_index, mac_sdu_len); - LOG_D(MAC, "[UE %d] Frame %d : DLSCH -> DL-DTCH %d (gNB %d, %d bytes)\n", module_idP, frameP, rx_lcid, gNB_index, mac_sdu_len); + #if defined(ENABLE_MAC_PAYLOAD_DEBUG) + LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP); - #if defined(ENABLE_MAC_PAYLOAD_DEBUG) - LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP); + for (i = 0; i < 32; i++) + LOG_T(MAC, "%x.", (pduP + mac_subheader_len)[i]); - for (i = 0; i < 32; i++) - LOG_T(MAC, "%x.", (pduP + mac_subheader_len)[i]); + LOG_T(MAC, "\n"); + #endif - LOG_T(MAC, "\n"); - #endif + if (rx_lcid < NB_RB_MAX && rx_lcid >= DL_SCH_LCID_DCCH) { - if (rx_lcid < NB_RB_MAX && rx_lcid >= DL_SCH_LCID_DCCH) { + mac_rlc_data_ind(module_idP, + mac->crnti, + gNB_index, + frameP, + ENB_FLAG_NO, + MBMS_FLAG_NO, + rx_lcid, + (char *) (pduP + mac_subheader_len), + mac_sdu_len, + 1, + NULL); + } else { + LOG_E(MAC, "[UE %d] Frame %d : unknown LCID %d (gNB %d)\n", module_idP, frameP, rx_lcid, gNB_index); + } - mac_rlc_data_ind(module_idP, - mac->crnti, - gNB_index, - frameP, - ENB_FLAG_NO, - MBMS_FLAG_NO, - rx_lcid, - (char *) (pduP + mac_subheader_len), - mac_sdu_len, - 1, - NULL); - } else { - LOG_E(MAC, "[UE %d] Frame %d : unknown LCID %d (gNB %d)\n", module_idP, frameP, rx_lcid, gNB_index); - } - break; + break; + } } pduP += ( mac_subheader_len + mac_ce_len + mac_sdu_len ); pdu_len -= ( mac_subheader_len + mac_ce_len + mac_sdu_len ); @@ -3791,7 +3805,7 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t } } if (rarh->RAPID == preamble_index) { - LOG_I(NR_MAC, "[UE %d][RAPROC][%d.%d] Found RAR with the intended RAPID %d\n", mod_id, frame, slot, rarh->RAPID); + LOG_A(NR_MAC, "[UE %d][RAPROC][%d.%d] Found RAR with the intended RAPID %d\n", mod_id, frame, slot, rarh->RAPID); rar = (NR_MAC_RAR *) (dlsch_buffer + n_subheaders + (n_subPDUs - 1) * sizeof(NR_MAC_RAR)); ra->RA_RAPID_found = 1; break; @@ -3908,6 +3922,8 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t LOG_W(MAC, "In %s: ul_config request is NULL. Probably due to unexpected UL DCI in frame.slot %d.%d. Ignoring DCI!\n", __FUNCTION__, frame, slot); return -1; } + AssertFatal(ul_config->number_pdus < sizeof(ul_config->ul_config_list) / sizeof(ul_config->ul_config_list[0]), + "Number of PDUS in ul_config = %d > ul_config_list num elements", ul_config->number_pdus); // Upon successful reception, set the T-CRNTI to the RAR value if the RA preamble is selected among the contention-based RA Preambles if (!ra->cfra) { diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 3d45877979..5284f7fc53 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -51,6 +51,7 @@ #include "assertions.h" #include "asn1_conversions.h" #include "SIMULATION/TOOLS/sim.h" // for taus +#include "utils.h" #include @@ -60,8 +61,13 @@ static prach_association_pattern_t prach_assoc_pattern; static ssb_list_info_t ssb_list; void fill_ul_config(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx, uint8_t pdu_type){ + + AssertFatal(ul_config->number_pdus < sizeof(ul_config->ul_config_list) / sizeof(ul_config->ul_config_list[0]), + "Number of PDUS in ul_config = %d > ul_config_list num elements", ul_config->number_pdus); // clear ul_config for new frame/slot - if ((ul_config->slot != slot_tx || ul_config->sfn != frame_tx) && ul_config->number_pdus != 0) { + if ((ul_config->slot != slot_tx || ul_config->sfn != frame_tx) && + ul_config->number_pdus != 0 && + !get_softmodem_params()->emulate_l1) { LOG_D(MAC, "%d.%d %d.%d f clear ul_config %p t %d pdu %d\n", frame_tx, slot_tx, ul_config->sfn, ul_config->slot, ul_config, pdu_type, ul_config->number_pdus); ul_config->number_pdus = 0; memset(ul_config->ul_config_list, 0, sizeof(ul_config->ul_config_list)); @@ -166,6 +172,8 @@ fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int sl num_slots_ul, index); + if(!mac->ul_config_request) + return NULL; return &mac->ul_config_request[index]; } @@ -912,6 +920,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in dcireq.slot = rx_slot; dcireq.dl_config_req.number_pdus = 0; nr_ue_dcireq(&dcireq); //to be replaced with function pointer later + mac->dl_config_request = dcireq.dl_config_req; fill_scheduled_response(&scheduled_response, &dcireq.dl_config_req, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id); if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) @@ -948,7 +957,9 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in RA_config_t *ra = &mac->ra; fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slot_tx); - + if (!ul_config) { + LOG_E(NR_MAC, "mac->ul_config is null!\n"); + } // Schedule ULSCH only if the current frame and slot match those in ul_config_req // AND if a UL grant (UL DCI or Msg3) has been received (as indicated by num_pdus) if (ul_config){ @@ -1019,7 +1030,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->gNB_index); } if (ra->ra_state == WAIT_RAR && !ra->cfra){ - LOG_I(NR_MAC,"[RAPROC][%d.%d] RA-Msg3 transmitted\n", frame_tx, slot_tx); + LOG_A(NR_MAC, "[RAPROC][%d.%d] RA-Msg3 transmitted\n", frame_tx, slot_tx); nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->gNB_index); } } @@ -2197,9 +2208,12 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); RA_config_t *ra = &mac->ra; + fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slotP); + if (!ul_config) { + LOG_E(NR_MAC, "mac->ul_config is null! \n"); + return; + } - //fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slotP); - fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request[0]; fapi_nr_ul_config_prach_pdu *prach_config_pdu; fapi_nr_config_request_t *cfg = &mac->phy_config.config_req; fapi_nr_prach_config_t *prach_config = &cfg->prach_config; @@ -2236,11 +2250,13 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s format = prach_occasion_info_p->format; format0 = format & 0xff; // single PRACH format format1 = (format >> 8) & 0xff; // dual PRACH format + AssertFatal(ul_config->number_pdus < sizeof(ul_config->ul_config_list) / sizeof(ul_config->ul_config_list[0]), + "Number of PDUS in ul_config = %d > ul_config_list num elements", ul_config->number_pdus); pthread_mutex_lock(&ul_config->mutex_ul_config); AssertFatal(ul_config->number_pdusnumber_pdus %d out of bounds\n",ul_config->number_pdus); prach_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].prach_config_pdu; - + memset(prach_config_pdu, 0, sizeof(fapi_nr_ul_config_prach_pdu)); fill_ul_config(ul_config, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PRACH); pthread_mutex_unlock(&ul_config->mutex_ul_config); LOG_D(PHY, "In %s: (%p) %d UL PDUs:\n", __FUNCTION__, ul_config, ul_config->number_pdus); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 2705b85b8c..ab3a128021 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -519,10 +519,16 @@ void nr_initiate_ra_proc(module_id_t module_idP, for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) { NR_RA_t *ra = &cc->ra[i]; pr_found = 0; + const int UE_id = find_nr_UE_id(module_idP, ra->rnti); + if (UE_id != -1) { + continue; + } if (ra->state == RA_IDLE) { for(int j = 0; j < ra->preambles.num_preambles; j++) { //check if the preamble received correspond to one of the listed or configured preambles if (preamble_index == ra->preambles.preamble_list[j]) { + if (ra->rnti == 0 && get_softmodem_params()->nsa) + continue; pr_found=1; break; } @@ -1229,7 +1235,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra dl_req->nPDUs+=1; nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15; - LOG_I(NR_MAC,"[gNB %d][RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg2 DCI, rnti 0x%04x, state %d, CoreSetType %d\n", + LOG_A(NR_MAC,"[gNB %d][RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg2 DCI, rnti 0x%x, state %d, CoreSetType %d\n", module_idP, CC_id, frameP, slotP, ra->RA_rnti, ra->state,pdcch_pdu_rel15->CoreSetType); // SCF222: PDU index incremented for each PDSCH PDU sent in TX control message. This is used to associate control @@ -1624,7 +1630,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra dl_req->nPDUs+=1; nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15; - LOG_I(NR_MAC,"[gNB %d] [RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg4 DCI, state %d\n", module_idP, CC_id, frameP, slotP, ra->state); + LOG_A(NR_MAC, "[gNB %d] [RAPROC] CC_id %d Frame %d, slotP %d: Generating RA-Msg4 DCI, state %d\n", module_idP, CC_id, frameP, slotP, ra->state); // SCF222: PDU index incremented for each PDSCH PDU sent in TX control message. This is used to associate control // information to data and is reset every slot. @@ -1809,7 +1815,7 @@ void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_fram if (harq->is_waiting == 0) { if (harq->round == 0) { if (stats->dlsch_errors == 0) { - LOG_I(NR_MAC, "(ue %i, rnti 0x%04x) Received Ack of RA-Msg4. CBRA procedure succeeded!\n", UE_id, ra->rnti); + LOG_A(NR_MAC, "(ue %i, rnti 0x%04x) Received Ack of RA-Msg4. CBRA procedure succeeded!\n", UE_id, ra->rnti); UE_info->active[UE_id] = true; UE_info->Msg4_ACKed[UE_id] = true; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index f9209f4cfe..ea298494c4 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -741,6 +741,11 @@ void pf_dl(module_id_t module_id, const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth,MAX_BWP_SIZE); int rbStart = 0; // start wrt BWPstart + if (sched_ctrl->available_dl_harq.head < 0) { + LOG_D(MAC, "UE %d RNTI %04x has no free HARQ process, skipping\n", UE_id, UE_info->rnti[UE_id]); + continue; + } + /* Find a free CCE */ bool freeCCE = find_free_CCE(module_id, slot, UE_id); if (!freeCCE) { @@ -851,7 +856,7 @@ void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t frame, slot, &UE_info->list, - 2, + MAX_MOBILES_PER_GNB, n_rb_sched, rballoc_mask); } @@ -997,6 +1002,7 @@ void nr_schedule_ue_spec(module_id_t module_id, const int coresetid = (bwp||bwpd) ? sched_ctrl->coreset->controlResourceSetId : gNB_mac->sched_ctrlCommon->coreset->controlResourceSetId; nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu = gNB_mac->pdcch_pdu_idx[CC_id][bwpid][coresetid]; if (!pdcch_pdu) { + LOG_D(NR_MAC, "creating pdcch pdu, pdcch_pdu = NULL. \n"); nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; memset(dl_tti_pdcch_pdu, 0, sizeof(nfapi_nr_dl_tti_request_pdu_t)); dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index 3b29616211..ca641ed1ba 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -563,6 +563,7 @@ void nr_csi_meas_reporting(int Mod_idP, } } +__attribute__((unused)) static void handle_dl_harq(module_id_t mod_id, int UE_id, int8_t harq_pid, @@ -1094,8 +1095,10 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id, const uint8_t harq_value = uci_01->harq->harq_list[harq_bit].harq_value; const uint8_t harq_confidence = uci_01->harq->harq_confidence_level; NR_UE_harq_t *harq = find_harq(mod_id, frame, slot, UE_id); - if (!harq) + if (!harq) { + LOG_E(NR_MAC, "Oh no! Could not find a harq in %s!\n", __FUNCTION__); break; + } DevAssert(harq->is_waiting); const int8_t pid = sched_ctrl->feedback_dl_harq.head; remove_front_nr_list(&sched_ctrl->feedback_dl_harq); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index c68b16b553..bde6c6109d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -32,6 +32,7 @@ #include "LAYER2/NR_MAC_gNB/mac_proto.h" #include "executables/softmodem-common.h" #include "common/utils/nr/nr_common.h" +#include "utils.h" #include #include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h" @@ -565,6 +566,7 @@ void handle_nr_ul_harq(const int CC_idP, NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info; NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; int8_t harq_pid = sched_ctrl->feedback_ul_harq.head; + LOG_D(NR_MAC, "Comparing crc_pdu->harq_id vs feedback harq_pid = %d %d\n",crc_pdu->harq_id, harq_pid); while (crc_pdu->harq_id != harq_pid || harq_pid < 0) { LOG_W(NR_MAC, "Unexpected ULSCH HARQ PID %d (have %d) for RNTI 0x%04x (ignore this warning for RA)\n", @@ -800,14 +802,14 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, LOG_D(NR_MAC, "[UE %d] PUSCH TPC %d and TA %d\n",UE_id,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update); if(ra->cfra) { - LOG_I(NR_MAC, "(ue %i, rnti 0x%04x) CFRA procedure succeeded!\n", UE_id, ra->rnti); + LOG_A(NR_MAC, "(ue %i, rnti 0x%04x) CFRA procedure succeeded!\n", UE_id, ra->rnti); nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti); nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); UE_info->active[UE_id] = true; } else { - LOG_I(NR_MAC,"[RAPROC] RA-Msg3 received (sdu_lenP %d)\n",sdu_lenP); + LOG_A(NR_MAC,"[RAPROC] RA-Msg3 received (sdu_lenP %d)\n",sdu_lenP); LOG_D(NR_MAC,"[RAPROC] Received Msg3:\n"); for (int k = 0; k < sdu_lenP; k++) { LOG_D(NR_MAC,"(%i): 0x%x\n",k,sduP[k]); @@ -1491,6 +1493,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static; /* Statistics */ + AssertFatal(cur_harq->round < 8, "Indexing ulsch_rounds[%d] is out of bounds\n", cur_harq->round); UE_info->mac_stats[UE_id].ulsch_rounds[cur_harq->round]++; if (cur_harq->round == 0) { UE_info->mac_stats[UE_id].ulsch_total_bytes_scheduled += sched_pusch->tb_size; @@ -1624,6 +1627,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) pusch_pdu->nr_of_symbols = ps->nrOfSymbols; /* PUSCH PDU */ + AssertFatal(cur_harq->round < 4, "Indexing nr_rv_round_map[%d] is out of bounds\n", cur_harq->round); pusch_pdu->pusch_data.rv_index = nr_rv_round_map[cur_harq->round]; pusch_pdu->pusch_data.harq_process_id = harq_id; pusch_pdu->pusch_data.new_data_indicator = cur_harq->ndi; diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 8d8b734b44..4d2e157728 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -1127,7 +1127,7 @@ pdcp_data_ind( * for the UE compiled in noS1 mode, we need 0 * TODO: be sure of this */ - if (NFAPI_MODE == NFAPI_UE_STUB_PNF ) { + if (NFAPI_MODE == NFAPI_UE_STUB_PNF || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF) { pdcpHead->inst = ctxt_pP->module_id; } else { // nfapi_mode if (UE_NAS_USE_TUN) { @@ -1343,7 +1343,7 @@ pdcp_run ( // IP/NAS -> PDCP traffic : TX, read the pkt from the upper layer buffer // if (LINK_ENB_PDCP_TO_GTPV1U && ctxt_pP->enb_flag == ENB_FLAG_NO) { - if (!EPC_MODE_ENABLED || ctxt_pP->enb_flag == ENB_FLAG_NO ) { + if (!get_softmodem_params()->emulate_l1 && (!EPC_MODE_ENABLED || ctxt_pP->enb_flag == ENB_FLAG_NO)) { pdcp_fifo_read_input_sdus(ctxt_pP); } @@ -1353,8 +1353,9 @@ pdcp_run ( } else { start_meas(&UE_pdcp_stats[ctxt_pP->module_id].pdcp_ip); } - - pdcp_fifo_flush_sdus(ctxt_pP); + if (!get_softmodem_params()->emulate_l1) { + pdcp_fifo_flush_sdus(ctxt_pP); + } if (ctxt_pP->enb_flag) { stop_meas(&eNB_pdcp_stats[ctxt_pP->module_id].pdcp_ip); @@ -2397,7 +2398,7 @@ void pdcp_set_pdcp_data_ind_func(pdcp_data_ind_func_t pdcp_data_ind) { pdcp_params.pdcp_data_ind_func = pdcp_data_ind; } -uint64_t pdcp_module_init( uint64_t pdcp_optmask ) { +uint64_t pdcp_module_init( uint64_t pdcp_optmask, int id) { /* temporary enforce netlink when UE_NAS_USE_TUN is set, this is while switching from noS1 as build option to noS1 as config option */ @@ -2414,18 +2415,18 @@ uint64_t pdcp_module_init( uint64_t pdcp_optmask ) { nas_getparams(); if(UE_NAS_USE_TUN) { - int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 )? MAX_MOBILES_PER_ENB : 1; - netlink_init_tun("ue",num_if); + int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF)? MAX_MOBILES_PER_ENB : 1; + netlink_init_tun("ue",num_if, id); if (IS_SOFTMODEM_NOS1) - nas_config(1, 1, 2, "ue"); - netlink_init_mbms_tun("uem"); + nas_config(1, 1, 2, "ue"); + netlink_init_mbms_tun("uem", id); nas_config_mbms(1, 2, 2, "uem"); LOG_I(PDCP, "UE pdcp will use tun interface\n"); } else if(ENB_NAS_USE_TUN) { - netlink_init_tun("enb",1); + netlink_init_tun("enb", 1, 0); nas_config(1, 1, 1, "enb"); if(pdcp_optmask & ENB_NAS_USE_TUN_W_MBMS_BIT){ - netlink_init_mbms_tun("enm"); + netlink_init_mbms_tun("enm", 0); nas_config_mbms(1, 2, 1, "enm"); LOG_I(PDCP, "ENB pdcp will use mbms tun interface\n"); } @@ -2437,8 +2438,8 @@ uint64_t pdcp_module_init( uint64_t pdcp_optmask ) { }else{ if(pdcp_optmask & ENB_NAS_USE_TUN_W_MBMS_BIT){ LOG_W(PDCP, "ENB pdcp will use tun interface for MBMS\n"); - netlink_init_mbms_tun("enm"); - nas_config_mbms_s1(1, 2, 1, "enm"); + netlink_init_mbms_tun("enm", 0); + nas_config_mbms_s1(1, 2, 1, "enm"); }else LOG_E(PDCP, "ENB pdcp will not use tun interface\n"); } @@ -2480,6 +2481,7 @@ pdcp_free ( void pdcp_module_cleanup (void) //----------------------------------------------------------------------------- { + netlink_cleanup(); } //----------------------------------------------------------------------------- diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h index 7f4640ede1..332ee382d7 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h @@ -56,6 +56,7 @@ typedef boolean_t (pdcp_data_ind_t)( const protocol_ctxt_t *, const srb_flag_t, mem_block_t *,const uint32_t *const, const uint32_t *const); typedef pdcp_data_ind_t* pdcp_data_ind_func_t; +#define MAX_NUMBER_NETIF 1 //16 #define ENB_NAS_USE_TUN_W_MBMS_BIT (1<< 10) #define PDCP_USE_NETLINK_BIT (1<< 11) #define LINK_ENB_PDCP_TO_IP_DRIVER_BIT (1<< 13) @@ -410,7 +411,8 @@ void pdcp_mbms_run ( */ void pdcp_run ( const protocol_ctxt_t *const ctxt_pP); -uint64_t pdcp_module_init (uint64_t pdcp_optmask); +uint64_t pdcp_module_init (uint64_t pdcp_optmask, int ue_id); +uint64_t nr_pdcp_module_init(uint64_t _pdcp_optmask, int id); void pdcp_module_cleanup (void); void nr_ip_over_LTE_DRB_preconfiguration (void); void pdcp_layer_init (void); diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index 05e77a935d..b49b020428 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -89,7 +89,7 @@ extern struct msghdr nas_msg_rx; extern int gtpv1u_new_data_req( uint8_t enb_module_idP, rnti_t ue_rntiP, uint8_t rab_idP, uint8_t *buffer_pP, uint32_t buf_lenP, uint32_t buf_offsetP); - +uint16_t ue_id_g; // Global variable to identify the ID for each UE. It is updated in main() of lte-uesoftmodem.c void debug_pdcp_pc5s_sdu(sidelink_pc5s_element *sl_pc5s_msg, char *title) { LOG_I(PDCP,"%s: \nPC5S message, header traffic_type: %d)\n", title, sl_pc5s_msg->pc5s_header.traffic_type); @@ -210,14 +210,46 @@ int pdcp_fifo_read_input_sdus_fromtun (const protocol_ctxt_t *const ctxt_pP) { pdcp_t *pdcp_p = NULL; int len; rb_id_t rab_id = DEFAULT_RAB_ID; + int sockd; - do { + if (UE_NAS_USE_TUN) { + if (ue_id_g == 0) { + sockd = nas_sock_fd[ctxt_pP->module_id]; + } + else { + sockd = nas_sock_fd[ue_id_g]; + } + } + else { + sockd = nas_sock_fd[0]; + } + + for (;;) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ, 1 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 1 ); - len = read(UE_NAS_USE_TUN?nas_sock_fd[ctxt_pP->module_id]:nas_sock_fd[0], &nl_rx_buf, NL_MAX_PAYLOAD); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 0 ); + len = read(sockd, &nl_rx_buf, NL_MAX_PAYLOAD); - if (len<=0) continue; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER, 0 ); + if (len == -1) { + if (errno == EAGAIN) { + LOG_D(PDCP, "Error reading NAS socket: %s\n", strerror(errno)); + } + else { + LOG_E(PDCP, "Error reading NAS socket: %s\n", strerror(errno)); + } + break; + } + /* Check for message truncation. Strictly speaking if the packet is exactly sizeof(nl_rx_buf) bytes + that would not be an error. But we cannot distinguish that from a packet > sizeof(nl_rx_buf) */ + if (len == sizeof(nl_rx_buf)) + { + LOG_E(PDCP, "%s(%d). Message truncated %d\n", __FUNCTION__, __LINE__, len); + break; + } + if (len == 0) { + LOG_E(PDCP, "EOF Reading NAS socket\n"); + break; + } if (UE_NAS_USE_TUN) { key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag); @@ -263,7 +295,7 @@ int pdcp_fifo_read_input_sdus_fromtun (const protocol_ctxt_t *const ctxt_pP) { ctxt.frame, ctxt.instance, rab_id, len, ctxt.module_id, ctxt.rnti, rab_id, key); } - } while (len > 0); + } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ, 0 ); return len; @@ -474,8 +506,12 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx // never finished code, dropped } } else { // ctxt.enb_flag => UE - if (NFAPI_MODE == NFAPI_UE_STUB_PNF) { + if (NFAPI_MODE == NFAPI_UE_STUB_PNF || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF) { +#ifdef UESIM_EXPANSION + ctxt.module_id = inst_pdcp_list[pdcp_read_header_g.inst]; +#else ctxt.module_id = pdcp_read_header_g.inst; +#endif } else { ctxt.module_id = 0; } @@ -526,8 +562,8 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx pdcp_read_header_g.data_size, (unsigned char *)NLMSG_DATA(nas_nlh_rx), PDCP_TRANSMISSION_MODE_DATA, - (NFAPI_MODE == NFAPI_UE_STUB_PNF)?NULL:&pdcp_read_header_g.sourceL2Id, - (NFAPI_MODE == NFAPI_UE_STUB_PNF)?NULL:&pdcp_read_header_g.destinationL2Id + (NFAPI_MODE == NFAPI_UE_STUB_PNF || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF) ? NULL : &pdcp_read_header_g.sourceL2Id, + (NFAPI_MODE == NFAPI_UE_STUB_PNF || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF) ? NULL : &pdcp_read_header_g.destinationL2Id ); } else { /* else of h_rc == HASH_TABLE_OK */ MSC_LOG_RX_DISCARDED_MESSAGE( @@ -571,8 +607,8 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx pdcp_read_header_g.data_size, (unsigned char *)NLMSG_DATA(nas_nlh_rx), PDCP_TRANSMISSION_MODE_DATA, - (NFAPI_MODE == NFAPI_UE_STUB_PNF) ? NULL :&pdcp_read_header_g.sourceL2Id, - (NFAPI_MODE == NFAPI_UE_STUB_PNF) ? NULL :&pdcp_read_header_g.destinationL2Id + (NFAPI_MODE == NFAPI_UE_STUB_PNF|| NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF) ? NULL : &pdcp_read_header_g.sourceL2Id, + (NFAPI_MODE == NFAPI_UE_STUB_PNF|| NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF) ? NULL : &pdcp_read_header_g.destinationL2Id ); } /* rab_id == 0 */ } /*pdcp_read_state_g != 0 */ @@ -597,35 +633,45 @@ void pdcp_fifo_read_input_sdus_frompc5s (const protocol_ctxt_t *const ctxt_pP) /* avoid gcc warnings */ (void)data_p; pdcp_t *pdcp_p = NULL; - //TTN for D2D (PC5S) - int prose_addr_len = sizeof(prose_pdcp_addr); - char send_buf[BUFSIZE], receive_buf[BUFSIZE]; - //int optval; int bytes_received; sidelink_pc5s_element *sl_pc5s_msg_send = NULL; pc5s_header_t *pc5s_header = NULL; rb_id_t rab_id = 0; //TTN for D2D (PC5S) // receive a message from ProSe App - memset(receive_buf, 0, BUFSIZE); - bytes_received = recvfrom(pdcp_pc5_sockfd, receive_buf, BUFSIZE, 0, - (struct sockaddr *) &prose_pdcp_addr, (socklen_t *)&prose_addr_len); - + char receive_buf[MAX_MESSAGE_SIZE]; + memset(receive_buf, 0, sizeof(receive_buf)); + socklen_t prose_addr_len = sizeof(prose_pdcp_addr); + bytes_received = recvfrom(pdcp_pc5_sockfd, receive_buf, sizeof(receive_buf), MSG_TRUNC, + (struct sockaddr *) &prose_pdcp_addr, &prose_addr_len); + if (bytes_received == -1) { + LOG_E(PDCP, "%s(%d). recvfrom failed. %s\n", __FUNCTION__, __LINE__, strerror(errno)); + return; + } + if (bytes_received == 0) { + LOG_E(PDCP, "%s(%d). EOF pdcp_pc5_sockfd.\n", __FUNCTION__, __LINE__); + } + if (bytes_received > sizeof(receive_buf)) { + LOG_E(PDCP, "%s(%d). Message truncated. %d\n", __FUNCTION__, __LINE__, bytes_received); + return; + } if (bytes_received > 0) { pc5s_header = calloc(1, sizeof(pc5s_header_t)); memcpy((void *)pc5s_header, (void *)receive_buf, sizeof(pc5s_header_t)); + char send_buf[MAX_MESSAGE_SIZE]; switch(pc5s_header->traffic_type) { case TRAFFIC_PC5S_SESSION_INIT : //send reply to ProSe app LOG_D(PDCP,"Received a request to open PDCP socket and establish a new PDCP session ... send response to ProSe App \n"); - memset(send_buf, 0, BUFSIZE); + memset(send_buf, 0, sizeof(send_buf)); sl_pc5s_msg_send = calloc(1, sizeof(sidelink_pc5s_element)); sl_pc5s_msg_send->pc5s_header.traffic_type = TRAFFIC_PC5S_SESSION_INIT; sl_pc5s_msg_send->pc5sPrimitive.status = 1; - memcpy((void *)send_buf, (void *)sl_pc5s_msg_send, sizeof(sidelink_pc5s_element)); + memcpy(send_buf, sl_pc5s_msg_send, sizeof(sidelink_pc5s_element)); int prose_addr_len = sizeof(prose_pdcp_addr); - int bytes_sent = sendto(pdcp_pc5_sockfd, (char *)send_buf, sizeof(sidelink_pc5s_element), 0, (struct sockaddr *)&prose_pdcp_addr, prose_addr_len); + int bytes_sent = sendto(pdcp_pc5_sockfd, send_buf, sizeof(sidelink_pc5s_element), 0, + (struct sockaddr *) &prose_pdcp_addr, prose_addr_len); free (sl_pc5s_msg_send); if (bytes_sent < 0) { diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index 322c39c49b..ab8578a0e7 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -556,7 +556,7 @@ void pdcp_layer_init(void) #include "targets/RT/USER/lte-softmodem.h" #include "openair2/RRC/NAS/nas_config.h" -uint64_t pdcp_module_init(uint64_t _pdcp_optmask) +uint64_t nr_pdcp_module_init(uint64_t _pdcp_optmask, int id) { /* hack: be sure to initialize only once */ static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; @@ -588,16 +588,18 @@ uint64_t pdcp_module_init(uint64_t _pdcp_optmask) nas_getparams(); if(UE_NAS_USE_TUN) { - int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 )? MAX_MOBILES_PER_ENB : 1; - netlink_init_tun("ue",num_if); + char *ifsuffix_ue = get_softmodem_params()->nsa ? "nrue" : "ue"; + int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF)? MAX_MOBILES_PER_ENB : 1; + netlink_init_tun(ifsuffix_ue, num_if, id); //Add --nr-ip-over-lte option check for next line if (IS_SOFTMODEM_NOS1) - nas_config(1, 1, 2, "ue"); + nas_config(1, 1, !get_softmodem_params()->nsa ? 2 : 3, ifsuffix_ue); LOG_I(PDCP, "UE pdcp will use tun interface\n"); start_pdcp_tun_ue(); } else if(ENB_NAS_USE_TUN) { - netlink_init_tun("enb",1); - nas_config(1, 1, 1, "enb"); + char *ifsuffix_base_s = get_softmodem_params()->nsa ? "gnb" : "enb"; + netlink_init_tun(ifsuffix_base_s, 1, id); + nas_config(1, 1, 1, ifsuffix_base_s); LOG_I(PDCP, "ENB pdcp will use tun interface\n"); start_pdcp_tun_enb(); } else { @@ -620,7 +622,7 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity, int rb_id; int i; - if(IS_SOFTMODEM_NOS1 || UE_NAS_USE_TUN){ + if (IS_SOFTMODEM_NOS1 || UE_NAS_USE_TUN) { LOG_D(PDCP, "IP packet received, to be sent to TUN interface"); if(entity->has_sdapDLheader){ @@ -631,7 +633,7 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity, } if (len != size) { - LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + LOG_E(PDCP, "%s:%d:%s: fatal error %d: %s\n", __FILE__, __LINE__, __FUNCTION__, errno, strerror(errno)); } } @@ -1186,7 +1188,7 @@ void nr_DRB_preconfiguration(uint16_t crnti) NR_RLC_BearerConfig_t *RLC_BearerConfig = calloc(1,sizeof(*RLC_BearerConfig)); nr_rlc_bearer_init(RLC_BearerConfig,NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity); - nr_drb_config(RLC_BearerConfig->rlc_Config, NR_RLC_Config_PR_um_Bi_Directional); + nr_drb_config(RLC_BearerConfig->rlc_Config, NR_RLC_Config_PR_am); nr_rlc_bearer_init_ul_spec(RLC_BearerConfig->mac_LogicalChannelConfig); Rlc_Bearer_ToAdd_list = calloc(1,sizeof(*Rlc_Bearer_ToAdd_list)); diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 7d2ce30494..78e06d37e2 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -530,6 +530,7 @@ rb_found: exit(1); } memcpy(memblock->data, buf, size); + LOG_D(PDCP, "Calling PDCP layer from RLC in %s\n", __FUNCTION__); if (!pdcp_data_ind(&ctx, is_srb, 0, rb_id, size, memblock, NULL, NULL)) { LOG_E(RLC, "%s:%d:%s: ERROR: pdcp_data_ind failed\n", __FILE__, __LINE__, __FUNCTION__); /* what to do in case of failure? for the moment: nothing */ diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index cb5bef5ab0..db992579f8 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -37,6 +37,8 @@ #include "common/ran_context.h" #include "executables/softmodem-common.h" #include "nfapi/oai_integration/vendor_ext.h" +#include "nfapi/oai_integration/gnb_ind_vars.h" +#include "openair2/PHY_INTERFACE/queue_t.h" #define MAX_IF_MODULES 100 //#define UL_HARQ_PRINT @@ -58,150 +60,371 @@ extern uint8_t nfapi_mode; extern uint16_t sf_ahead; extern uint16_t sl_ahead; -void handle_nr_rach(NR_UL_IND_t *UL_info) { + +void handle_nr_rach(NR_UL_IND_t *UL_info) +{ if(NFAPI_MODE == NFAPI_MODE_PNF) { - if (UL_info->rach_ind.number_of_pdus>0) { + if (UL_info->rach_ind.number_of_pdus > 0) { LOG_D(PHY,"UL_info->UL_info->rach_ind.number_of_pdus:%d SFN/Slot:%d.%d \n", UL_info->rach_ind.number_of_pdus, UL_info->rach_ind.sfn,UL_info->rach_ind.slot); oai_nfapi_nr_rach_indication(&UL_info->rach_ind); UL_info->rach_ind.number_of_pdus = 0; } + return; } - else{ - if (UL_info->rach_ind.number_of_pdus>0) { - LOG_D(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SLOT:%d/%d\n",UL_info->frame,UL_info->slot, UL_info->rach_ind.sfn,UL_info->rach_ind.slot); - int npdus = UL_info->rach_ind.number_of_pdus; - for(int i = 0; i < npdus; i++) { - UL_info->rach_ind.number_of_pdus--; - if (UL_info->rach_ind.pdu_list[i].num_preamble>0) - AssertFatal(UL_info->rach_ind.pdu_list[i].num_preamble==1, - "More than 1 preamble not supported\n"); - - nr_initiate_ra_proc(UL_info->module_id, - UL_info->CC_id, - UL_info->rach_ind.sfn, - UL_info->rach_ind.slot, - UL_info->rach_ind.pdu_list[i].preamble_list[0].preamble_index, - UL_info->rach_ind.pdu_list[i].freq_index, - UL_info->rach_ind.pdu_list[i].symbol_index, - UL_info->rach_ind.pdu_list[i].preamble_list[0].timing_advance); - } + NR_UL_IND_t UL_INFO; + nfapi_nr_rach_indication_t *rach_ind = NULL; + if (get_softmodem_params()->emulate_l1) + { + if (gnb_rach_ind_queue.num_items == 0) + return; + LOG_I(NR_MAC, "gnb_rach_ind_queue size = %zu\n", gnb_rach_ind_queue.num_items); + rach_ind = get_queue(&gnb_rach_ind_queue); + + UL_INFO.rach_ind = *rach_ind; + UL_INFO.module_id = UL_info->module_id; + UL_INFO.CC_id = UL_info->CC_id; + } + else + { + UL_INFO.rach_ind = UL_info->rach_ind; + UL_INFO.module_id = UL_info->module_id; + UL_INFO.CC_id = UL_info->CC_id; + } + + int frame_diff = UL_info->frame - UL_INFO.rach_ind.sfn; + if (frame_diff < 0) + { + frame_diff += 1024; + } + bool in_timewindow = frame_diff == 0 || (frame_diff == 1 && UL_info->slot < 7); + + if (UL_INFO.rach_ind.number_of_pdus>0 && in_timewindow) { + LOG_A(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SLOT:%d/%d\n", + UL_info->frame, UL_info->slot, UL_INFO.rach_ind.sfn, UL_INFO.rach_ind.slot); + int npdus = UL_INFO.rach_ind.number_of_pdus; + for(int i = 0; i < npdus; i++) { + UL_INFO.rach_ind.number_of_pdus--; + if (UL_INFO.rach_ind.pdu_list[i].num_preamble>0) + AssertFatal(UL_INFO.rach_ind.pdu_list[i].num_preamble==1, + "More than 1 preamble not supported\n"); + + nr_initiate_ra_proc(UL_INFO.module_id, + UL_INFO.CC_id, + UL_INFO.rach_ind.sfn, + UL_INFO.rach_ind.slot, + UL_INFO.rach_ind.pdu_list[i].preamble_list[0].preamble_index, + UL_INFO.rach_ind.pdu_list[i].freq_index, + UL_INFO.rach_ind.pdu_list[i].symbol_index, + UL_INFO.rach_ind.pdu_list[i].preamble_list[0].timing_advance); } } + if (get_softmodem_params()->emulate_l1) + { + if (rach_ind && rach_ind->number_of_pdus > 0) + { + for(int i = 0; i < rach_ind->number_of_pdus; i++) + { + free(rach_ind->pdu_list[i].preamble_list); + rach_ind->pdu_list[i].preamble_list = NULL; + } + free(rach_ind->pdu_list); + rach_ind->pdu_list = NULL; + } + free(rach_ind); + rach_ind = NULL; + } } void handle_nr_uci(NR_UL_IND_t *UL_info) -{ +{ if(NFAPI_MODE == NFAPI_MODE_PNF) { - if (UL_info->uci_ind.num_ucis>0) { + if (UL_info->uci_ind.num_ucis > 0) { LOG_D(PHY,"PNF Sending UL_info->num_ucis:%d PDU_type: %d, SFN/SF:%d.%d \n", UL_info->uci_ind.num_ucis, UL_info->uci_ind.uci_list[0].pdu_type ,UL_info->frame, UL_info->slot); oai_nfapi_nr_uci_indication(&UL_info->uci_ind); UL_info->uci_ind.num_ucis = 0; } + return; } - else{ - const module_id_t mod_id = UL_info->module_id; - const frame_t frame = UL_info->frame; - const sub_frame_t slot = UL_info->slot; - int num_ucis = UL_info->uci_ind.num_ucis; - nfapi_nr_uci_t *uci_list = UL_info->uci_ind.uci_list; - LOG_D(MAC,"handling UCI SFN/slot: %d.%d, num_ucis: %d \n", frame,slot, num_ucis); - for (int i = 0; i < num_ucis; i++) { - switch (uci_list[i].pdu_type) { - case NFAPI_NR_UCI_PUSCH_PDU_TYPE: - LOG_E(MAC, "%s(): unhandled NFAPI_NR_UCI_PUSCH_PDU_TYPE\n", __func__); - break; - case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: { - const nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &uci_list[i].pucch_pdu_format_0_1; - handle_nr_uci_pucch_0_1(mod_id, frame, slot, uci_pdu); - break; - } + NR_UL_IND_t UL_INFO; + nfapi_nr_uci_indication_t *uci_ind = NULL; + if (get_softmodem_params()->emulate_l1) + { + if (gnb_uci_ind_queue.num_items == 0) + return; + LOG_I(NR_MAC, "gnb_uci_ind_queue size = %zu\n", gnb_uci_ind_queue.num_items); + uci_ind = get_queue(&gnb_uci_ind_queue); + UL_INFO.uci_ind = *uci_ind; + } + else + { + UL_INFO.uci_ind = UL_info->uci_ind; + } + + const module_id_t mod_id = UL_info->module_id; + const frame_t frame = UL_INFO.uci_ind.sfn; + const sub_frame_t slot = UL_INFO.uci_ind.slot; + int num_ucis = UL_INFO.uci_ind.num_ucis; + nfapi_nr_uci_t *uci_list = UL_INFO.uci_ind.uci_list; + + for (int i = 0; i < num_ucis; i++) { + switch (uci_list[i].pdu_type) { + case NFAPI_NR_UCI_PUSCH_PDU_TYPE: + LOG_E(MAC, "%s(): unhandled NFAPI_NR_UCI_PUSCH_PDU_TYPE\n", __func__); + break; + + case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: { + const nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &uci_list[i].pucch_pdu_format_0_1; + LOG_D(NR_MAC, "The received uci has sfn slot %d %d, num_ucis %d and pdu_size %d\n", + UL_INFO.uci_ind.sfn, UL_INFO.uci_ind.slot, num_ucis, uci_list[i].pdu_size); + handle_nr_uci_pucch_0_1(mod_id, frame, slot, uci_pdu); + break; + } case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: { const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu = &uci_list[i].pucch_pdu_format_2_3_4; handle_nr_uci_pucch_2_3_4(mod_id, frame, slot, uci_pdu); break; } - } LOG_D(MAC, "UCI handled \n"); } } - UL_info->uci_ind.num_ucis = 0; + if (get_softmodem_params()->emulate_l1) + { + for (int i = 0; i < num_ucis; i++) { + switch (uci_list[i].pdu_type) { + case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: + if (uci_list[i].pucch_pdu_format_0_1.harq) { + free(uci_list[i].pucch_pdu_format_0_1.harq->harq_list); + uci_list[i].pucch_pdu_format_0_1.harq->harq_list = NULL; + } + free(uci_list[i].pucch_pdu_format_0_1.harq); + uci_list[i].pucch_pdu_format_0_1.harq = NULL; + free(uci_list[i].pucch_pdu_format_0_1.sr); + uci_list[i].pucch_pdu_format_0_1.sr = NULL; + break; + + case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: + free(uci_list[i].pucch_pdu_format_2_3_4.harq.harq_payload); + free(uci_list[i].pucch_pdu_format_2_3_4.csi_part1.csi_part1_payload); + free(uci_list[i].pucch_pdu_format_2_3_4.csi_part2.csi_part2_payload); + break; + } + } + if (uci_ind && num_ucis > 0) { + free(uci_list); + uci_list = NULL; + } + free(uci_ind); + uci_ind = NULL; + } + else + { + UL_info->uci_ind.num_ucis = 0; + } +} + +static bool crc_sfn_slot_matcher(void *wanted, void *candidate) +{ + nfapi_p7_message_header_t *msg = candidate; + int sfn_sf = *(int*)wanted; + + switch (msg->message_id) + { + case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION: + { + nfapi_nr_crc_indication_t *ind = candidate; + return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->sfn && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->slot; + } + + default: + LOG_E(NR_MAC, "sfn_slot_match bad ID: %d\n", msg->message_id); + + } + return false; } void handle_nr_ulsch(NR_UL_IND_t *UL_info) { if(NFAPI_MODE == NFAPI_MODE_PNF) { - if (UL_info->crc_ind.number_crcs>0) { + if (UL_info->crc_ind.number_crcs > 0) { LOG_D(PHY,"UL_info->UL_info->crc_ind.number_crcs:%d CRC_IND:SFN/Slot:%d.%d\n", UL_info->crc_ind.number_crcs, UL_info->crc_ind.sfn, UL_info->crc_ind.slot); oai_nfapi_nr_crc_indication(&UL_info->crc_ind); UL_info->crc_ind.number_crcs = 0; } - if (UL_info->rx_ind.number_of_pdus>0) { + if (UL_info->rx_ind.number_of_pdus > 0) { LOG_D(PHY,"UL_info->rx_ind.number_of_pdus:%d RX_IND:SFN/Slot:%d.%d \n", UL_info->rx_ind.number_of_pdus, UL_info->rx_ind.sfn, UL_info->rx_ind.slot); oai_nfapi_nr_rx_data_indication(&UL_info->rx_ind); UL_info->rx_ind.number_of_pdus = 0; } + return; } - else{ - if (UL_info->rx_ind.number_of_pdus > 0 && UL_info->crc_ind.number_crcs > 0) { - for (int i = 0; i < UL_info->rx_ind.number_of_pdus; i++) { - for (int j = 0; j < UL_info->crc_ind.number_crcs; j++) { - // find crc_indication j corresponding rx_indication i - const nfapi_nr_rx_data_pdu_t *rx = &UL_info->rx_ind.pdu_list[i]; - const nfapi_nr_crc_t *crc = &UL_info->crc_ind.crc_list[j]; - LOG_D(PHY, - "UL_info->crc_ind.pdu_list[%d].rnti:%04x " - "UL_info->rx_ind.pdu_list[%d].rnti:%04x\n", - j, - crc->rnti, - i, - rx->rnti); - if (crc->rnti != rx->rnti) - continue; + NR_UL_IND_t UL_INFO; + nfapi_nr_rx_data_indication_t *rx_ind = NULL; + nfapi_nr_crc_indication_t *crc_ind = NULL; + if (get_softmodem_params()->emulate_l1) + { + rx_ind = get_queue(&gnb_rx_ind_queue); + if (!rx_ind) + { + LOG_D(NR_PHY, "No rx data indication (empty gnb_rx_ind_queue)\n"); + return; + } - LOG_D(MAC, - "%4d.%2d Calling rx_sdu (CRC %s/tb_crc_status %d)\n", - UL_info->frame, - UL_info->slot, - crc->tb_crc_status ? "error" : "ok", - crc->tb_crc_status); + int sfn_slot = NFAPI_SFNSLOT2HEX(rx_ind->sfn, rx_ind->slot); + + crc_ind = unqueue_matching(&gnb_crc_ind_queue, + MAX_QUEUE_SIZE, + crc_sfn_slot_matcher, + &sfn_slot); + if (!crc_ind) + { + LOG_D(NR_PHY, "No crc indication with the same SFN SLOT of rx indication %u %u\n", rx_ind->sfn, rx_ind->slot); + put_queue(&gnb_rx_ind_queue, rx_ind); + return; + } - /* if CRC passes, pass PDU, otherwise pass NULL as error indication */ - nr_rx_sdu(UL_info->module_id, - UL_info->CC_id, - UL_info->rx_ind.sfn, - UL_info->rx_ind.slot, - rx->rnti, - crc->tb_crc_status ? NULL : rx->pdu, - rx->pdu_length, - rx->timing_advance, - rx->ul_cqi, - rx->rssi); - handle_nr_ul_harq(UL_info->CC_id, UL_info->module_id, UL_info->frame, UL_info->slot, crc); - break; - } // for (j=0;jcrc_ind.number_crcs;j++) - } // for (i=0;irx_ind.number_of_pdus;i++) + UL_INFO.rx_ind = *rx_ind; + UL_INFO.crc_ind = *crc_ind; + UL_INFO.module_id = UL_info->module_id; + UL_INFO.CC_id = UL_info->CC_id; + } + else + { + UL_INFO.rx_ind = UL_info->rx_ind; + UL_INFO.crc_ind = UL_info->crc_ind; + UL_INFO.module_id = UL_info->module_id; + UL_INFO.CC_id = UL_info->CC_id; + } + UL_INFO.frame = UL_INFO.rx_ind.sfn; + UL_INFO.slot = UL_INFO.rx_ind.slot; + UL_INFO.module_id = UL_info->module_id; + UL_INFO.CC_id = UL_info->CC_id; + LOG_D(NR_MAC, " UL_info frame slot vs rx_ind frame slot vs crc_ind slot frame slot = %u %u vs %u %u vs %u %u\n", + UL_info->frame, UL_info->slot, + UL_INFO.rx_ind.sfn, UL_INFO.rx_ind.slot, + UL_INFO.crc_ind.sfn, UL_INFO.crc_ind.slot + ); + + if (UL_INFO.rx_ind.number_of_pdus > 0 && UL_INFO.crc_ind.number_crcs > 0) { + for (int i = 0; i < UL_INFO.rx_ind.number_of_pdus; i++) { + int j; + for (j = 0; j < UL_INFO.crc_ind.number_crcs; j++) { + // find crc_indication j corresponding rx_indication i + const nfapi_nr_rx_data_pdu_t *rx = &UL_INFO.rx_ind.pdu_list[i]; + const nfapi_nr_crc_t *crc = &UL_INFO.crc_ind.crc_list[j]; + LOG_D(NR_PHY, + "UL_INFO.crc_ind.pdu_list[%d].rnti:%04x " + "UL_INFO.rx_ind.pdu_list[%d].rnti:%04x\n", + j, + crc->rnti, + i, + rx->rnti); + + if (crc->rnti != rx->rnti) + { + LOG_D(NR_MAC, "mis-match between CRC rnti %04x and RX rnit %04x\n", crc->rnti, rx->rnti); + continue; + } + + LOG_D(NR_MAC, + "%4d.%2d Calling rx_sdu (CRC %s/tb_crc_status %d)\n", + UL_INFO.frame, + UL_INFO.slot, + crc->tb_crc_status ? "error" : "ok", + crc->tb_crc_status); + + /* if CRC passes, pass PDU, otherwise pass NULL as error indication */ + nr_rx_sdu(UL_INFO.module_id, + UL_INFO.CC_id, + UL_INFO.rx_ind.sfn, + UL_INFO.rx_ind.slot, + rx->rnti, + crc->tb_crc_status ? NULL : rx->pdu, + rx->pdu_length, + rx->timing_advance, + rx->ul_cqi, + rx->rssi); + handle_nr_ul_harq(UL_INFO.CC_id, UL_INFO.module_id, UL_INFO.frame, UL_INFO.slot, crc); + break; + } // for (j=0;jemulate_l1) + { + int last = UL_INFO.crc_ind.number_crcs - 1; + if (j < last) + { + crc_ind->crc_list[j] = crc_ind->crc_list[last]; + UL_INFO.crc_ind.number_crcs--; + } + else if (j == last) + { + UL_INFO.crc_ind.number_crcs--; + } + + last = UL_INFO.rx_ind.number_of_pdus - 1; + if (i < last) + { + rx_ind->pdu_list[i] = rx_ind->pdu_list[last]; + UL_INFO.rx_ind.number_of_pdus--; + i--; + } + else if (i == last) + { + UL_INFO.rx_ind.number_of_pdus--; + } + } + } // for (i=0;iemulate_l1) + { + if (UL_INFO.crc_ind.number_crcs > 0) + { + crc_ind->number_crcs = UL_INFO.crc_ind.number_crcs; + requeue(&gnb_crc_ind_queue, crc_ind); + } + + if (UL_INFO.rx_ind.number_of_pdus > 0) + { + rx_ind->number_of_pdus = UL_INFO.rx_ind.number_of_pdus; + requeue(&gnb_rx_ind_queue, rx_ind); + } + + if (UL_INFO.crc_ind.number_crcs == 0) + { + free(crc_ind->crc_list); + crc_ind->crc_list = NULL; + free(crc_ind); + crc_ind = NULL; + } + if (UL_INFO.rx_ind.number_of_pdus == 0) + { + free(rx_ind->pdu_list); + rx_ind->pdu_list = NULL; + free(rx_ind); + rx_ind = NULL; + } + } + else + { UL_info->crc_ind.number_crcs = 0; UL_info->rx_ind.number_of_pdus = 0; - } else if (UL_info->rx_ind.number_of_pdus != 0 - || UL_info->crc_ind.number_crcs != 0) { - LOG_E(PHY, - "hoping not to have mis-match between CRC ind and RX ind - " - "hopefully the missing message is coming shortly " - "rx_ind:%d(SFN/SL:%d/%d) crc_ind:%d(SFN/SL:%d/%d) \n", - UL_info->rx_ind.number_of_pdus, - UL_info->rx_ind.sfn, - UL_info->rx_ind.slot, - UL_info->crc_ind.number_crcs, - UL_info->rx_ind.sfn, - UL_info->rx_ind.slot); } + } else if ((UL_INFO.rx_ind.number_of_pdus != 0) + || (UL_INFO.crc_ind.number_crcs != 0)) { + LOG_E(NR_PHY, + "hoping not to have mis-match between CRC ind and RX ind - " + "hopefully the missing message is coming shortly " + "rx_ind:%d(SFN/SL:%d/%d) crc_ind:%d(SFN/SL:%d/%d) \n", + UL_INFO.rx_ind.number_of_pdus, + UL_INFO.rx_ind.sfn, + UL_INFO.rx_ind.slot, + UL_INFO.crc_ind.number_crcs, + UL_INFO.crc_ind.sfn, + UL_INFO.crc_ind.slot); } } @@ -215,10 +438,10 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) { NR_Sched_Rsp_t *sched_info = &NR_Sched_INFO[module_id][CC_id]; NR_IF_Module_t *ifi = nr_if_inst[module_id]; gNB_MAC_INST *mac = RC.nrmac[module_id]; - LOG_D(PHY,"SFN/SF:%d%d module_id:%d CC_id:%d UL_info[rach_pdus:%d rx_ind:%d crcs:%d]\n", + LOG_D(NR_PHY,"SFN/SLOT:%d.%d module_id:%d CC_id:%d UL_info[rach_pdus:%zu rx_ind:%zu crcs:%zu]\n", UL_info->frame,UL_info->slot, - module_id,CC_id, UL_info->rach_ind.number_of_pdus, - UL_info->rx_ind.number_of_pdus, UL_info->crc_ind.number_crcs); + module_id,CC_id, gnb_rach_ind_queue.num_items, + gnb_rx_ind_queue.num_items, gnb_crc_ind_queue.num_items); handle_nr_rach(UL_info); @@ -250,7 +473,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) { gNB_dlsch_ulsch_scheduler(module_id, (UL_info->frame+((UL_info->slot>(spf-1-sl_ahead))?1:0)) % 1024, (UL_info->slot+sl_ahead)%spf); - + ifi->CC_mask = 0; sched_info->module_id = module_id; sched_info->CC_id = CC_id; @@ -274,7 +497,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) { ifi->NR_Schedule_response(sched_info); } - LOG_D(PHY,"NR_Schedule_response: SFN_SF:%d%d dl_pdus:%d\n", + LOG_D(NR_PHY,"NR_Schedule_response: SFN SLOT:%d %d dl_pdus:%d\n", sched_info->frame, sched_info->slot, sched_info->DL_req->dl_tti_request_body.nPDUs); diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_PHY_INTERFACE/NR_IF_Module.h index d523d6e0f0..f857151763 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.h +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.h @@ -124,6 +124,8 @@ void NR_IF_Module_kill(int Mod_id); void NR_UL_indication(NR_UL_IND_t *UL_INFO); +void RCconfig_nr_ue_L1(void); + /*Interface for Downlink, transmitting the DLSCH SDU, DCI SDU*/ void NR_Schedule_Response(NR_Sched_Rsp_t *Sched_INFO); diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 66c7870f80..c7b54950d7 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -37,14 +37,967 @@ #include "NR_MAC_UE/mac_extern.h" #include "SCHED_NR_UE/fapi_nr_ue_l1.h" #include "executables/softmodem-common.h" - +#include "openair2/RRC/NR_UE/rrc_proto.h" +#include "openair2/GNB_APP/L1_nr_paramdef.h" +#include "openair2/GNB_APP/gnb_paramdef.h" +#include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h" #include #define MAX_IF_MODULES 100 -const char *dl_indication_type[] = {"MIB", "SIB", "DLSCH", "DCI", "RAR"}; +UL_IND_t *UL_INFO = NULL; +static eth_params_t stub_eth_params; static nr_ue_if_module_t *nr_ue_if_module_inst[MAX_IF_MODULES]; +static int ue_tx_sock_descriptor = -1; +static int ue_rx_sock_descriptor = -1; +static int g_harq_pid; +sem_t sfn_slot_semaphore; + +queue_t nr_sfn_slot_queue; +queue_t nr_chan_param_queue; +queue_t nr_dl_tti_req_queue; +queue_t nr_tx_req_queue; +queue_t nr_ul_dci_req_queue; +queue_t nr_ul_tti_req_queue; +queue_t nr_wait_ul_tti_req_queue; + +void nrue_init_standalone_socket(int tx_port, int rx_port) +{ + { + struct sockaddr_in server_address; + int addr_len = sizeof(server_address); + memset(&server_address, 0, addr_len); + server_address.sin_family = AF_INET; + server_address.sin_port = htons(tx_port); + + int sd = socket(server_address.sin_family, SOCK_DGRAM, 0); + if (sd < 0) + { + LOG_E(MAC, "Socket creation error standalone PNF\n"); + return; + } + + if (inet_pton(server_address.sin_family, stub_eth_params.remote_addr, &server_address.sin_addr) <= 0) + { + LOG_E(MAC, "Invalid standalone PNF Address\n"); + close(sd); + return; + } + + // Using connect to use send() instead of sendto() + if (connect(sd, (struct sockaddr *)&server_address, addr_len) < 0) + { + LOG_E(MAC, "Connection to standalone PNF failed: %s\n", strerror(errno)); + close(sd); + return; + } + assert(ue_tx_sock_descriptor == -1); + ue_tx_sock_descriptor = sd; + LOG_D(NR_RRC, "Successfully set up tx_socket in %s.\n", __FUNCTION__); + } + + { + struct sockaddr_in server_address; + int addr_len = sizeof(server_address); + memset(&server_address, 0, addr_len); + server_address.sin_family = AF_INET; + server_address.sin_addr.s_addr = INADDR_ANY; + server_address.sin_port = htons(rx_port); + + int sd = socket(server_address.sin_family, SOCK_DGRAM, 0); + if (sd < 0) + { + LOG_E(MAC, "Socket creation error standalone PNF\n"); + return; + } + + if (bind(sd, (struct sockaddr *)&server_address, addr_len) < 0) + { + LOG_E(MAC, "Connection to standalone PNF failed: %s\n", strerror(errno)); + close(sd); + return; + } + assert(ue_rx_sock_descriptor == -1); + ue_rx_sock_descriptor = sd; + LOG_D(NR_RRC, "Successfully set up rx_socket in %s.\n", __FUNCTION__); + } + LOG_I(NR_RRC, "NRUE standalone socket info: tx_port %d rx_port %d on %s.\n", + tx_port, rx_port, stub_eth_params.remote_addr); +} + +void send_nsa_standalone_msg(NR_UL_IND_t *UL_INFO, uint16_t msg_id) +{ + switch(msg_id) + { + case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION: + { + char buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE]; + LOG_D(NR_MAC, "RACH header id :%d", UL_INFO->rach_ind.header.message_id); + int encoded_size = nfapi_nr_p7_message_pack(&UL_INFO->rach_ind, buffer, sizeof(buffer), NULL); + if (encoded_size <= 0) + { + LOG_E(NR_MAC, "nfapi_nr_p7_message_pack has failed. Encoded size = %d\n", encoded_size); + return; + } + + LOG_I(NR_MAC, "NR_RACH_IND sent to Proxy, Size: %d Frame %d Slot %d Num PDUS %d\n", encoded_size, + UL_INFO->rach_ind.sfn, UL_INFO->rach_ind.slot, UL_INFO->rach_ind.number_of_pdus); + if (send(ue_tx_sock_descriptor, buffer, encoded_size, 0) < 0) + { + LOG_E(NR_MAC, "Send Proxy NR_UE failed\n"); + return; + } + break; + } + case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION: + { + char buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE]; + LOG_D(NR_MAC, "RX header id :%d", UL_INFO->rx_ind.header.message_id); + int encoded_size = nfapi_nr_p7_message_pack(&UL_INFO->rx_ind, buffer, sizeof(buffer), NULL); + if (encoded_size <= 0) + { + LOG_E(NR_MAC, "nfapi_nr_p7_message_pack has failed. Encoded size = %d\n", encoded_size); + return; + } + + LOG_I(NR_MAC, "NR_RX_IND sent to Proxy, Size: %d Frame %d Slot %d Num PDUS %d\n", encoded_size, + UL_INFO->rx_ind.sfn, UL_INFO->rx_ind.slot, UL_INFO->rx_ind.number_of_pdus); + if (send(ue_tx_sock_descriptor, buffer, encoded_size, 0) < 0) + { + LOG_E(NR_MAC, "Send Proxy NR_UE failed\n"); + return; + } + break; + } + case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION: + { + char buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE]; + LOG_D(NR_MAC, "CRC header id :%d", UL_INFO->crc_ind.header.message_id); + int encoded_size = nfapi_nr_p7_message_pack(&UL_INFO->crc_ind, buffer, sizeof(buffer), NULL); + if (encoded_size <= 0) + { + LOG_E(NR_MAC, "nfapi_nr_p7_message_pack has failed. Encoded size = %d\n", encoded_size); + return; + } + + LOG_I(NR_MAC, "NR_CRC_IND sent to Proxy, Size: %d Frame %d Slot %d Num PDUS %d\n", encoded_size, + UL_INFO->crc_ind.sfn, UL_INFO->crc_ind.slot, UL_INFO->crc_ind.number_crcs); + if (send(ue_tx_sock_descriptor, buffer, encoded_size, 0) < 0) + { + LOG_E(NR_MAC, "Send Proxy NR_UE failed\n"); + return; + } + break; + } + case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION: + { + char buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE]; + LOG_I(NR_MAC, "UCI header id :%d", UL_INFO->uci_ind.header.message_id); + int encoded_size = nfapi_nr_p7_message_pack(&UL_INFO->uci_ind, buffer, sizeof(buffer), NULL); + if (encoded_size <= 0) + { + LOG_E(NR_MAC, "nfapi_nr_p7_message_pack has failed. Encoded size = %d\n", encoded_size); + return; + } + + LOG_I(NR_MAC, "NR_UCI_IND sent to Proxy, Size: %d Frame %d Slot %d Num PDUS %d\n", encoded_size, + UL_INFO->uci_ind.sfn, UL_INFO->uci_ind.slot, UL_INFO->uci_ind.num_ucis); + if (send(ue_tx_sock_descriptor, buffer, encoded_size, 0) < 0) + { + LOG_E(NR_MAC, "Send Proxy NR_UE failed\n"); + return; + } + break; + } + case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION: + break; + default: + break; + } +} + +static void fill_dl_info_with_pdcch(fapi_nr_dci_indication_t *dci, nfapi_nr_dl_dci_pdu_t *rx_dci, int idx) +{ + int num_bytes = (rx_dci->PayloadSizeBits + 7) / 8; + LOG_I(NR_PHY, "[%d, %d] PDCCH DCI (Payload) for rnti %x with PayloadSizeBits %d, num_bytes %d\n", + dci->SFN, dci->slot, rx_dci->RNTI, rx_dci->PayloadSizeBits, num_bytes); + for (int k = 0; k < num_bytes; k++) + { + LOG_I(NR_MAC, "PDCCH DCI PDU payload[%d] = %d\n", k, rx_dci->Payload[k]); + dci->dci_list[idx].payloadBits[k] = rx_dci->Payload[k]; + } + dci->dci_list[idx].payloadSize = rx_dci->PayloadSizeBits; + dci->dci_list[idx].rnti = rx_dci->RNTI; + dci->number_of_dcis = idx + 1; +} + +static void fill_mib_in_rx_ind(nfapi_nr_dl_tti_request_pdu_t *pdu_list, fapi_nr_rx_indication_t *rx_ind, int pdu_idx, int pdu_type) +{ + AssertFatal(pdu_idx < sizeof(rx_ind->rx_indication_body) / sizeof(rx_ind->rx_indication_body[0]), + "pdu_index (%d) is greater than rx_indication_body size!\n", pdu_idx); + AssertFatal(pdu_idx == rx_ind->number_pdus, "Invalid pdu_idx %d!\n", pdu_idx); + + LOG_D(NR_MAC, "Recevied an SSB and are filling rx_ind with the MIB!\n"); + + nfapi_nr_dl_tti_ssb_pdu_rel15_t *ssb_pdu = &pdu_list->ssb_pdu.ssb_pdu_rel15; + rx_ind->rx_indication_body[pdu_idx].ssb_pdu.cell_id = ssb_pdu->PhysCellId; + rx_ind->rx_indication_body[pdu_idx].ssb_pdu.pdu = MALLOC(3 * sizeof(*rx_ind->rx_indication_body[pdu_idx].ssb_pdu.pdu)); + rx_ind->rx_indication_body[pdu_idx].ssb_pdu.pdu[0] = (ssb_pdu->bchPayload) & 0xff; + rx_ind->rx_indication_body[pdu_idx].ssb_pdu.pdu[1] = (ssb_pdu->bchPayload >> 8) & 0xff; + rx_ind->rx_indication_body[pdu_idx].ssb_pdu.pdu[2] = (ssb_pdu->bchPayload >> 16) & 0xff; + rx_ind->rx_indication_body[pdu_idx].ssb_pdu.rsrp_dBm = ssb_pdu->ssbRsrp; + rx_ind->rx_indication_body[pdu_idx].ssb_pdu.ssb_index = ssb_pdu->SsbBlockIndex; + rx_ind->rx_indication_body[pdu_idx].ssb_pdu.ssb_length = pdu_list->PDUSize; + rx_ind->rx_indication_body[pdu_idx].ssb_pdu.ssb_start_subcarrier = ssb_pdu->SsbSubcarrierOffset; + rx_ind->rx_indication_body[pdu_idx].pdu_type = pdu_type; + rx_ind->number_pdus = pdu_idx + 1; + +} + +static bool is_my_dci(NR_UE_MAC_INST_t *mac, nfapi_nr_dl_dci_pdu_t *received_pdu) +{ + /* For multiple UEs, we need to be able to filter the rx'd messages by + the RNTI. The filtering is different between NSA mode and SA mode. + NSA mode has a two step CFRA procedure and SA has a 4 step procedure. + We only need to check if the rx'd RNTI doesnt match the CRNTI if the RAR + has been processed already, in NSA mode. + In SA, depending on the RA state, we can have a SIB (0xffff), RAR (0x10b), + Msg3 (TC_RNTI) or an actual DCI message (CRNTI). When we get Msg3, the + MAC instance of the UE still has a CRNTI = 0. We should only check if the + CRNTI doesnt match the received RNTI in SA mode if Msg3 has been processed + already. Only once the RA procedure succeeds is the CRNTI value updated + to the TC_RNTI. */ + if (get_softmodem_params()->nsa) + { + if (received_pdu->RNTI != mac->crnti && + (received_pdu->RNTI != mac->ra.ra_rnti || mac->ra.RA_RAPID_found)) + return false; + } + if (get_softmodem_params()->sa) + { + if (received_pdu->RNTI != mac->crnti && mac->ra.ra_state == RA_SUCCEEDED) + return false; + if (received_pdu->RNTI != mac->ra.t_crnti && mac->ra.ra_state == WAIT_CONTENTION_RESOLUTION) + return false; + if (received_pdu->RNTI != 0x10b && mac->ra.ra_state == WAIT_RAR) + return false; + if (received_pdu->RNTI != 0xFFFF && mac->ra.ra_state <= GENERATE_PREAMBLE) + return false; + } + return true; +} + +static void copy_dl_tti_req_to_dl_info(nr_downlink_indication_t *dl_info, nfapi_nr_dl_tti_request_t *dl_tti_request) +{ + NR_UE_MAC_INST_t *mac = get_mac_inst(dl_info->module_id); + mac->nr_ue_emul_l1.expected_sib = false; + memset(mac->nr_ue_emul_l1.index_has_sib, 0, sizeof(*mac->nr_ue_emul_l1.index_has_sib)); + mac->nr_ue_emul_l1.expected_rar = false; + memset(mac->nr_ue_emul_l1.index_has_rar, 0, sizeof(*mac->nr_ue_emul_l1.index_has_rar)); + mac->nr_ue_emul_l1.expected_dci = false; + memset(mac->nr_ue_emul_l1.index_has_dci, 0, sizeof(*mac->nr_ue_emul_l1.index_has_dci)); + int pdu_idx = 0; + + int num_pdus = dl_tti_request->dl_tti_request_body.nPDUs; + AssertFatal(num_pdus >= 0, "Invalid dl_tti_request number of PDUS\n"); + + for (int i = 0; i < num_pdus; i++) + { + nfapi_nr_dl_tti_request_pdu_t *pdu_list = &dl_tti_request->dl_tti_request_body.dl_tti_pdu_list[i]; + if (pdu_list->PDUType == NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE) + { + LOG_I(NR_PHY, "[%d, %d] PDSCH PDU for rnti %x\n", + dl_tti_request->SFN, dl_tti_request->Slot, pdu_list->pdsch_pdu.pdsch_pdu_rel15.rnti); + } + + if (pdu_list->PDUType == NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE) + { + LOG_I(NR_PHY, "[%d, %d] PDCCH DCI PDU (Format for incoming PDSCH PDU)\n", + dl_tti_request->SFN, dl_tti_request->Slot); + uint16_t num_dcis = pdu_list->pdcch_pdu.pdcch_pdu_rel15.numDlDci; + if (num_dcis > 0) + { + if (!dl_info->dci_ind) + { + dl_info->dci_ind = CALLOC(1, sizeof(fapi_nr_dci_indication_t)); + } + dl_info->dci_ind->SFN = dl_tti_request->SFN; + dl_info->dci_ind->slot = dl_tti_request->Slot; + AssertFatal(num_dcis <= sizeof(dl_info->dci_ind->dci_list) / sizeof(dl_info->dci_ind->dci_list[0]), + "The number of DCIs is greater than dci_list"); + for (int j = 0; j < num_dcis; j++) + { + nfapi_nr_dl_dci_pdu_t *dci_pdu_list = &pdu_list->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[j]; + if (!is_my_dci(mac, dci_pdu_list)) + { + continue; + } + fill_dl_info_with_pdcch(dl_info->dci_ind, dci_pdu_list, pdu_idx); + if (dci_pdu_list->RNTI == 0xffff) + { + mac->nr_ue_emul_l1.expected_sib = true; + mac->nr_ue_emul_l1.index_has_sib[j] = true; + LOG_D(NR_MAC, "Setting index_has_sib[%d] = true\n", j); + } + else if (dci_pdu_list->RNTI == mac->ra.ra_rnti) + { + mac->nr_ue_emul_l1.expected_rar = true; + mac->nr_ue_emul_l1.index_has_rar[j] = true; + LOG_D(NR_MAC, "Setting index_has_rar[%d] = true\n", j); + } + else + { + mac->nr_ue_emul_l1.expected_dci = true; + mac->nr_ue_emul_l1.index_has_dci[j] = true; + LOG_D(NR_MAC, "Setting index_has_dci[%d] = true\n", j); + } + pdu_idx++; + } + } + } + if (pdu_list->PDUType == NFAPI_NR_DL_TTI_SSB_PDU_TYPE) + { + /* If we get a MIB, we want to handle it right away and then come back. + The MIB and SIB come in the same dl_tti_req but the MIB should be + processed first and then the DCI and payload of the SIB1 can be + processed. The MIB should be handled first and then the rx_ind + will be freed after handling. This is why the PDU index will + always be zero for the RX_IND becasue we should not have more than + one MIB. */ + if (!dl_info->rx_ind) + { + dl_info->rx_ind = CALLOC(1, sizeof(*dl_info->rx_ind)); + } + fapi_nr_rx_indication_t *rx_ind = dl_info->rx_ind; + rx_ind->sfn = dl_tti_request->SFN; + rx_ind->slot = dl_tti_request->Slot; + fill_mib_in_rx_ind(pdu_list, rx_ind, 0, FAPI_NR_RX_PDU_TYPE_SSB); + NR_UL_TIME_ALIGNMENT_t ul_time_alignment; + memset(&ul_time_alignment, 0, sizeof(ul_time_alignment)); + nr_ue_dl_indication(&mac->dl_info, &ul_time_alignment); + } + } + dl_info->slot = dl_tti_request->Slot; + dl_info->frame = dl_tti_request->SFN; +} + +static void fill_rx_ind(nfapi_nr_pdu_t *pdu_list, fapi_nr_rx_indication_t *rx_ind, int pdu_idx, int pdu_type) +{ + AssertFatal(pdu_list->num_TLV < sizeof(pdu_list->TLVs) / sizeof(pdu_list->TLVs[0]), "Num TLVs exceeds TLV array size"); + int length = 0; + for (int j = 0; j < pdu_list->num_TLV; j++) + { + length += pdu_list->TLVs[j].length; + } + LOG_I(NR_PHY, "%s: num_tlv %d and length %d, pdu index %d\n", + __FUNCTION__, pdu_list->num_TLV, length, pdu_idx); + uint8_t *pdu = malloc(length); + AssertFatal(pdu != NULL, "%s: Out of memory in malloc", __FUNCTION__); + rx_ind->rx_indication_body[pdu_idx].pdsch_pdu.pdu = pdu; + for (int j = 0; j < pdu_list->num_TLV; j++) + { + const uint32_t *ptr; + if (pdu_list->TLVs[j].tag) + ptr = pdu_list->TLVs[j].value.ptr; + else + ptr = pdu_list->TLVs[j].value.direct; + memcpy(pdu, ptr, pdu_list->TLVs[j].length); + pdu += pdu_list->TLVs[j].length; + } + rx_ind->rx_indication_body[pdu_idx].pdsch_pdu.ack_nack = 1; + rx_ind->rx_indication_body[pdu_idx].pdsch_pdu.pdu_length = length; + rx_ind->rx_indication_body[pdu_idx].pdu_type = pdu_type; + +} + + +static void copy_tx_data_req_to_dl_info(nr_downlink_indication_t *dl_info, nfapi_nr_tx_data_request_t *tx_data_request) +{ + NR_UE_MAC_INST_t *mac = get_mac_inst(dl_info->module_id); + int num_pdus = tx_data_request->Number_of_PDUs; + AssertFatal(num_pdus >= 0, "Invalid tx_data_request number of PDUS\n"); + + if (!dl_info->rx_ind) + { + dl_info->rx_ind = CALLOC(1, sizeof(fapi_nr_rx_indication_t)); + } + AssertFatal(dl_info->rx_ind != NULL, "%s: Out of memory in calloc", __FUNCTION__); + fapi_nr_rx_indication_t *rx_ind = dl_info->rx_ind; + rx_ind->sfn = tx_data_request->SFN; + rx_ind->slot = tx_data_request->Slot; + + int pdu_idx = 0; + + for (int i = 0; i < num_pdus; i++) + { + nfapi_nr_pdu_t *pdu_list = &tx_data_request->pdu_list[i]; + if (mac->nr_ue_emul_l1.index_has_sib[i]) + { + AssertFatal(!get_softmodem_params()->nsa, + "Should not be processing SIB in NSA mode, something bad happened\n"); + fill_rx_ind(pdu_list, rx_ind, pdu_idx, FAPI_NR_RX_PDU_TYPE_SIB); + pdu_idx++; + } + else if (mac->nr_ue_emul_l1.index_has_rar[i]) + { + fill_rx_ind(pdu_list, rx_ind, pdu_idx, FAPI_NR_RX_PDU_TYPE_RAR); + pdu_idx++; + } + else if (mac->nr_ue_emul_l1.index_has_dci[i]) + { + fill_rx_ind(pdu_list, rx_ind, pdu_idx, FAPI_NR_RX_PDU_TYPE_DLSCH); + pdu_idx++; + } + else + { + LOG_D(NR_MAC, "mac->nr_ue_emul_l1.index_has_dci[%d] = 0, so this index contained a DCI for a different UE\n", i); + } + + } + dl_info->slot = tx_data_request->Slot; + dl_info->frame = tx_data_request->SFN; + dl_info->rx_ind->number_pdus = pdu_idx; +} + +static void copy_ul_dci_data_req_to_dl_info(nr_downlink_indication_t *dl_info, nfapi_nr_ul_dci_request_t *ul_dci_req) +{ + NR_UE_MAC_INST_t *mac = get_mac_inst(dl_info->module_id); + int pdu_idx = 0; + + int num_pdus = ul_dci_req->numPdus; + AssertFatal(num_pdus >= 0, "Invalid ul_dci_request number of PDUS\n"); + + for (int i = 0; i < num_pdus; i++) + { + nfapi_nr_ul_dci_request_pdus_t *pdu_list = &ul_dci_req->ul_dci_pdu_list[i]; + AssertFatal(pdu_list->PDUType == 0, "ul_dci_req pdu type != PUCCH"); + LOG_I(NR_PHY, "[%d %d] PUCCH PDU in ul_dci for rnti %x and numDLDCI = %d\n", + ul_dci_req->SFN, ul_dci_req->Slot, pdu_list->pdcch_pdu.pdcch_pdu_rel15.dci_pdu->RNTI, + pdu_list->pdcch_pdu.pdcch_pdu_rel15.numDlDci); + uint16_t num_dci = pdu_list->pdcch_pdu.pdcch_pdu_rel15.numDlDci; + if (num_dci > 0) + { + if (!dl_info->dci_ind) + { + dl_info->dci_ind = CALLOC(1, sizeof(fapi_nr_dci_indication_t)); + } + AssertFatal(dl_info->dci_ind != NULL, "%s: Out of memory in calloc", __FUNCTION__); + dl_info->dci_ind->SFN = ul_dci_req->SFN; + dl_info->dci_ind->slot = ul_dci_req->Slot; + AssertFatal(num_dci < sizeof(dl_info->dci_ind->dci_list) / sizeof(dl_info->dci_ind->dci_list[0]), "The number of DCIs is greater than dci_list"); + for (int j = 0; j < num_dci; j++) + { + nfapi_nr_dl_dci_pdu_t *dci_pdu_list = &pdu_list->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[j]; + if (dci_pdu_list->RNTI != mac->crnti) + { + LOG_D(NR_MAC, "dci_pdu_list->RNTI (%x) != mac->crnti (%x)\n", dci_pdu_list->RNTI, mac->crnti); + continue; + } + fill_dl_info_with_pdcch(dl_info->dci_ind, dci_pdu_list, pdu_idx); + pdu_idx++; + } + } + } + dl_info->frame = ul_dci_req->SFN; + dl_info->slot = ul_dci_req->Slot; +} + +static nfapi_nr_uci_indication_t *multiplex_uci_ind(NR_UE_MAC_INST_t *mac, int num_active_harqs) +{ + AssertFatal(num_active_harqs >= 0, "Invalid value for num_active_harqs %d\n", num_active_harqs); + if (num_active_harqs == 0) + { + return NULL; + } + if (num_active_harqs != nr_uci_ind_queue.num_items) + { + LOG_I(NR_MAC, "The number of active harqs %d doesn't match the number of UCIs in the queue %lu\n", + num_active_harqs, nr_uci_ind_queue.num_items); + return NULL; + } + + nfapi_nr_uci_indication_t *uci_ind = MALLOC(sizeof(*uci_ind)); + uci_ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION; + uci_ind->sfn = NFAPI_SFNSLOT2SFN(mac->nr_ue_emul_l1.active_harq_sfn_slot); + uci_ind->slot = NFAPI_SFNSLOT2SLOT(mac->nr_ue_emul_l1.active_harq_sfn_slot); + uci_ind->num_ucis = num_active_harqs; + uci_ind->uci_list = CALLOC(uci_ind->num_ucis, sizeof(*uci_ind->uci_list)); + for (int i = 0; i < num_active_harqs; i++) + { + nfapi_nr_uci_indication_t *queued_uci_ind = get_queue(&nr_uci_ind_queue); + AssertFatal(queued_uci_ind, "There was not a UCI in the queue!\n"); + nfapi_nr_uci_pucch_pdu_format_0_1_t *pdu_0_1 = &uci_ind->uci_list[i].pucch_pdu_format_0_1; + + /* In openair1/SCHED_NR_UE/fapi_nr_ue_l1.c nr_ue_schedule_response_stub(), the + number of UCIs is hard coded to 1. This is why we always use index 0 of the + queued UCI indication to fill the new multiplexed UCI indication */ + AssertFatal(queued_uci_ind->num_ucis == 1, "The number of UCIs from de-queueud UCI is not 1, its %d\n", + queued_uci_ind->num_ucis); + uci_ind->uci_list[i].pdu_type = queued_uci_ind->uci_list[0].pdu_type; + uci_ind->uci_list[i].pdu_size = queued_uci_ind->uci_list[0].pdu_size; + + nfapi_nr_uci_pucch_pdu_format_0_1_t *queued_pdu_0_1 = &queued_uci_ind->uci_list[0].pucch_pdu_format_0_1; + pdu_0_1->handle = queued_pdu_0_1->handle; + pdu_0_1->rnti = queued_pdu_0_1->rnti; + pdu_0_1->pucch_format = queued_pdu_0_1->pucch_format; + pdu_0_1->ul_cqi = queued_pdu_0_1->ul_cqi; + pdu_0_1->timing_advance = queued_pdu_0_1->timing_advance; + pdu_0_1->rssi = queued_pdu_0_1->rssi; + free(queued_uci_ind->uci_list); + queued_uci_ind->uci_list = NULL; + free(queued_uci_ind); + queued_uci_ind = NULL; + } + return uci_ind; +} + +static void copy_ul_tti_data_req_to_dl_info(nr_downlink_indication_t *dl_info, nfapi_nr_ul_tti_request_t *ul_tti_req) +{ + NR_UE_MAC_INST_t *mac = get_mac_inst(dl_info->module_id); + int num_pdus = ul_tti_req->n_pdus; + AssertFatal(num_pdus >= 0, "Invalid ul_tti_request number of PDUS\n"); + AssertFatal(num_pdus <= sizeof(ul_tti_req->pdus_list) / sizeof(ul_tti_req->pdus_list[0]), + "Too many pdus %d in ul_tti_req\n", num_pdus); + + bool sent_uci = false; + for (int i = 0; i < num_pdus; i++) + { + nfapi_nr_ul_tti_request_number_of_pdus_t *pdu_list = &ul_tti_req->pdus_list[i]; + LOG_D(NR_PHY, "This is the pdu type %d and rnti %x and SR flag %d and harq_pdu_len %d in in ul_tti_req\n", + pdu_list->pdu_type, ul_tti_req->pdus_list[i].pucch_pdu.rnti, pdu_list->pucch_pdu.sr_flag, pdu_list->pucch_pdu.bit_len_harq); + if (pdu_list->pdu_type == NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE && pdu_list->pucch_pdu.rnti == mac->crnti) + { + AssertFatal(nr_uci_ind_queue.num_items >= 0, "Invalid num_items in UCI_ind queue %lu\n", + nr_uci_ind_queue.num_items); + int num_active_harqs = pdu_list->pucch_pdu.bit_len_harq; + LOG_I(NR_MAC, "The number of active harqs %d from ul_tti_req\n", num_active_harqs); + nfapi_nr_uci_indication_t *uci_ind = multiplex_uci_ind(mac, num_active_harqs); + + if (uci_ind && uci_ind->num_ucis > 0) + { + LOG_D(NR_MAC, "This is the SFN/SF [%d, %d] and RNTI %x of the UCI ind. ul_tti_req.pdu[%d]->rnti = %x \n", + uci_ind->sfn, uci_ind->slot, uci_ind->uci_list[0].pucch_pdu_format_0_1.rnti, i, ul_tti_req->pdus_list[i].pucch_pdu.rnti); + uci_ind->sfn = ul_tti_req->SFN; + uci_ind->slot = ul_tti_req->Slot; + for (int j = 0; j < uci_ind->num_ucis; j++) + { + nfapi_nr_uci_pucch_pdu_format_0_1_t *pdu_0_1 = &uci_ind->uci_list[j].pucch_pdu_format_0_1; + if (pdu_list->pucch_pdu.sr_flag) + { + LOG_D(NR_MAC, "We have the SR flag in pdu i %d\n", i); + pdu_0_1->pduBitmap = 1; // (value->pduBitmap >> 1) & 0x01) == HARQ and (value->pduBitmap) & 0x01) == SR + pdu_0_1->sr = CALLOC(1, sizeof(*pdu_0_1->sr)); + pdu_0_1->sr->sr_confidence_level = 0; + pdu_0_1->sr->sr_indication = 1; + } + if (pdu_list->pucch_pdu.bit_len_harq > 0) + { + LOG_D(NR_MAC, "We have the Harq len bits %d\n", pdu_list->pucch_pdu.bit_len_harq); + pdu_0_1->pduBitmap = 2; // (value->pduBitmap >> 1) & 0x01) == HARQ and (value->pduBitmap) & 0x01) == SR + pdu_0_1->harq = CALLOC(1, sizeof(*pdu_0_1->harq)); + pdu_0_1->harq->num_harq = 1; + pdu_0_1->harq->harq_confidence_level = 0; + pdu_0_1->harq->harq_list = CALLOC(pdu_0_1->harq->num_harq, sizeof(*pdu_0_1->harq->harq_list)); + for (int k = 0; k < pdu_0_1->harq->num_harq; k++) + { + pdu_0_1->harq->harq_list[k].harq_value = 0; + } + } + } + LOG_I(NR_MAC, "We have dequeued the previously filled uci_ind and updated the snf/slot to %d/%d.\n", + uci_ind->sfn, uci_ind->slot); + NR_UL_IND_t UL_INFO = { + .uci_ind = *uci_ind, + }; + send_nsa_standalone_msg(&UL_INFO, uci_ind->header.message_id); + sent_uci = true; + + for (int k = 0; k < uci_ind->num_ucis; k++) + { + nfapi_nr_uci_pucch_pdu_format_0_1_t *pdu_0_1 = &uci_ind->uci_list[k].pucch_pdu_format_0_1; + if (pdu_list->pucch_pdu.sr_flag) + { + free(pdu_0_1->sr); + pdu_0_1->sr = NULL; + } + if (pdu_list->pucch_pdu.bit_len_harq > 1) + { + free(pdu_0_1->harq->harq_list); + pdu_0_1->harq->harq_list = NULL; + free(pdu_0_1->harq); + pdu_0_1->harq = NULL; + } + } + free(uci_ind->uci_list); + uci_ind->uci_list = NULL; + free(uci_ind); + uci_ind = NULL; + } + } + } + if (!sent_uci) + { + LOG_E(NR_MAC, "UCI ind not sent\n"); + if (!put_queue(&nr_ul_tti_req_queue, ul_tti_req)) + { + LOG_E(NR_PHY, "put_queue failed for ul_tti_req.\n"); + free(ul_tti_req); + ul_tti_req = NULL; + } + } +} + +static void fill_dci_from_dl_config(nr_downlink_indication_t*dl_ind, fapi_nr_dl_config_request_t *dl_config) +{ + if (!dl_ind->dci_ind) + { + return; + } + + AssertFatal(dl_config->number_pdus < sizeof(dl_config->dl_config_list) / sizeof(dl_config->dl_config_list[0]), + "Too many dl_config pdus %d", dl_config->number_pdus); + for (int i = 0; i < dl_config->number_pdus; i++) + { + LOG_I(PHY, "In %s: filling DCI with a total of %d total DL PDUs (dl_config %p) \n", + __FUNCTION__, dl_config->number_pdus, dl_config); + fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15_dci = &dl_config->dl_config_list[i].dci_config_pdu.dci_config_rel15; + int num_dci_options = rel15_dci->num_dci_options; + if (num_dci_options <= 0) + { + LOG_I(NR_MAC, "num_dci_opts = %d for pdu[%d] in dl_config_list\n", rel15_dci->num_dci_options, i); + } + AssertFatal(num_dci_options <= sizeof(rel15_dci->dci_length_options) / sizeof(rel15_dci->dci_length_options[0]), + "num_dci_options %d > dci_length_options array\n", num_dci_options); + AssertFatal(num_dci_options <= sizeof(rel15_dci->dci_format_options) / sizeof(rel15_dci->dci_format_options[0]), + "num_dci_options %d > dci_format_options array\n", num_dci_options); + + for (int j = 0; j < num_dci_options; j++) + { + int num_dcis = dl_ind->dci_ind->number_of_dcis; + AssertFatal(num_dcis <= sizeof(dl_ind->dci_ind->dci_list) / sizeof(dl_ind->dci_ind->dci_list[0]), + "dl_config->number_pdus %d > dci_ind->dci_list array\n", num_dcis); + for (int k = 0; k < num_dcis; k++) + { + LOG_I(NR_PHY, "Received len %d, length options[%d] %d, format assigned %d, format options[%d] %d\n", + dl_ind->dci_ind->dci_list[k].payloadSize, j, rel15_dci->dci_length_options[j], + dl_ind->dci_ind->dci_list[k].dci_format, j, rel15_dci->dci_format_options[j]); + if (rel15_dci->dci_length_options[j] == dl_ind->dci_ind->dci_list[k].payloadSize) + { + dl_ind->dci_ind->dci_list[k].dci_format = rel15_dci->dci_format_options[j]; + } + int CCEind = rel15_dci->CCE[j]; + int L = rel15_dci->L[j]; + dl_ind->dci_ind->dci_list[k].n_CCE = CCEind; + dl_ind->dci_ind->dci_list[k].N_CCE = L; + } + } + } +} + +void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request, + nfapi_nr_tx_data_request_t *tx_data_request, + nfapi_nr_ul_dci_request_t *ul_dci_request, + nfapi_nr_ul_tti_request_t *ul_tti_request) +{ + frame_t frame = 0; + int slot = 0; + NR_UE_MAC_INST_t *mac = get_mac_inst(0); + + if (pthread_mutex_lock(&mac->mutex_dl_info)) abort(); + + if (dl_tti_request) + { + frame = dl_tti_request->SFN; + slot = dl_tti_request->Slot; + LOG_I(NR_PHY, "[%d, %d] dl_tti_request\n", frame, slot); + copy_dl_tti_req_to_dl_info(&mac->dl_info, dl_tti_request); + } + /* This checks if the previously recevied DCI matches our current RNTI + value. The assumption is that if the DCI matches our RNTI, then the + incoming tx_data_request is also destined for the current UE. If the + RAR hasn't been processed yet, we do not want to be filtering the + tx_data_requests. */ + if (tx_data_request && (mac->nr_ue_emul_l1.expected_sib || + mac->nr_ue_emul_l1.expected_rar || + mac->nr_ue_emul_l1.expected_dci)) + { + frame = tx_data_request->SFN; + slot = tx_data_request->Slot; + LOG_I(NR_PHY, "[%d, %d] PDSCH in tx_request\n", frame, slot); + copy_tx_data_req_to_dl_info(&mac->dl_info, tx_data_request); + } + else if (ul_dci_request) + { + frame = ul_dci_request->SFN; + slot = ul_dci_request->Slot; + LOG_I(NR_PHY, "[%d, %d] ul_dci_request\n", frame, slot); + copy_ul_dci_data_req_to_dl_info(&mac->dl_info, ul_dci_request); + } + else if (ul_tti_request) + { + frame = ul_tti_request->SFN; + slot = ul_tti_request->Slot; + LOG_I(NR_PHY, "[%d, %d] ul_tti_request\n", frame, slot); + copy_ul_tti_data_req_to_dl_info(&mac->dl_info, ul_tti_request); + } + else + { + if (pthread_mutex_unlock(&mac->mutex_dl_info)) abort(); + LOG_E(NR_MAC, "Error! All indications were NULL\n"); + return; + } + + + NR_UL_TIME_ALIGNMENT_t ul_time_alignment; + memset(&ul_time_alignment, 0, sizeof(ul_time_alignment)); + fill_dci_from_dl_config(&mac->dl_info, &mac->dl_config_request); + nr_ue_dl_indication(&mac->dl_info, &ul_time_alignment); + + if (pthread_mutex_unlock(&mac->mutex_dl_info)) abort(); + + // If we filled dl_info AFTER we got the slot indication, we want to check if we should fill tx_req: + nr_uplink_indication_t ul_info; + memset(&ul_info, 0, sizeof(ul_info)); + int slots_per_frame = 20; //30 kHZ subcarrier spacing + int slot_ahead = 2; // TODO: Make this dynamic + ul_info.frame_rx = frame; + ul_info.slot_rx = slot; + ul_info.slot_tx = (slot + slot_ahead) % slots_per_frame; + ul_info.frame_tx = (ul_info.slot_rx + slot_ahead >= slots_per_frame) ? ul_info.frame_rx + 1 : ul_info.frame_rx; + ul_info.ue_sched_mode = SCHED_ALL; + if (mac->scc || mac->scc_SIB) + { + if (is_nr_UL_slot(mac->scc ? + mac->scc->tdd_UL_DL_ConfigurationCommon : + mac->scc_SIB->tdd_UL_DL_ConfigurationCommon, + ul_info.slot_tx, + mac->frame_type)) + nr_ue_ul_indication(&ul_info); + } +} + +void save_nr_measurement_info(nfapi_nr_dl_tti_request_t *dl_tti_request) +{ + int num_pdus = dl_tti_request->dl_tti_request_body.nPDUs; + char buffer[MAX_MESSAGE_SIZE]; + if (num_pdus <= 0) + { + LOG_E(NR_PHY, "%s: dl_tti_request number of PDUS <= 0\n", __FUNCTION__); + abort(); + } + LOG_D(NR_PHY, "%s: dl_tti_request number of PDUS: %d\n", __FUNCTION__, num_pdus); + for (int i = 0; i < num_pdus; i++) + { + nfapi_nr_dl_tti_request_pdu_t *pdu_list = &dl_tti_request->dl_tti_request_body.dl_tti_pdu_list[i]; + if (pdu_list->PDUType == NFAPI_NR_DL_TTI_SSB_PDU_TYPE) + { + LOG_D(NR_PHY, "Cell_id: %d, the ssb_block_idx %d, sc_offset: %d and payload %d\n", + pdu_list->ssb_pdu.ssb_pdu_rel15.PhysCellId, + pdu_list->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex, + pdu_list->ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset, + pdu_list->ssb_pdu.ssb_pdu_rel15.bchPayload); + pdu_list->ssb_pdu.ssb_pdu_rel15.ssbRsrp = 60; + LOG_D(NR_RRC, "Setting pdulist[%d].ssbRsrp to %d\n", i, pdu_list->ssb_pdu.ssb_pdu_rel15.ssbRsrp); + } + } + + size_t pack_len = nfapi_nr_p7_message_pack((void *)dl_tti_request, + buffer, + sizeof(buffer), + NULL); + if (pack_len < 0) + { + LOG_E(NR_PHY, "%s: Error packing nr p7 message.\n", __FUNCTION__); + } + nsa_sendmsg_to_lte_ue(buffer, pack_len, NR_UE_RRC_MEASUREMENT); + LOG_A(NR_RRC, "Populated NR_UE_RRC_MEASUREMENT information and sent to LTE UE\n"); +} + +static void enqueue_nr_nfapi_msg(void *buffer, ssize_t len, nfapi_p7_message_header_t header) +{ + + switch (header.message_id) + { + case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST: + { + nfapi_nr_dl_tti_request_t *dl_tti_request = MALLOC(sizeof(*dl_tti_request)); + if (nfapi_nr_p7_message_unpack(buffer, len, dl_tti_request, + sizeof(*dl_tti_request), NULL) < 0) + { + LOG_E(NR_PHY, "Message dl_tti_request failed to unpack\n"); + break; + } + LOG_I(NR_PHY, "Received an NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST message in sfn/slot %d %d. \n", + dl_tti_request->SFN, dl_tti_request->Slot); + if (!put_queue(&nr_dl_tti_req_queue, dl_tti_request)) + { + LOG_E(NR_PHY, "put_queue failed for dl_tti_request.\n"); + free(dl_tti_request); + dl_tti_request = NULL; + } + break; + } + + case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST: + { + nfapi_nr_tx_data_request_t *tx_data_request = MALLOC(sizeof(*tx_data_request)); + if (nfapi_nr_p7_message_unpack(buffer, len, tx_data_request, + sizeof(*tx_data_request), NULL) < 0) + { + LOG_E(NR_PHY, "Message tx_data_request failed to unpack\n"); + break; + } + LOG_I(NR_PHY, "Received an NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST message in SFN/slot %d %d. \n", + tx_data_request->SFN, tx_data_request->Slot); + if (!put_queue(&nr_tx_req_queue, tx_data_request)) + { + LOG_E(NR_PHY, "put_queue failed for tx_request.\n"); + free(tx_data_request); + tx_data_request = NULL; + } + break; + } + + case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST: + { + nfapi_nr_ul_dci_request_t *ul_dci_request = MALLOC(sizeof(*ul_dci_request)); + if (nfapi_nr_p7_message_unpack(buffer, len, ul_dci_request, + sizeof(*ul_dci_request), NULL) < 0) + { + LOG_E(NR_PHY, "Message ul_dci_request failed to unpack\n"); + break; + } + LOG_I(NR_PHY, "Received an NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST message in SFN/slot %d %d. \n", + ul_dci_request->SFN, ul_dci_request->Slot); + if (!put_queue(&nr_ul_dci_req_queue, ul_dci_request)) + { + LOG_E(NR_PHY, "put_queue failed for ul_dci_request.\n"); + free(ul_dci_request); + ul_dci_request = NULL; + } + break; + } + + case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST: + { + nfapi_nr_ul_tti_request_t *ul_tti_request = MALLOC(sizeof(*ul_tti_request)); + if (nfapi_nr_p7_message_unpack(buffer, len, ul_tti_request, + sizeof(*ul_tti_request), NULL) < 0) + { + LOG_E(NR_PHY, "Message ul_tti_request failed to unpack\n"); + break; + } + LOG_I(NR_PHY, "Received an NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST message in SFN/slot %d %d.\n", + ul_tti_request->SFN, ul_tti_request->Slot); + if (nr_uci_ind_queue.num_items > 0) //TODO: In the future UL_TTIs can be for ULSCH and SRS. + { + LOG_D(NR_MAC, "We added UL_TTI_REQ to queue for sfn slot %d %d\n", + ul_tti_request->SFN, ul_tti_request->Slot); + if (!put_queue(&nr_ul_tti_req_queue, ul_tti_request)) + { + LOG_E(NR_PHY, "put_queue failed for ul_tti_request.\n"); + free(ul_tti_request); + ul_tti_request = NULL; + } + } + /* TODO: This indicates that dl_tti_req was late or never arrived. If there are + not any prepared uci indications, the NRUE likely never had time to + populate the message is the dl_tti_req came in late and we received a + ul_tti_req immediately after the dl_tti_request. This is an attempt to + mitigate proxy timing issues. */ + else if (nr_uci_ind_queue.num_items == 0) + { + LOG_D(NR_MAC, "We added UL_TTI_REQ to queue for sfn slot %d %d\n", + ul_tti_request->SFN, ul_tti_request->Slot); + nfapi_nr_ul_tti_request_t *evicted_ul_tti_req = put_queue_replace(&nr_wait_ul_tti_req_queue, ul_tti_request); + free(evicted_ul_tti_req); + } + break; + } + + default: + LOG_E(NR_PHY, "Invalid nFAPI message. Header ID %d\n", + header.message_id); + break; + } + return; +} + +void *nrue_standalone_pnf_task(void *context) +{ + struct sockaddr_in server_address; + socklen_t addr_len = sizeof(server_address); + int sd = ue_rx_sock_descriptor; + assert(sd > 0); + + char buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE]; + + LOG_I(NR_RRC, "Successfully started %s.\n", __FUNCTION__); + + while (true) + { + ssize_t len = recvfrom(sd, buffer, sizeof(buffer), MSG_TRUNC, (struct sockaddr *)&server_address, &addr_len); + if (len == -1) + { + LOG_E(NR_PHY, "reading from standalone pnf sctp socket failed \n"); + continue; + } + if (len > sizeof(buffer)) + { + LOG_E(NR_PHY, "%s(%d). Message truncated. %zd\n", __FUNCTION__, __LINE__, len); + continue; + } + if (len == sizeof(uint16_t)) + { + uint16_t *sfn_slot = CALLOC(1, sizeof(*sfn_slot)); + memcpy(sfn_slot, buffer, sizeof(*sfn_slot)); + + LOG_I(NR_PHY, "Received from proxy sfn %d slot %d\n", + NFAPI_SFNSLOT2SFN(*sfn_slot), NFAPI_SFNSLOT2SLOT(*sfn_slot)); + + if (!put_queue(&nr_sfn_slot_queue, sfn_slot)) + { + LOG_E(NR_PHY, "put_queue failed for sfn slot.\n"); + } + + if (sem_post(&sfn_slot_semaphore) != 0) + { + LOG_E(NR_PHY, "sem_post() error\n"); + abort(); + } + } + else if (len == sizeof(nr_phy_channel_params_t)) + { + nr_phy_channel_params_t *ch_info = CALLOC(1, sizeof(*ch_info)); + memcpy(ch_info, buffer, sizeof(*ch_info)); + + LOG_D(NR_PHY, "Received_SINR = %f, sfn:slot %d:%d\n", + ch_info->sinr, NFAPI_SFNSLOT2SFN(ch_info->sfn_slot), NFAPI_SFNSLOT2SLOT(ch_info->sfn_slot)); + + if (!put_queue(&nr_chan_param_queue, ch_info)) + { + LOG_E(NR_PHY, "put_queue failed for sfn slot.\n"); + } + + if (sem_post(&sfn_slot_semaphore) != 0) + { + LOG_E(MAC, "sem_post() error\n"); + abort(); + } + } + else + { + nfapi_p7_message_header_t header; + if (nfapi_p7_message_header_unpack(buffer, len, &header, sizeof(header), NULL) < 0) + { + LOG_E(NR_PHY, "Header unpack failed for nrue_standalone pnf\n"); + continue; + } + enqueue_nr_nfapi_msg(buffer, len, header); + } + } //while(true) +} // L2 Abstraction Layer int handle_bcch_bch(module_id_t module_id, int cc_id, @@ -81,6 +1034,8 @@ int handle_dci(module_id_t module_id, int cc_id, unsigned int gNB_index, frame_t // Note: sdu should always be processed because data and timing advance updates are transmitted by the UE int8_t handle_dlsch(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment, int pdu_id){ + dl_info->rx_ind->rx_indication_body[pdu_id].pdsch_pdu.harq_pid = g_harq_pid; + update_harq_status(dl_info->module_id, dl_info->rx_ind->rx_indication_body[pdu_id].pdsch_pdu.harq_pid, dl_info->rx_ind->rx_indication_body[pdu_id].pdsch_pdu.ack_nack); @@ -117,8 +1072,12 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){ ret = nr_ue_scheduler(NULL, ul_info); return 0; } - else if (ul_info->ue_sched_mode == SCHED_ALL) + if (ul_info->ue_sched_mode == SCHED_ALL) { ret = nr_ue_scheduler(NULL, ul_info); + } + else + LOG_D(NR_MAC, "In %s():%d not calling scheduler. sched mode = %d and mac->ra.ra_state = %d\n", + __FUNCTION__, __LINE__, ul_info->ue_sched_mode, mac->ra.ra_state); NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon = mac->scc != NULL ? mac->scc->tdd_UL_DL_ConfigurationCommon : mac->scc_SIB->tdd_UL_DL_ConfigurationCommon; @@ -146,20 +1105,19 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment){ - int32_t i; uint32_t ret_mask = 0x0; module_id_t module_id = dl_info->module_id; NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); fapi_nr_dl_config_request_t *dl_config = &mac->dl_config_request; - - if (!dl_info->dci_ind && !dl_info->rx_ind) { + + if ((!dl_info->dci_ind && !dl_info->rx_ind)) { // UL indication to schedule DCI reception nr_ue_scheduler(dl_info, NULL); } else { // UL indication after reception of DCI or DL PDU - if(dl_info->dci_ind != NULL){ + if (dl_info && dl_info->dci_ind && dl_info->dci_ind->number_of_dcis) { LOG_D(MAC,"[L2][IF MODULE][DL INDICATION][DCI_IND]\n"); - for(i=0; idci_ind->number_of_dcis; ++i){ + for (int i = 0; i < dl_info->dci_ind->number_of_dcis; i++) { LOG_D(MAC,">>>NR_IF_Module i=%d, dl_info->dci_ind->number_of_dcis=%d\n",i,dl_info->dci_ind->number_of_dcis); nr_scheduled_response_t scheduled_response; int8_t ret = handle_dci(dl_info->module_id, @@ -169,6 +1127,17 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_ dl_info->slot, dl_info->dci_ind->dci_list+i); + fapi_nr_dci_indication_pdu_t *dci_index = dl_info->dci_ind->dci_list+i; + + /* The check below filters out UL_DCIs (format 7) which are being processed as DL_DCIs. */ + if (dci_index->dci_format == 7 && mac->ra.ra_state == RA_SUCCEEDED) { + LOG_D(NR_MAC, "We are filtering a UL_DCI to prevent it from being treated like a DL_DCI\n"); + break; + } + dci_pdu_rel15_t *def_dci_pdu_rel15 = &mac->def_dci_pdu_rel15[dci_index->dci_format]; + g_harq_pid = def_dci_pdu_rel15->harq_pid; + LOG_D(NR_MAC, "Setting harq_pid = %d and dci_index = %d (based on format)\n", g_harq_pid, dci_index->dci_format); + ret_mask |= (ret << FAPI_NR_DCI_IND); if (ret >= 0) { AssertFatal( nr_ue_if_module_inst[module_id] != NULL, "IF module is NULL!\n" ); @@ -176,16 +1145,19 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_ fill_scheduled_response(&scheduled_response, dl_config, NULL, NULL, dl_info->module_id, dl_info->cc_id, dl_info->frame, dl_info->slot, dl_info->thread_id); nr_ue_if_module_inst[module_id]->scheduled_response(&scheduled_response); } + memset(def_dci_pdu_rel15, 0, sizeof(*def_dci_pdu_rel15)); } + free(dl_info->dci_ind); + dl_info->dci_ind = NULL; } - if(dl_info->rx_ind != NULL){ + if (dl_info->rx_ind != NULL) { - for(i=0; irx_ind->number_pdus; ++i){ + for (int i=0; irx_ind->number_pdus; ++i) { - LOG_D(MAC, "In %s sending DL indication to MAC. 1 PDU type %s of %d total number of PDUs \n", + LOG_D(MAC, "In %s sending DL indication to MAC. 1 PDU type %d of %d total number of PDUs \n", __FUNCTION__, - dl_indication_type[dl_info->rx_ind->rx_indication_body[i].pdu_type - 1], + dl_info->rx_ind->rx_indication_body[i].pdu_type, dl_info->rx_ind->number_pdus); switch(dl_info->rx_ind->rx_indication_body[i].pdu_type){ @@ -217,11 +1189,15 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_ break; } } + free(dl_info->rx_ind); + dl_info->rx_ind = NULL; } //clean up nr_downlink_indication_t *dl_info - dl_info->rx_ind = NULL; + free(dl_info->dci_ind); dl_info->dci_ind = NULL; + free(dl_info->rx_ind); + dl_info->rx_ind = NULL; } return 0; @@ -237,7 +1213,10 @@ nr_ue_if_module_t *nr_ue_if_module_init(uint32_t module_id){ nr_ue_if_module_inst[module_id]->current_frame = 0; nr_ue_if_module_inst[module_id]->current_slot = 0; nr_ue_if_module_inst[module_id]->phy_config_request = nr_ue_phy_config_request; - nr_ue_if_module_inst[module_id]->scheduled_response = nr_ue_scheduled_response; + if (get_softmodem_params()->emulate_l1) + nr_ue_if_module_inst[module_id]->scheduled_response = nr_ue_scheduled_response_stub; + else + nr_ue_if_module_inst[module_id]->scheduled_response = nr_ue_scheduled_response; nr_ue_if_module_inst[module_id]->dl_indication = nr_ue_dl_indication; nr_ue_if_module_inst[module_id]->ul_indication = nr_ue_ul_indication; } @@ -266,3 +1245,32 @@ int nr_ue_dcireq(nr_dcireq_t *dcireq) { return 0; } + +void RCconfig_nr_ue_L1(void) { + int j; + paramdef_t L1_Params[] = L1PARAMS_DESC; + paramlist_def_t L1_ParamList = {CONFIG_STRING_L1_LIST, NULL, 0}; + + config_getlist(&L1_ParamList, L1_Params, sizeof(L1_Params) / sizeof(paramdef_t), NULL); + if (L1_ParamList.numelt > 0) { + for (j = 0; j < L1_ParamList.numelt; j++) { + if (strcmp(*(L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "nfapi") == 0) { + stub_eth_params.local_if_name = strdup( + *(L1_ParamList.paramarray[j][L1_LOCAL_N_IF_NAME_IDX].strptr)); + stub_eth_params.my_addr = strdup( + *(L1_ParamList.paramarray[j][L1_LOCAL_N_ADDRESS_IDX].strptr)); + stub_eth_params.remote_addr = strdup( + *(L1_ParamList.paramarray[j][L1_REMOTE_N_ADDRESS_IDX].strptr)); + stub_eth_params.my_portc = + *(L1_ParamList.paramarray[j][L1_LOCAL_N_PORTC_IDX].iptr); + stub_eth_params.remote_portc = + *(L1_ParamList.paramarray[j][L1_REMOTE_N_PORTC_IDX].iptr); + stub_eth_params.my_portd = + *(L1_ParamList.paramarray[j][L1_LOCAL_N_PORTD_IDX].iptr); + stub_eth_params.remote_portd = + *(L1_ParamList.paramarray[j][L1_REMOTE_N_PORTD_IDX].iptr); + stub_eth_params.transp_preference = ETH_UDP_MODE; + } + } + } +} diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h index 1ba8238f1e..2a8a514769 100755 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h @@ -35,10 +35,21 @@ #include "platform_types.h" #include +#include #include "fapi_nr_ue_interface.h" +#include "openair2/PHY_INTERFACE/queue_t.h" +#include "nfapi_nr_interface_scf.h" +#include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h" typedef struct NR_UL_TIME_ALIGNMENT NR_UL_TIME_ALIGNMENT_t; +typedef struct nr_phy_channel_params_t +{ + uint16_t sfn_slot; + float sinr; + // Incomplete, need all channel parameters +} nr_phy_channel_params_t; + typedef enum { ONLY_PUSCH, NOT_PUSCH, @@ -209,6 +220,25 @@ typedef struct nr_ue_if_module_s { \param module_id module id*/ nr_ue_if_module_t *nr_ue_if_module_init(uint32_t module_id); +void nrue_init_standalone_socket(int tx_port, int rx_port); + +void *nrue_standalone_pnf_task(void *context); +extern sem_t sfn_slot_semaphore; + +typedef struct nfapi_dl_tti_config_req_tx_data_req_t +{ + nfapi_nr_dl_tti_request_pdu_t *dl_itti_config_req; + nfapi_nr_tx_data_request_t *tx_data_req_pdu_list; +} nfapi_dl_tti_config_req_tx_data_req_t; + +void send_nsa_standalone_msg(NR_UL_IND_t *UL_INFO, uint16_t msg_id); + +void save_nr_measurement_info(nfapi_nr_dl_tti_request_t *dl_tti_request); + +void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request, + nfapi_nr_tx_data_request_t *tx_data_request, + nfapi_nr_ul_dci_request_t *ul_dci_request, + nfapi_nr_ul_tti_request_t *ul_tti_request); /**\brief done free of memory allocation by module_id and release to pointer pool. \param module_id module id*/ diff --git a/openair2/PHY_INTERFACE/.gitignore b/openair2/PHY_INTERFACE/.gitignore new file mode 100644 index 0000000000..2dca7a7611 --- /dev/null +++ b/openair2/PHY_INTERFACE/.gitignore @@ -0,0 +1 @@ +/queue_test diff --git a/openair2/PHY_INTERFACE/IF_Module.c b/openair2/PHY_INTERFACE/IF_Module.c index ed3c9a5b7d..fba9e1d8b6 100644 --- a/openair2/PHY_INTERFACE/IF_Module.c +++ b/openair2/PHY_INTERFACE/IF_Module.c @@ -24,25 +24,31 @@ extern RAN_CONTEXT_t RC; uint16_t frame_cnt=0; void handle_rach(UL_IND_t *UL_info) { int i; - - if(NFAPI_MODE == NFAPI_MODE_VNF) { - for(uint8_t j = 0; j < NUM_NFPAI_SUBFRAME; j++) { - if (UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles>0) { - AssertFatal(UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles==1,"More than 1 preamble not supported\n"); - LOG_D(MAC,"UL_info[Frame %d, Subframe %d] Calling initiate_ra_proc RACH:SFN/SF:%d\n",UL_info->frame,UL_info->subframe, NFAPI_SFNSF2DEC(UL_RCC_INFO.rach_ind[j].sfn_sf)); - initiate_ra_proc(UL_info->module_id, - UL_info->CC_id, - NFAPI_SFNSF2SFN(UL_RCC_INFO.rach_ind[j].sfn_sf), - NFAPI_SFNSF2SF(UL_RCC_INFO.rach_ind[j].sfn_sf), - UL_RCC_INFO.rach_ind[j].rach_indication_body.preamble_list[0].preamble_rel8.preamble, - UL_RCC_INFO.rach_ind[j].rach_indication_body.preamble_list[0].preamble_rel8.timing_advance, - UL_RCC_INFO.rach_ind[j].rach_indication_body.preamble_list[0].preamble_rel8.rnti, - 0 - ); - free(UL_RCC_INFO.rach_ind[j].rach_indication_body.preamble_list); - UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles = 0; - UL_RCC_INFO.rach_ind[j].header.message_id = 0; + int j = UL_info->subframe; + AssertFatal(j < sizeof(UL_RCC_INFO.rach_ind) / sizeof(UL_RCC_INFO.rach_ind[0]), "j index out of range of index of rach_ind\n"); + if (NFAPI_MODE == NFAPI_MODE_VNF) + { + if (UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles > 0) + { + if (UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles > 1) + { + LOG_D(MAC, "handle_rach j: %d UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles: %d\n", + j, UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles); + LOG_D(MAC, "UL_info[Frame %d, Subframe %d] Calling initiate_ra_proc RACH:Frame: %d Subframe: %d\n", + UL_info->frame, UL_info->subframe, NFAPI_SFNSF2SFN(UL_RCC_INFO.rach_ind[j].sfn_sf), NFAPI_SFNSF2SF(UL_RCC_INFO.rach_ind[j].sfn_sf)); } + AssertFatal(UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles == 1, "More than 1 preamble not supported\n"); // dump frame/sf and all things in UL_RCC_INFO + initiate_ra_proc(UL_info->module_id, + UL_info->CC_id, + NFAPI_SFNSF2SFN(UL_RCC_INFO.rach_ind[j].sfn_sf), + NFAPI_SFNSF2SF(UL_RCC_INFO.rach_ind[j].sfn_sf), + UL_RCC_INFO.rach_ind[j].rach_indication_body.preamble_list[0].preamble_rel8.preamble, + UL_RCC_INFO.rach_ind[j].rach_indication_body.preamble_list[0].preamble_rel8.timing_advance, + UL_RCC_INFO.rach_ind[j].rach_indication_body.preamble_list[0].preamble_rel8.rnti, + 0); + free(UL_RCC_INFO.rach_ind[j].rach_indication_body.preamble_list); + UL_RCC_INFO.rach_ind[j].rach_indication_body.number_of_preambles = 0; + UL_RCC_INFO.rach_ind[j].header.message_id = 0; } } else { if (UL_info->rach_ind.rach_indication_body.number_of_preambles>0) { @@ -92,8 +98,9 @@ void handle_sr(UL_IND_t *UL_info) { oai_nfapi_sr_indication(&UL_info->sr_ind); } } else if(NFAPI_MODE == NFAPI_MODE_VNF) { - for(uint8_t j = 0; j < NUM_NFPAI_SUBFRAME; j++) { + for(uint8_t j = 0; j < NUM_NFAPI_SUBFRAME; j++) { if(UL_RCC_INFO.sr_ind[j].sr_indication_body.number_of_srs > 0) { + assert(UL_RCC_INFO.sr_ind[j].sr_indication_body.number_of_srs <= NFAPI_SR_IND_MAX_PDU); for (i=0; imodule_id, UL_info->CC_id, @@ -109,6 +116,7 @@ void handle_sr(UL_IND_t *UL_info) { } } } else { + assert(UL_info->sr_ind.sr_indication_body.number_of_srs <= NFAPI_SR_IND_MAX_PDU); for (i=0; isr_ind.sr_indication_body.number_of_srs; i++) SR_indication(UL_info->module_id, UL_info->CC_id, @@ -133,8 +141,9 @@ void handle_cqi(UL_IND_t *UL_info) { UL_info->cqi_ind.cqi_indication_body.number_of_cqis=0; } } else if (NFAPI_MODE == NFAPI_MODE_VNF) { - for(uint8_t j = 0; j < NUM_NFPAI_SUBFRAME; j++) { + for(uint8_t j = 0; j < NUM_NFAPI_SUBFRAME; j++) { if(UL_RCC_INFO.cqi_ind[j].cqi_indication_body.number_of_cqis > 0) { + assert(UL_RCC_INFO.cqi_ind[j].cqi_indication_body.number_of_cqis <= NFAPI_CQI_IND_MAX_PDU); for (i=0; imodule_id, UL_info->CC_id, @@ -153,6 +162,7 @@ void handle_cqi(UL_IND_t *UL_info) { } } } else { + assert(UL_info->cqi_ind.cqi_indication_body.number_of_cqis <= NFAPI_CQI_IND_MAX_PDU); for (i=0; icqi_ind.cqi_indication_body.number_of_cqis; i++) cqi_indication(UL_info->module_id, UL_info->CC_id, @@ -178,8 +188,9 @@ void handle_harq(UL_IND_t *UL_info) { UL_info->harq_ind.harq_indication_body.number_of_harqs = 0; } else if(NFAPI_MODE == NFAPI_MODE_VNF) { - for(uint8_t j = 0; j < NUM_NFPAI_SUBFRAME; j++) { + for(uint8_t j = 0; j < NUM_NFAPI_SUBFRAME; j++) { if(UL_RCC_INFO.harq_ind[j].harq_indication_body.number_of_harqs > 0) { + assert(UL_RCC_INFO.harq_ind[j].harq_indication_body.number_of_harqs <= NFAPI_HARQ_IND_MAX_PDU); for (int i=0; imodule_id, UL_info->CC_id, @@ -194,6 +205,7 @@ void handle_harq(UL_IND_t *UL_info) { } } } else { + assert(UL_info->harq_ind.harq_indication_body.number_of_harqs <= NFAPI_HARQ_IND_MAX_PDU); for (int i=0; i < UL_info->harq_ind.harq_indication_body.number_of_harqs; i++) harq_indication(UL_info->module_id, UL_info->CC_id, @@ -221,9 +233,11 @@ void handle_ulsch(UL_IND_t *UL_info) { UL_info->rx_ind.rx_indication_body.number_of_pdus = 0; } } else if(NFAPI_MODE == NFAPI_MODE_VNF) { - for(uint8_t k = 0; k < NUM_NFPAI_SUBFRAME; k++) { + for(uint8_t k = 0; k < NUM_NFAPI_SUBFRAME; k++) { if((UL_RCC_INFO.rx_ind[k].rx_indication_body.number_of_pdus>0) && (UL_RCC_INFO.crc_ind[k].crc_indication_body.number_of_crcs>0)) { + assert(UL_RCC_INFO.rx_ind[k].rx_indication_body.number_of_pdus <= NFAPI_RX_IND_MAX_PDU); for (i=0; icrc_ind.crc_indication_body.crc_pdu_list[%d].rx_ue_information.rnti:%04x UL_info->rx_ind.rx_indication_body.rx_pdu_list[%d].rx_ue_information.rnti:%04x\n", @@ -251,16 +265,12 @@ void handle_ulsch(UL_IND_t *UL_info) { NFAPI_SFNSF2SFN(UL_RCC_INFO.rx_ind[k].sfn_sf), //UL_info->frame, NFAPI_SFNSF2SF(UL_RCC_INFO.rx_ind[k].sfn_sf), //UL_info->subframe, UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti, - UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].data, + UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_ind_data, UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length, UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_indication_rel8.timing_advance, UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].rx_indication_rel8.ul_cqi); } - if(UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].data != NULL) { - free(UL_RCC_INFO.rx_ind[k].rx_indication_body.rx_pdu_list[i].data); - } - break; } //if (UL_info->crc_ind.crc_pdu_list[j].rx_ue_information.rnti == UL_info->rx_ind.rx_pdu_list[i].rx_ue_information.rnti) } // for (j=0;jcrc_ind.crc_indication_body.number_of_crcs;j++) @@ -276,7 +286,9 @@ void handle_ulsch(UL_IND_t *UL_info) { } } else { if (UL_info->rx_ind.rx_indication_body.number_of_pdus>0 && UL_info->crc_ind.crc_indication_body.number_of_crcs>0) { + assert(UL_info->rx_ind.rx_indication_body.number_of_pdus <= NFAPI_RX_IND_MAX_PDU); for (i=0; irx_ind.rx_indication_body.number_of_pdus; i++) { + assert(UL_info->crc_ind.crc_indication_body.number_of_crcs <= NFAPI_CRC_IND_MAX_PDU); for (j=0; jcrc_ind.crc_indication_body.number_of_crcs; j++) { // find crc_indication j corresponding rx_indication i LOG_D(PHY,"UL_info->crc_ind.crc_indication_body.crc_pdu_list[%d].rx_ue_information.rnti:%04x UL_info->rx_ind.rx_indication_body.rx_pdu_list[%d].rx_ue_information.rnti:%04x\n", j, @@ -304,7 +316,7 @@ void handle_ulsch(UL_IND_t *UL_info) { NFAPI_SFNSF2SFN(UL_info->rx_ind.sfn_sf), //UL_info->frame, NFAPI_SFNSF2SF(UL_info->rx_ind.sfn_sf), //UL_info->subframe, UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_ue_information.rnti, - UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].data, + UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_ind_data, UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.length, UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.timing_advance, UL_info->rx_ind.rx_indication_body.rx_pdu_list[i].rx_indication_rel8.ul_cqi); @@ -790,6 +802,7 @@ IF_Module_t *IF_Module_init(int Mod_id) { "allocation of if_inst[%d]->if_mutex fails\n",Mod_id); } + memset(&UL_RCC_INFO, 0, sizeof(UL_RCC_INFO)); return if_inst[Mod_id]; } diff --git a/openair2/PHY_INTERFACE/IF_Module.h b/openair2/PHY_INTERFACE/IF_Module.h index 096979c4fd..b1123dce5f 100644 --- a/openair2/PHY_INTERFACE/IF_Module.h +++ b/openair2/PHY_INTERFACE/IF_Module.h @@ -87,25 +87,25 @@ typedef struct { } UL_IND_t; // Downlink subframe P7 -#define NUM_NFPAI_SUBFRAME 5 +#define NUM_NFAPI_SUBFRAME 10 typedef struct { /// harq indication list - nfapi_harq_indication_t harq_ind[NUM_NFPAI_SUBFRAME]; + nfapi_harq_indication_t harq_ind[NUM_NFAPI_SUBFRAME]; /// crc indication list - nfapi_crc_indication_t crc_ind[NUM_NFPAI_SUBFRAME]; + nfapi_crc_indication_t crc_ind[NUM_NFAPI_SUBFRAME]; /// SR indication list - nfapi_sr_indication_t sr_ind[NUM_NFPAI_SUBFRAME]; + nfapi_sr_indication_t sr_ind[NUM_NFAPI_SUBFRAME]; /// CQI indication list - nfapi_cqi_indication_t cqi_ind[NUM_NFPAI_SUBFRAME]; + nfapi_cqi_indication_t cqi_ind[NUM_NFAPI_SUBFRAME]; /// RACH indication list - nfapi_rach_indication_t rach_ind[NUM_NFPAI_SUBFRAME]; + nfapi_rach_indication_t rach_ind[NUM_NFAPI_SUBFRAME]; /// RX indication - nfapi_rx_indication_t rx_ind[NUM_NFPAI_SUBFRAME]; + nfapi_rx_indication_t rx_ind[NUM_NFAPI_SUBFRAME]; } UL_RCC_IND_t; @@ -151,6 +151,17 @@ typedef struct IF_Module_s{ pthread_mutex_t if_mutex; } IF_Module_t; +// These mutex is used for multiple UEs L2 FAPI simulator. +// Each UEs set these value in UL and UL_INFO is shared in all UE's thread. +typedef struct { + pthread_mutex_t rx_mutex; + pthread_mutex_t crc_mutex; + pthread_mutex_t sr_mutex; + pthread_mutex_t harq_mutex; + pthread_mutex_t cqi_mutex; + pthread_mutex_t rach_mutex; +} FILL_UL_INFO_MUTEX_t; + /*Initial */ IF_Module_t *IF_Module_init(int Mod_id); void IF_Module_kill(int Mod_id); diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c index c212075934..1598e3d620 100644 --- a/openair2/PHY_INTERFACE/phy_stub_UE.c +++ b/openair2/PHY_INTERFACE/phy_stub_UE.c @@ -30,10 +30,14 @@ #include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h" #include "common/config/config_load_configmodule.h" #include "common/config/config_userapi.h" +#include +#include +#include #include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h" #include "openair1/PHY/defs_gNB.h" #include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h" #include "openair1/PHY/LTE_TRANSPORT/transport_common.h" +#include "softmodem-common.h" extern int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind); void configure_nfapi_pnf(char *vnf_ip_addr, @@ -43,15 +47,33 @@ void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p7_port); UL_IND_t *UL_INFO = NULL; -nfapi_tx_request_pdu_t* tx_request_pdu_list = NULL; -nfapi_dl_config_request_t* dl_config_req = NULL; -nfapi_ul_config_request_t* ul_config_req = NULL; -nfapi_hi_dci0_request_t* hi_dci0_req = NULL; -extern nfapi_tx_request_pdu_t* tx_request_pdu[1023][10][10]; +queue_t dl_config_req_tx_req_queue; +queue_t ul_config_req_queue; +queue_t hi_dci0_req_queue; + +FILL_UL_INFO_MUTEX_t fill_ul_mutex; + +int current_sfn_sf; +sem_t sfn_semaphore; + +static sf_rnti_mcs_s sf_rnti_mcs[NUM_NFAPI_SUBFRAME]; + +static int ue_tx_sock_descriptor = -1; +static int ue_rx_sock_descriptor = -1; +static int get_mcs_from_sinr(float sinr); +static int get_cqi_from_mcs(void); +static void read_channel_param(const nfapi_dl_config_request_pdu_t * pdu, int sf, int index); +static bool did_drop_transport_block(int sf, uint16_t rnti); +static float get_bler_val(uint8_t mcs, int sinr); +static bool should_drop_transport_block(int sf, uint16_t rnti); +static void save_dci_pdu_for_crnti(nfapi_dl_config_request_t *dl_config_req); + +extern nfapi_tx_request_pdu_t* tx_request_pdu[1023][NUM_NFAPI_SUBFRAME][10]; //TODO: NFAPI_TX_MAX_PDU for last dim? Check nfapi_pnf.c ln. 81 //extern int timer_subframe; //extern int timer_frame; +extern UE_RRC_INST *UE_rrc_inst; extern uint16_t sf_ahead; static eth_params_t stub_eth_params; @@ -65,14 +87,19 @@ void fill_rx_indication_UE_MAC(module_id_t Mod_id, uint8_t *ulsch_buffer, uint16_t buflen, uint16_t rnti, - int index) { + int index, + nfapi_ul_config_request_t *ul_config_req) { nfapi_rx_indication_pdu_t *pdu; int timing_advance_update; + pthread_mutex_lock(&fill_ul_mutex.rx_mutex); + + UL_INFO->rx_ind.header.message_id = NFAPI_RX_ULSCH_INDICATION; UL_INFO->rx_ind.sfn_sf = frame << 4 | subframe; UL_INFO->rx_ind.rx_indication_body.tl.tag = NFAPI_RX_INDICATION_BODY_TAG; UL_INFO->rx_ind.vendor_extension = ul_config_req->vendor_extension; + assert(UL_INFO->rx_ind.rx_indication_body.number_of_pdus <= NFAPI_RX_IND_MAX_PDU); pdu = &UL_INFO->rx_ind.rx_indication_body .rx_pdu_list[UL_INFO->rx_ind.rx_indication_body.number_of_pdus]; // pdu = &UL_INFO->rx_ind.rx_indication_body.rx_pdu_list[index]; @@ -87,8 +114,10 @@ void fill_rx_indication_UE_MAC(module_id_t Mod_id, pdu->rx_indication_rel9.timing_advance_r9 = 0; // ulsch_buffer is necessary to keep its value. - pdu->data = malloc(buflen); - memcpy(pdu->data, ulsch_buffer, buflen); + assert(buflen <= NFAPI_RX_IND_DATA_MAX); + memcpy(pdu->rx_ind_data, ulsch_buffer, buflen); + LOG_I(MAC, "buflen of rx_ind pdu_data = %u SFN.SF: %d.%d\n", buflen, + frame, subframe); // estimate timing advance for MAC timing_advance_update = 0; // Don't know what to put here pdu->rx_indication_rel8.timing_advance = timing_advance_update; @@ -104,15 +133,21 @@ void fill_rx_indication_UE_MAC(module_id_t Mod_id, UL_INFO->rx_ind.rx_indication_body.number_of_pdus++; UL_INFO->rx_ind.sfn_sf = frame << 4 | subframe; + + pthread_mutex_unlock(&fill_ul_mutex.rx_mutex); } void fill_sr_indication_UE_MAC(int Mod_id, int frame, int subframe, UL_IND_t *UL_INFO, - uint16_t rnti) { + uint16_t rnti, + nfapi_ul_config_request_t *ul_config_req) { + pthread_mutex_lock(&fill_ul_mutex.sr_mutex); + nfapi_sr_indication_t *sr_ind = &UL_INFO->sr_ind; nfapi_sr_indication_body_t *sr_ind_body = &sr_ind->sr_indication_body; + assert(sr_ind_body->number_of_srs <= NFAPI_SR_IND_MAX_PDU); nfapi_sr_indication_pdu_t *pdu = &sr_ind_body->sr_pdu_list[sr_ind_body->number_of_srs]; UL_INFO->sr_ind.vendor_extension = ul_config_req->vendor_extension; @@ -139,6 +174,8 @@ void fill_sr_indication_UE_MAC(int Mod_id, // UL_INFO->rx_ind.rx_indication_body.number_of_pdus++; sr_ind_body->number_of_srs++; + + pthread_mutex_unlock(&fill_ul_mutex.sr_mutex); } void fill_crc_indication_UE_MAC(int Mod_id, @@ -147,7 +184,12 @@ void fill_crc_indication_UE_MAC(int Mod_id, UL_IND_t *UL_INFO, uint8_t crc_flag, int index, - uint16_t rnti) { + uint16_t rnti, + nfapi_ul_config_request_t *ul_config_req) { + pthread_mutex_lock(&fill_ul_mutex.crc_mutex); + LOG_D(MAC, "fill crc_indication num_crcs: %u\n", + UL_INFO->crc_ind.crc_indication_body.number_of_crcs); + assert(UL_INFO->crc_ind.crc_indication_body.number_of_crcs < NUMBER_OF_UE_MAX); nfapi_crc_indication_pdu_t *pdu = &UL_INFO->crc_ind.crc_indication_body .crc_pdu_list[UL_INFO->crc_ind.crc_indication_body.number_of_crcs]; @@ -171,6 +213,8 @@ void fill_crc_indication_UE_MAC(int Mod_id, __FUNCTION__, pdu->rx_ue_information.rnti, UL_INFO->crc_ind.crc_indication_body.number_of_crcs); + + pthread_mutex_unlock(&fill_ul_mutex.crc_mutex); } void fill_rach_indication_UE_MAC(int Mod_id, @@ -179,6 +223,8 @@ void fill_rach_indication_UE_MAC(int Mod_id, UL_IND_t *UL_INFO, uint8_t ra_PreambleIndex, uint16_t ra_RNTI) { + pthread_mutex_lock(&fill_ul_mutex.rach_mutex); + UL_INFO->rach_ind.rach_indication_body.number_of_preambles = 1; UL_INFO->rach_ind.header.message_id = NFAPI_RACH_INDICATION; @@ -221,8 +267,15 @@ void fill_rach_indication_UE_MAC(int Mod_id, // This function is currently defined only in the nfapi-RU-RAU-split so we // should call it when we merge with that branch. - oai_nfapi_rach_ind(&UL_INFO->rach_ind); + if (NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF) { + send_standalone_msg(UL_INFO, UL_INFO->rach_ind.header.message_id); + } else { + oai_nfapi_rach_ind(&UL_INFO->rach_ind); + } + free(UL_INFO->rach_ind.rach_indication_body.preamble_list); + + pthread_mutex_unlock(&fill_ul_mutex.rach_mutex); } void fill_ulsch_cqi_indication_UE_MAC(int Mod_id, @@ -230,6 +283,10 @@ void fill_ulsch_cqi_indication_UE_MAC(int Mod_id, uint8_t subframe, UL_IND_t *UL_INFO, uint16_t rnti) { + pthread_mutex_lock(&fill_ul_mutex.cqi_mutex); + LOG_D(MAC, "num_cqis: %u in fill_ulsch_cqi_indication_UE_MAC\n", + UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis); + assert(UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis <= NFAPI_CQI_IND_MAX_PDU); nfapi_cqi_indication_pdu_t *pdu = &UL_INFO->cqi_ind.cqi_indication_body .cqi_pdu_list[UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis]; @@ -240,7 +297,7 @@ void fill_ulsch_cqi_indication_UE_MAC(int Mod_id, UL_INFO->cqi_ind.sfn_sf = frame << 4 | subframe; // because of nfapi_vnf.c:733, set message id to 0, not // NFAPI_RX_CQI_INDICATION; - UL_INFO->cqi_ind.header.message_id = 0; + UL_INFO->cqi_ind.header.message_id = NFAPI_RX_CQI_INDICATION; UL_INFO->cqi_ind.cqi_indication_body.tl.tag = NFAPI_CQI_INDICATION_BODY_TAG; pdu->rx_ue_information.tl.tag = NFAPI_RX_UE_INFORMATION_TAG; @@ -256,13 +313,15 @@ void fill_ulsch_cqi_indication_UE_MAC(int Mod_id, pdu->cqi_indication_rel8.timing_advance = 0; // pdu->cqi_indication_rel8.number_of_cc_reported = 1; pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG; - pdu->ul_cqi_information.channel = 1; // PUSCH + pdu->ul_cqi_information.channel = 1; // eNB_scheduler_primitives.c:4839: the upper four bits seem to be the CQI - const int cqi = 15; + const int cqi = get_cqi_from_mcs(); raw_pdu->pdu[0] = cqi << 4; UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis++; + + pthread_mutex_unlock(&fill_ul_mutex.cqi_mutex); } void fill_ulsch_harq_indication_UE_MAC( @@ -271,7 +330,11 @@ void fill_ulsch_harq_indication_UE_MAC( int subframe, UL_IND_t *UL_INFO, nfapi_ul_config_ulsch_harq_information *harq_information, - uint16_t rnti) { + uint16_t rnti, + nfapi_ul_config_request_t *ul_config_req) { + pthread_mutex_lock(&fill_ul_mutex.harq_mutex); + + assert(UL_INFO->harq_ind.harq_indication_body.number_of_harqs <= NFAPI_HARQ_IND_MAX_PDU); nfapi_harq_indication_pdu_t *pdu = &UL_INFO->harq_ind.harq_indication_body.harq_pdu_list [UL_INFO->harq_ind.harq_indication_body.number_of_harqs]; @@ -303,6 +366,8 @@ void fill_ulsch_harq_indication_UE_MAC( } UL_INFO->harq_ind.harq_indication_body.number_of_harqs++; + + pthread_mutex_unlock(&fill_ul_mutex.harq_mutex); } void fill_uci_harq_indication_UE_MAC(int Mod_id, @@ -310,9 +375,13 @@ void fill_uci_harq_indication_UE_MAC(int Mod_id, int subframe, UL_IND_t *UL_INFO, nfapi_ul_config_harq_information *harq_information, - uint16_t rnti) { + uint16_t rnti, + nfapi_ul_config_request_t *ul_config_req) { + pthread_mutex_lock(&fill_ul_mutex.harq_mutex); + nfapi_harq_indication_t *ind = &UL_INFO->harq_ind; nfapi_harq_indication_body_t *body = &ind->harq_indication_body; + assert(UL_INFO->harq_ind.harq_indication_body.number_of_harqs <= NFAPI_HARQ_IND_MAX_PDU); nfapi_harq_indication_pdu_t *pdu = &body->harq_pdu_list[UL_INFO->harq_ind.harq_indication_body .number_of_harqs]; @@ -330,7 +399,7 @@ void fill_uci_harq_indication_UE_MAC(int Mod_id, pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG; - int SNRtimes10 = 640; + int SNRtimes10 = 640; // TODO: Replace with EpiSci SNR * 10 if (SNRtimes10 < -640) pdu->ul_cqi_information.ul_cqi = 0; @@ -353,6 +422,17 @@ void fill_uci_harq_indication_UE_MAC(int Mod_id, pdu->harq_indication_fdd_rel13.harq_tb_n[0] = 1; // Assuming always an ACK (No NACK or DTX) + // TODO: Fix ack/dtx -- needed for 5G + // 1.) if received dl_config_req (with c-rnti) store this info and corresponding subframe. + // 2.) if receiving ul_config_req for uci ack/nack or ulsch ack/nak in subframe n + // go look to see if dl_config_req (with c-rnti) was received in subframe (n - 4) + // 3.) if the answer to #2 is yes then send ACK IF NOT send DTX + if (did_drop_transport_block(((subframe+6) % 10), rnti)) // TODO: Handle DTX. Also discuss handling PDCCH + { + pdu->harq_indication_fdd_rel13.harq_tb_n[0] = 2; + LOG_I(PHY, "Setting HARQ No ACK - Channel Model\n"); + } + } else if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 0) && (harq_information->harq_information_rel9_fdd.harq_size == 2)) { @@ -392,6 +472,8 @@ void fill_uci_harq_indication_UE_MAC(int Mod_id, LOG_D(PHY, "Incremented eNB->UL_INFO.harq_ind.number_of_harqs:%d\n", UL_INFO->harq_ind.harq_indication_body.number_of_harqs); + + pthread_mutex_unlock(&fill_ul_mutex.harq_mutex); } void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id, @@ -399,7 +481,8 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id, uint16_t frame, uint8_t subframe, uint8_t srs_present, - int index) { + int index, + nfapi_ul_config_request_t *ul_config_req) { if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) { LOG_D(PHY, "Applying UL config for UE, rnti %x for frame %d, subframe %d\n", @@ -418,7 +501,8 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id, Mod_id, frame, subframe); - fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti); + fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti, + ul_config_req); fill_rx_indication_UE_MAC(Mod_id, frame, subframe, @@ -426,7 +510,8 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id, UE_mac_inst[Mod_id].RA_prach_resources.Msg3, buflen, rnti, - index); + index, + ul_config_req); Msg3_transmitted(Mod_id, 0, frame, 0); // Modification UE_mac_inst[Mod_id].UE_mode[0] = PUSCH; @@ -436,7 +521,7 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id, // UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; } else { ue_get_sdu(Mod_id, 0, frame, subframe, 0, ulsch_buffer, buflen, &access_mode); - fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti); + fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti, ul_config_req); fill_rx_indication_UE_MAC(Mod_id, frame, subframe, @@ -444,7 +529,8 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id, ulsch_buffer, buflen, rnti, - index); + index, + ul_config_req); } } } @@ -462,8 +548,8 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id, uint16_t rnti = ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti; uint8_t access_mode = SCHEDULED_ACCESS; if (buflen > 0) { - if (UE_mac_inst[Mod_id].first_ULSCH_Tx == 1) { // Msg3 case - fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti); + if (UE_mac_inst[Mod_id].first_ULSCH_Tx == 1) { + fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti, ul_config_req); fill_rx_indication_UE_MAC(Mod_id, frame, subframe, @@ -471,7 +557,8 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id, UE_mac_inst[Mod_id].RA_prach_resources.Msg3, buflen, rnti, - index); + index, + ul_config_req); Msg3_transmitted(Mod_id, 0, frame, 0); // UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; // Modification @@ -479,7 +566,7 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id, UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; } else { ue_get_sdu(Mod_id, 0, frame, subframe, 0, ulsch_buffer, buflen, &access_mode); - fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti); + fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti, ul_config_req); fill_rx_indication_UE_MAC(Mod_id, frame, subframe, @@ -487,12 +574,13 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id, ulsch_buffer, buflen, rnti, - index); + index, + ul_config_req); } } if (ulsch_harq_information != NULL) fill_ulsch_harq_indication_UE_MAC( - Mod_id, frame, subframe, UL_INFO, ulsch_harq_information, rnti); + Mod_id, frame, subframe, UL_INFO, ulsch_harq_information, rnti, ul_config_req); } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE) { uint8_t ulsch_buffer[5477] __attribute__((aligned(32))); @@ -502,7 +590,7 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id, uint8_t access_mode = SCHEDULED_ACCESS; if (buflen > 0) { if (UE_mac_inst[Mod_id].first_ULSCH_Tx == 1) { // Msg3 case - fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti); + fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti, ul_config_req); fill_rx_indication_UE_MAC(Mod_id, frame, subframe, @@ -510,7 +598,8 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id, UE_mac_inst[Mod_id].RA_prach_resources.Msg3, buflen, rnti, - index); + index, + ul_config_req); Msg3_transmitted(Mod_id, 0, frame, 0); // UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; // Modification @@ -518,7 +607,7 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id, UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; } else { ue_get_sdu(Mod_id, 0, frame, subframe, 0, ulsch_buffer, buflen, &access_mode); - fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti); + fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti, ul_config_req); fill_rx_indication_UE_MAC(Mod_id, frame, subframe, @@ -526,7 +615,9 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id, ulsch_buffer, buflen, rnti, - index); + index, + ul_config_req); + fill_ulsch_cqi_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, rnti); } } } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE) { @@ -539,7 +630,7 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id, uint8_t access_mode = SCHEDULED_ACCESS; if (buflen > 0) { if (UE_mac_inst[Mod_id].first_ULSCH_Tx == 1) { // Msg3 case - fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti); + fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti, ul_config_req); fill_rx_indication_UE_MAC(Mod_id, frame, subframe, @@ -547,7 +638,8 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id, UE_mac_inst[Mod_id].RA_prach_resources.Msg3, buflen, rnti, - index); + index, + ul_config_req); Msg3_transmitted(Mod_id, 0, frame, 0); // UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; // Modification @@ -555,7 +647,7 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id, UE_mac_inst[Mod_id].first_ULSCH_Tx = 0; } else { ue_get_sdu(Mod_id, 0, frame, subframe, 0, ulsch_buffer, buflen, &access_mode); - fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti); + fill_crc_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, 0, index, rnti, ul_config_req); fill_rx_indication_UE_MAC(Mod_id, frame, subframe, @@ -563,18 +655,20 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id, ulsch_buffer, buflen, rnti, - index); + index, + ul_config_req); + fill_ulsch_cqi_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, rnti); } } if (ulsch_harq_information != NULL) - fill_ulsch_harq_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_harq_information, rnti); + fill_ulsch_harq_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_harq_information, rnti, ul_config_req); } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) { uint16_t rnti = ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti; nfapi_ul_config_harq_information *ulsch_harq_information = &ul_config_pdu->uci_harq_pdu.harq_information; if (ulsch_harq_information != NULL) - fill_uci_harq_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_harq_information, rnti); + fill_uci_harq_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, ulsch_harq_information, rnti, ul_config_req); } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE) { AssertFatal(1 == 0, "NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE not handled yet\n"); } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE) { @@ -588,7 +682,7 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id, ul_config_pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti; if (ue_get_SR(Mod_id, 0, frame, 0, rnti, subframe)) - fill_sr_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, rnti); + fill_sr_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, rnti, ul_config_req); } else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE) { // AssertFatal((UE_id = @@ -602,13 +696,13 @@ void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id, // We fill the sr_indication only if ue_get_sr() would normally instruct PHY // to send a SR. if (ue_get_SR(Mod_id, 0, frame, 0, rnti, subframe)) - fill_sr_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, rnti); + fill_sr_indication_UE_MAC(Mod_id, frame, subframe, UL_INFO, rnti, ul_config_req); nfapi_ul_config_harq_information *ulsch_harq_information = &ul_config_pdu->uci_sr_harq_pdu.harq_information; if (ulsch_harq_information != NULL) fill_uci_harq_indication_UE_MAC( - Mod_id, frame, subframe, UL_INFO, ulsch_harq_information, rnti); + Mod_id, frame, subframe, UL_INFO, ulsch_harq_information, rnti, ul_config_req); } } @@ -625,6 +719,9 @@ int ul_config_req_UE_MAC(nfapi_ul_config_request_t *req, req->ul_config_request_body.rach_prach_frequency_resources, req->ul_config_request_body.srs_present); + LOG_D(MAC, "ul_config_req Frame: %d Subframe: %d Proxy Frame: %u Subframe: %u\n", + NFAPI_SFNSF2SFN(req->sfn_sf), NFAPI_SFNSF2SF(req->sfn_sf), + timer_frame, timer_subframe); int sfn = NFAPI_SFNSF2SFN(req->sfn_sf); int sf = NFAPI_SFNSF2SF(req->sfn_sf); @@ -654,10 +751,9 @@ int ul_config_req_UE_MAC(nfapi_ul_config_request_t *req, || (pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE && pdu->uci_cqi_sr_harq_pdu.ue_information.ue_information_rel8.rnti == rnti)) { handle_nfapi_ul_pdu_UE_MAC( - Mod_id, pdu, sfn, sf, req->ul_config_request_body.srs_present, i); + Mod_id, pdu, sfn, sf, req->ul_config_request_body.srs_present, i, req); } else { - // NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() PDU:%i UNKNOWN type :%d\n", - // __FUNCTION__, i, ul_config_pdu_list[i].pdu_type); + LOG_D(MAC, "UNKNOWN UL_CONFIG_REQ PDU_TYPE or RNTI not matching pdu type: %d\n", pdu_type); } } @@ -693,7 +789,8 @@ void dl_config_req_UE_MAC_dci(int sfn, int sf, nfapi_dl_config_request_pdu_t *dci, nfapi_dl_config_request_pdu_t *dlsch, - int num_ue) { + int num_ue, + nfapi_tx_req_pdu_list_t *tx_req_pdu_list) { DevAssert(dci->pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE); DevAssert(dlsch->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE); @@ -707,7 +804,7 @@ void dl_config_req_UE_MAC_dci(int sfn, } const int pdu_index = dlsch->dlsch_pdu.dlsch_pdu_rel8.pdu_index; - if (pdu_index < 0 || pdu_index >= tx_req_num_elems) { + if (pdu_index < 0 || pdu_index >= tx_req_pdu_list->num_pdus) { LOG_E(MAC, "%s(): Problem with receiving data: " "sfn/sf:%d.%d PDU size:%d, TX_PDU index: %d\n", @@ -716,6 +813,8 @@ void dl_config_req_UE_MAC_dci(int sfn, return; } + LOG_I(MAC, "%s() rnti value: 0x%x rnti type: %d\n", __func__, + rnti, rnti_type); if (rnti_type == 1) { // C-RNTI (Normal DLSCH case) for (int ue_id = 0; ue_id < num_ue; ue_id++) { if (UE_mac_inst[ue_id].crnti == rnti) { @@ -725,11 +824,18 @@ void dl_config_req_UE_MAC_dci(int sfn, __func__, sfn, sf, dci->pdu_size, dlsch->dlsch_pdu.dlsch_pdu_rel8.pdu_index, - tx_req_num_elems); - ue_send_sdu(ue_id, 0, sfn, sf, - tx_request_pdu_list[pdu_index].segments[0].segment_data, - tx_request_pdu_list[pdu_index].segments[0].segment_length, - 0); + tx_req_pdu_list->num_pdus); + if (node_number > 0 || !should_drop_transport_block(sf, dci->dci_dl_pdu.dci_dl_pdu_rel8.rnti)) + { + ue_send_sdu(ue_id, 0, sfn, sf, + tx_req_pdu_list->pdus[pdu_index].segments[0].segment_data, + tx_req_pdu_list->pdus[pdu_index].segments[0].segment_length, + 0); + } + else + { + LOG_I(MAC, "Transport Block discarded - ue_send_sdu not called. sf: %d", sf); + } return; } } @@ -738,18 +844,18 @@ void dl_config_req_UE_MAC_dci(int sfn, for (int ue_id = 0; ue_id < num_ue; ue_id++) { if (UE_mac_inst[ue_id].UE_mode[0] == NOT_SYNCHED) continue; - ue_decode_si(ue_id, 0, sfn, 0, - tx_request_pdu_list[pdu_index].segments[0].segment_data, - tx_request_pdu_list[pdu_index].segments[0].segment_length); + tx_req_pdu_list->pdus[pdu_index].segments[0].segment_data, + tx_req_pdu_list->pdus[pdu_index].segments[0].segment_length); } } else if (rnti == 0xFFFE) { /* PI-RNTI */ for (int ue_id = 0; ue_id < num_ue; ue_id++) { LOG_I(MAC, "%s() Received paging message: sfn/sf:%d.%d\n", __func__, sfn, sf); + ue_decode_p(ue_id, 0, sfn, 0, - tx_request_pdu_list[pdu_index].segments[0].segment_data, - tx_request_pdu_list[pdu_index].segments[0].segment_length); + tx_req_pdu_list->pdus[pdu_index].segments[0].segment_data, + tx_req_pdu_list->pdus[pdu_index].segments[0].segment_length); } } else if (rnti == 0x0002) { /* RA-RNTI */ for (int ue_id = 0; ue_id < num_ue; ue_id++) { @@ -769,19 +875,21 @@ void dl_config_req_UE_MAC_dci(int sfn, LOG_E(MAC, "%s(): Received RAR, PreambleIndex: %d\n", __func__, UE_mac_inst[ue_id].RA_prach_resources.ra_PreambleIndex); + ue_process_rar(ue_id, 0, sfn, ra_rnti, //RA-RNTI - tx_request_pdu_list[pdu_index].segments[0].segment_data, + tx_req_pdu_list->pdus[pdu_index].segments[0].segment_data, &UE_mac_inst[ue_id].crnti, //t-crnti UE_mac_inst[ue_id].RA_prach_resources.ra_PreambleIndex, - tx_request_pdu_list[pdu_index].segments[0].segment_data); - UE_mac_inst[ue_id].UE_mode[0] = RA_RESPONSE; + tx_req_pdu_list->pdus[pdu_index].segments[0].segment_data); + // UE_mac_inst[ue_id].UE_mode[0] = RA_RESPONSE; + LOG_I(MAC, "setting UE_MODE now: %d\n", UE_mac_inst[ue_id].UE_mode[0]); // Expecting an UL_CONFIG_ULSCH_PDU to enable Msg3 Txon (first // ULSCH Txon for the UE) UE_mac_inst[ue_id].first_ULSCH_Tx = 1; } } - } + } //else if (dl_config_pdu_list[i].pdu_type == NFAPI_DL_CONFIG_BCH_PDU_TYPE) { // // BCH case: Last parameter is 1 if first time synchronization and zero // // otherwise. Not sure which value to put for our case. @@ -810,7 +918,7 @@ void dl_config_req_UE_MAC_dci(int sfn, // tx_request_pdu_list[pdu_index].segments[0].segment_length, // 0,0); - //} + //} else { LOG_W(MAC, "can not handle special RNTI %x\n", rnti); } @@ -842,7 +950,8 @@ void dl_config_req_UE_MAC_bch(int sfn, void dl_config_req_UE_MAC_mch(int sfn, int sf, nfapi_dl_config_request_pdu_t *mch, - int num_ue) { + int num_ue, + nfapi_tx_req_pdu_list_t *tx_req_pdu_list) { DevAssert(mch->pdu_type == NFAPI_DL_CONFIG_MCH_PDU_TYPE); for (int ue_id = 0; ue_id < num_ue; ue_id++) { @@ -857,7 +966,7 @@ void dl_config_req_UE_MAC_mch(int sfn, } else { const int pdu_index = mch->mch_pdu.mch_pdu_rel8.pdu_index; - if (pdu_index < 0 || pdu_index >= tx_req_num_elems) { + if (pdu_index < 0 || pdu_index >= tx_req_pdu_list->num_pdus) { LOG_E(MAC, "%s(): Problem with receiving data: " "sfn/sf:%d.%d PDU size:%d, TX_PDU index: %d\n", @@ -866,8 +975,8 @@ void dl_config_req_UE_MAC_mch(int sfn, return; } ue_send_mch_sdu(ue_id, 0, sfn, - tx_request_pdu_list[pdu_index].segments[0].segment_data, - tx_request_pdu_list[pdu_index].segments[0].segment_length, + tx_req_pdu_list->pdus[pdu_index].segments[0].segment_data, + tx_req_pdu_list->pdus[pdu_index].segments[0].segment_length, 0,0); } } @@ -885,7 +994,6 @@ void hi_dci0_req_UE_MAC(int sfn, return; for (int ue_id = 0; ue_id < num_ue; ue_id++) { if (dci->rnti == UE_mac_inst[ue_id].crnti) { - fill_ulsch_cqi_indication_UE_MAC(ue_id, sfn, sf, UL_INFO, dci->rnti); return; } } @@ -893,114 +1001,147 @@ void hi_dci0_req_UE_MAC(int sfn, // The following set of memcpy functions should be getting called as callback // functions from pnf_p7_subframe_ind. -int memcpy_dl_config_req(L1_rxtx_proc_t *proc, - nfapi_pnf_p7_config_t *pnf_p7, - nfapi_dl_config_request_t *req) { - dl_config_req = (nfapi_dl_config_request_t *)malloc(sizeof(nfapi_dl_config_request_t)); - // UE_mac_inst[Mod_id].dl_config_req->header = req->header; - dl_config_req->sfn_sf = req->sfn_sf; - - dl_config_req->vendor_extension = req->vendor_extension; - - dl_config_req->dl_config_request_body.number_dci = req->dl_config_request_body.number_dci; - dl_config_req->dl_config_request_body.number_pdcch_ofdm_symbols = req->dl_config_request_body.number_pdcch_ofdm_symbols; - dl_config_req->dl_config_request_body.number_pdsch_rnti = req->dl_config_request_body.number_pdsch_rnti; - dl_config_req->dl_config_request_body.number_pdu = req->dl_config_request_body.number_pdu; - - dl_config_req->dl_config_request_body.tl.tag = req->dl_config_request_body.tl.tag; - dl_config_req->dl_config_request_body.tl.length = req->dl_config_request_body.tl.length; - - dl_config_req->dl_config_request_body.dl_config_pdu_list = - calloc(req->dl_config_request_body.number_pdu, - sizeof(nfapi_dl_config_request_pdu_t)); - for (int i = 0; i < dl_config_req->dl_config_request_body.number_pdu; i++) { - dl_config_req->dl_config_request_body.dl_config_pdu_list[i] = - req->dl_config_request_body.dl_config_pdu_list[i]; - } - - return 0; -} - -int memcpy_ul_config_req (L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t* pnf_p7, nfapi_ul_config_request_t* req) +static bool is_my_ul_config_req(nfapi_ul_config_request_t *req) { - ul_config_req = malloc(sizeof(nfapi_ul_config_request_t)); - - - ul_config_req->sfn_sf = req->sfn_sf; - ul_config_req->vendor_extension = req->vendor_extension; - - ul_config_req->ul_config_request_body.number_of_pdus = req->ul_config_request_body.number_of_pdus; - ul_config_req->ul_config_request_body.rach_prach_frequency_resources = req->ul_config_request_body.rach_prach_frequency_resources; - ul_config_req->ul_config_request_body.srs_present = req->ul_config_request_body.srs_present; - - ul_config_req->ul_config_request_body.tl.tag = req->ul_config_request_body.tl.tag; - ul_config_req->ul_config_request_body.tl.length = req->ul_config_request_body.tl.length; - - ul_config_req->ul_config_request_body.ul_config_pdu_list = - calloc(req->ul_config_request_body.number_of_pdus, - sizeof(nfapi_ul_config_request_pdu_t)); - for (int i = 0; i < ul_config_req->ul_config_request_body.number_of_pdus; i++) { - ul_config_req->ul_config_request_body.ul_config_pdu_list[i] = - req->ul_config_request_body.ul_config_pdu_list[i]; - } - - return 0; -} - -int memcpy_tx_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_tx_request_t *req) { - tx_req_num_elems = req->tx_request_body.number_of_pdus; - tx_request_pdu_list = calloc(tx_req_num_elems, sizeof(nfapi_tx_request_pdu_t)); - for (int i = 0; i < tx_req_num_elems; i++) { - tx_request_pdu_list[i].num_segments = req->tx_request_body.tx_pdu_list[i].num_segments; - tx_request_pdu_list[i].pdu_index = req->tx_request_body.tx_pdu_list[i].pdu_index; - tx_request_pdu_list[i].pdu_length = req->tx_request_body.tx_pdu_list[i].pdu_length; - for (int j = 0; j < req->tx_request_body.tx_pdu_list[i].num_segments; j++) { - tx_request_pdu_list[i].segments[j].segment_length = req->tx_request_body.tx_pdu_list[i].segments[j].segment_length; - if (tx_request_pdu_list[i].segments[j].segment_length > 0) { - tx_request_pdu_list[i].segments[j].segment_data = calloc( - tx_request_pdu_list[i].segments[j].segment_length, sizeof(uint8_t)); - memcpy(tx_request_pdu_list[i].segments[j].segment_data, - req->tx_request_body.tx_pdu_list[i].segments[j].segment_data, - tx_request_pdu_list[i].segments[j].segment_length); - } + bool is_my_rnti = false; + const rnti_t rnti = UE_mac_inst[0].crnti; // 0 for standalone pnf mode. TODO: Make this more clear - Andrew + for (int i = 0; i < req->ul_config_request_body.number_of_pdus; i++) + { + nfapi_ul_config_request_pdu_t *pdu = &req->ul_config_request_body.ul_config_pdu_list[i]; + const int pdu_type = pdu->pdu_type; + if ((pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE && pdu->ulsch_pdu.ulsch_pdu_rel8.rnti == rnti) || + (pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE && pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti) || + (pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE && pdu->ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti) || + (pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE && pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti == rnti) || + (pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE && pdu->uci_cqi_harq_pdu.ue_information.ue_information_rel8.rnti == rnti) || + (pdu_type == NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE && pdu->uci_sr_pdu.ue_information.ue_information_rel8.rnti == rnti) || + (pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE && pdu->uci_cqi_sr_harq_pdu.ue_information.ue_information_rel8.rnti == rnti)) + { + is_my_rnti = true; + break; + } + else + { + LOG_D(MAC, "UNKNOWN UL_CONFIG_REQ PDU_TYPE: %d or RNTI is not mine \n", pdu_type); } } + return is_my_rnti; +} + +int memcpy_ul_config_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_ul_config_request_t *req) +{ + if (!is_my_ul_config_req(req)) return 0; + + nfapi_ul_config_request_t *p = malloc(sizeof(nfapi_ul_config_request_t)); + + p->sfn_sf = req->sfn_sf; + p->vendor_extension = req->vendor_extension; + + p->ul_config_request_body.number_of_pdus = req->ul_config_request_body.number_of_pdus; + p->ul_config_request_body.rach_prach_frequency_resources = req->ul_config_request_body.rach_prach_frequency_resources; + p->ul_config_request_body.srs_present = req->ul_config_request_body.srs_present; + + p->ul_config_request_body.tl.tag = req->ul_config_request_body.tl.tag; + p->ul_config_request_body.tl.length = req->ul_config_request_body.tl.length; + + p->ul_config_request_body.ul_config_pdu_list = + calloc(req->ul_config_request_body.number_of_pdus, + sizeof(nfapi_ul_config_request_pdu_t)); + for (int i = 0; i < p->ul_config_request_body.number_of_pdus; i++) + { + p->ul_config_request_body.ul_config_pdu_list[i] = + req->ul_config_request_body.ul_config_pdu_list[i]; + } + + if (!put_queue(&ul_config_req_queue, p)) + { + free(p); + } + return 0; } -int memcpy_hi_dci0_req (L1_rxtx_proc_t *proc, - nfapi_pnf_p7_config_t* pnf_p7, +void nfapi_free_tx_req_pdu_list(nfapi_tx_req_pdu_list_t *list) +{ + // free all the p[i].segments[j].segment_data memory + int num_pdus = list->num_pdus; + nfapi_tx_request_pdu_t *pdus = list->pdus; + for (int i = 0; i < num_pdus; i++) { + int num_segments = pdus[i].num_segments; + for (int j = 0; j < num_segments; j++) { + free(pdus[i].segments[j].segment_data); + pdus[i].segments[j].segment_data = NULL; + } + } + free(list); +} + +static bool is_my_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) +{ + bool is_my_rnti = false; + const rnti_t rnti = UE_mac_inst[0].crnti; // This is 0 representing the num_ues is 1 + nfapi_hi_dci0_request_body_t *hi_dci0_body = &hi_dci0_req->hi_dci0_request_body; + for (int i = 0; i < hi_dci0_body->number_of_dci + hi_dci0_body->number_of_hi; i++) + { + nfapi_hi_dci0_request_pdu_t *hi_dci0 = &hi_dci0_body->hi_dci0_pdu_list[i]; + if (hi_dci0->pdu_type != NFAPI_HI_DCI0_DCI_PDU_TYPE || hi_dci0->dci_pdu.dci_pdu_rel8.cqi_csi_request) + { + continue; + } + if (hi_dci0->dci_pdu.dci_pdu_rel8.rnti == rnti) + { + is_my_rnti = true; + break; + } + } + + return is_my_rnti; +} + +int memcpy_hi_dci0_req (L1_rxtx_proc_t *proc, + nfapi_pnf_p7_config_t* pnf_p7, nfapi_hi_dci0_request_t* req) { - hi_dci0_req = (nfapi_hi_dci0_request_t *)malloc(sizeof(nfapi_hi_dci0_request_t)); + + if (!is_my_hi_dci0_req(req)) + { + LOG_I(MAC, "Filtering hi_dci0_req\n"); + return 0; + } + nfapi_hi_dci0_request_t *p = (nfapi_hi_dci0_request_t *)malloc(sizeof(nfapi_hi_dci0_request_t)); //if(req!=0){ - hi_dci0_req->sfn_sf = req->sfn_sf; - hi_dci0_req->vendor_extension = req->vendor_extension; + p->sfn_sf = req->sfn_sf; + p->vendor_extension = req->vendor_extension; - hi_dci0_req->hi_dci0_request_body.number_of_dci = req->hi_dci0_request_body.number_of_dci; - hi_dci0_req->hi_dci0_request_body.number_of_hi = req->hi_dci0_request_body.number_of_hi; - hi_dci0_req->hi_dci0_request_body.sfnsf = req->hi_dci0_request_body.sfnsf; + p->hi_dci0_request_body.number_of_dci = req->hi_dci0_request_body.number_of_dci; + p->hi_dci0_request_body.number_of_hi = req->hi_dci0_request_body.number_of_hi; + p->hi_dci0_request_body.sfnsf = req->hi_dci0_request_body.sfnsf; - // UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.tl = + // UE_mac_inst[Mod_id].p->hi_dci0_request_body.tl = // req->hi_dci0_request_body.tl; - hi_dci0_req->hi_dci0_request_body.tl.tag = req->hi_dci0_request_body.tl.tag; - hi_dci0_req->hi_dci0_request_body.tl.length = req->hi_dci0_request_body.tl.length; + p->hi_dci0_request_body.tl.tag = req->hi_dci0_request_body.tl.tag; + p->hi_dci0_request_body.tl.length = req->hi_dci0_request_body.tl.length; - int total_pdus = hi_dci0_req->hi_dci0_request_body.number_of_dci - + hi_dci0_req->hi_dci0_request_body.number_of_hi; + int total_pdus = p->hi_dci0_request_body.number_of_dci + + p->hi_dci0_request_body.number_of_hi; - hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list = + p->hi_dci0_request_body.hi_dci0_pdu_list = calloc(total_pdus, sizeof(nfapi_hi_dci0_request_pdu_t)); for (int i = 0; i < total_pdus; i++) { - hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list[i] = req->hi_dci0_request_body.hi_dci0_pdu_list[i]; + p->hi_dci0_request_body.hi_dci0_pdu_list[i] = req->hi_dci0_request_body.hi_dci0_pdu_list[i]; // LOG_I(MAC, "Original hi_dci0 req. type:%d, Copy type: %d // \n",req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type, - // UE_mac_inst[Mod_id].hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type); + // UE_mac_inst[Mod_id].p->hi_dci0_request_body.hi_dci0_pdu_list[i].pdu_type); } + + if (!put_queue(&hi_dci0_req_queue, p)) { + free(p); + } + LOG_I(MAC, "DCI0 QUEUE: %zu\n", hi_dci0_req_queue.num_items); return 0; } @@ -1039,6 +1180,9 @@ void UE_config_stub_pnf(void) { *(L1_ParamList.paramarray[j][L1_REMOTE_N_PORTD_IDX].iptr); stub_eth_params.transp_preference = ETH_UDP_MODE; + if (NFAPI_MODE!=NFAPI_UE_STUB_PNF) + continue; + sf_ahead = 2; // Cannot cope with 4 subframes betweem RX and TX - set it to 2 // configure_nfapi_pnf(UE_mac_inst[0].eth_params_n.remote_addr, // UE_mac_inst[0].eth_params_n.remote_portc, @@ -1055,79 +1199,934 @@ void UE_config_stub_pnf(void) { } } +void ue_init_standalone_socket(int tx_port, int rx_port) +{ + { + struct sockaddr_in server_address; + int addr_len = sizeof(server_address); + memset(&server_address, 0, addr_len); + server_address.sin_family = AF_INET; + server_address.sin_port = htons(tx_port); + + int sd = socket(server_address.sin_family, SOCK_DGRAM, 0); + if (sd < 0) + { + LOG_E(MAC, "Socket creation error standalone PNF\n"); + return; + } + + if (inet_pton(server_address.sin_family, stub_eth_params.remote_addr, &server_address.sin_addr) <= 0) + { + LOG_E(MAC, "Invalid standalone PNF Address\n"); + close(sd); + return; + } + + // Using connect to use send() instead of sendto() + if (connect(sd, (struct sockaddr *)&server_address, addr_len) < 0) + { + LOG_E(MAC, "Connection to standalone PNF failed: %s\n", strerror(errno)); + close(sd); + return; + } + assert(ue_tx_sock_descriptor == -1); + ue_tx_sock_descriptor = sd; + } + + { + struct sockaddr_in server_address; + int addr_len = sizeof(server_address); + memset(&server_address, 0, addr_len); + server_address.sin_family = AF_INET; + server_address.sin_addr.s_addr = INADDR_ANY; + server_address.sin_port = htons(rx_port); + + int sd = socket(server_address.sin_family, SOCK_DGRAM, 0); + if (sd < 0) + { + LOG_E(MAC, "Socket creation error standalone PNF\n"); + return; + } + + if (bind(sd, (struct sockaddr *)&server_address, addr_len) < 0) + { + LOG_E(MAC, "Connection to standalone PNF failed: %s\n", strerror(errno)); + close(sd); + return; + } + assert(ue_rx_sock_descriptor == -1); + ue_rx_sock_descriptor = sd; + } +} + +void *ue_standalone_pnf_task(void *context) +{ + struct sockaddr_in server_address; + socklen_t addr_len = sizeof(server_address); + char buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE]; + int sd = ue_rx_sock_descriptor; + assert(sd > 0); + + nfapi_tx_request_t tx_req; + nfapi_dl_config_request_t dl_config_req; + bool tx_req_valid = false; + bool dl_config_req_valid = false; + while (true) + { + ssize_t len = recvfrom(sd, buffer, sizeof(buffer), MSG_TRUNC, (struct sockaddr *)&server_address, &addr_len); + if (len == -1) + { + LOG_E(MAC, "reading from standalone pnf sctp socket failed \n"); + continue; + } + if (len > sizeof(buffer)) + { + LOG_E(MAC, "%s(%d). Message truncated. %zd\n", __FUNCTION__, __LINE__, len); + continue; + } + + /* First we'll check for possible messages from the proxy. We do this by checking + the length of the message. This works because sizeof(uint16_t) < sizeof(nfapi_p7_message_header_t) + and sizeof(phy_channel_params_t) < sizeof(nfapi_p7_message_header_t) and + sizeof(uint16_t) != sizeof(phy_channel_params_t). */ + if (len == sizeof(uint16_t)) + { + uint16_t sfn_sf = 0; + memcpy((void *)&sfn_sf, buffer, sizeof(sfn_sf)); + current_sfn_sf = sfn_sf; + + if (sem_post(&sfn_semaphore) != 0) + { + LOG_E(MAC, "sem_post() error\n"); + abort(); + } + } + else if (len == sizeof(phy_channel_params_t)) + { + phy_channel_params_t ch_info; + memcpy(&ch_info, buffer, sizeof(phy_channel_params_t)); + current_sfn_sf = ch_info.sfn_sf; + if (sem_post(&sfn_semaphore) != 0) + { + LOG_E(MAC, "sem_post() error\n"); + abort(); + } + uint16_t sf = ch_info.sfn_sf & 15; + assert(sf < 10); + + sf_rnti_mcs[sf].sinr = ch_info.sinr; + LOG_D(MAC, "Received_SINR = %f\n",ch_info.sinr); + } + else + { + nfapi_p7_message_header_t header; + if (nfapi_p7_message_header_unpack((void *)buffer, len, &header, sizeof(header), NULL) < 0) + { + LOG_E(MAC, "Header unpack failed for standalone pnf\n"); + continue; + } + switch (header.message_id) + { + case NFAPI_DL_CONFIG_REQUEST: + { + if (dl_config_req_valid) + { + LOG_W(MAC, "Received consecutive dl_config_reqs. Previous dl_config_req frame: %u, subframe: %u\n", + dl_config_req.sfn_sf >> 4, dl_config_req.sfn_sf & 15); + } + if (nfapi_p7_message_unpack((void *)buffer, len, &dl_config_req, + sizeof(dl_config_req), NULL) < 0) + { + LOG_E(MAC, "Message dl_config_req failed to unpack\n"); + break; + } + + LOG_I(MAC, "dl_config_req Frame: %u Subframe: %u\n", dl_config_req.sfn_sf >> 4, + dl_config_req.sfn_sf & 15); + + dl_config_req_valid = true; + + save_dci_pdu_for_crnti(&dl_config_req); + + if (tx_req_valid) + { + if (dl_config_req.sfn_sf != tx_req.sfn_sf) + { + LOG_W(MAC, "sfnsf mismatch. dl_config_req Frame: %u Subframe: %u, Discarding tx_req Frame: %u Subframe: %u\n", + dl_config_req.sfn_sf >> 4, dl_config_req.sfn_sf & 15, + tx_req.sfn_sf >> 4, tx_req.sfn_sf & 15); + tx_req_valid = false; + break; + } + enqueue_dl_config_req_tx_req(&dl_config_req, &tx_req); + dl_config_req_valid = false; + tx_req_valid = false; + } + + break; + } + case NFAPI_TX_REQUEST: + { + if (tx_req_valid) + { + LOG_W(MAC, "Received consecutive tx_reqs. Previous tx_req frame: %u, subframe: %u\n", + tx_req.sfn_sf >> 4, tx_req.sfn_sf & 15); + } + if (nfapi_p7_message_unpack((void *)buffer, len, &tx_req, + sizeof(tx_req), NULL) < 0) + { + LOG_E(MAC, "Message tx_req failed to unpack\n"); + break; + } + + LOG_I(MAC, "tx_req Frame: %u Subframe: %u\n", tx_req.sfn_sf >> 4, + tx_req.sfn_sf & 15); + + tx_req_valid = true; + if (dl_config_req_valid) + { + if (dl_config_req.sfn_sf != tx_req.sfn_sf) + { + LOG_W(MAC, "sfnsf mismatch. Discarding dl_config_req Frame: %u Subframe: %u, tx_req Frame: %u Subframe: %u\n", + dl_config_req.sfn_sf >> 4, dl_config_req.sfn_sf & 15, + tx_req.sfn_sf >> 4, tx_req.sfn_sf & 15); + dl_config_req_valid = false; + break; + } + enqueue_dl_config_req_tx_req(&dl_config_req, &tx_req); + dl_config_req_valid = false; + tx_req_valid = false; + } + + break; + } + case NFAPI_HI_DCI0_REQUEST: + { + nfapi_hi_dci0_request_t hi_dci0_req; + // lock this hi_dci0_req + if (nfapi_p7_message_unpack((void *)buffer, len, &hi_dci0_req, + sizeof(hi_dci0_req), NULL) < 0) + { + LOG_E(MAC, "Message hi_dci0_req failed to unpack\n"); + break; + } + + // check to see if hi_dci0_req is null + memcpy_hi_dci0_req(NULL, NULL, &hi_dci0_req); + + break; + } + case NFAPI_UL_CONFIG_REQUEST: + { + nfapi_ul_config_request_t ul_config_req; + // lock this ul_config_req + if (nfapi_p7_message_unpack((void *)buffer, len, &ul_config_req, + sizeof(ul_config_req), NULL) < 0) + { + LOG_E(MAC, "Message ul_config_req failed to unpack\n"); + break; + } + + // check to see if ul_config_req is null + memcpy_ul_config_req(NULL, NULL, &ul_config_req); + + break; + } + default: + LOG_E(MAC, "Case Statement has no corresponding nfapi message\n"); + break; + } + } + } +} + +static void save_dci_pdu_for_crnti(nfapi_dl_config_request_t *dl_config_req) +{ + int count_sent = 0; + int number_of_dci = dl_config_req->dl_config_request_body.number_dci; + int number_of_pdu = dl_config_req->dl_config_request_body.number_pdu; + if (number_of_pdu <= 0) + { + LOG_E(MAC, "%s: dl_config_req pdu size <= 0\n", __FUNCTION__); + abort(); + } + if (number_of_dci > 0) + { + for (int n = 0; n < number_of_pdu; n++) + { + const nfapi_dl_config_request_pdu_t *current_pdu_list = &dl_config_req->dl_config_request_body.dl_config_pdu_list[n]; + int rnti_type = current_pdu_list->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type; + if (current_pdu_list->pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE && rnti_type == 1 && count_sent < number_of_dci) + { + read_channel_param(current_pdu_list, (dl_config_req->sfn_sf & 15), count_sent); + count_sent++; + } + } + } +} + +void *memcpy_dl_config_req_standalone(nfapi_dl_config_request_t *dl_config_req) +{ + nfapi_dl_config_request_t *p = malloc(sizeof(nfapi_dl_config_request_t)); + + p->sfn_sf = dl_config_req->sfn_sf; + + p->vendor_extension = dl_config_req->vendor_extension; + + p->dl_config_request_body.number_dci = dl_config_req->dl_config_request_body.number_dci; + p->dl_config_request_body.number_pdcch_ofdm_symbols = dl_config_req->dl_config_request_body.number_pdcch_ofdm_symbols; + p->dl_config_request_body.number_pdsch_rnti = dl_config_req->dl_config_request_body.number_pdsch_rnti; + p->dl_config_request_body.number_pdu = dl_config_req->dl_config_request_body.number_pdu; + + p->dl_config_request_body.tl.tag = dl_config_req->dl_config_request_body.tl.tag; + p->dl_config_request_body.tl.length = dl_config_req->dl_config_request_body.tl.length; + + p->dl_config_request_body.dl_config_pdu_list = + calloc(dl_config_req->dl_config_request_body.number_pdu, + sizeof(nfapi_dl_config_request_pdu_t)); + for (int i = 0; i < p->dl_config_request_body.number_pdu; i++) { + p->dl_config_request_body.dl_config_pdu_list[i] = + dl_config_req->dl_config_request_body.dl_config_pdu_list[i]; + } + return p; +} + +void *memcpy_tx_req_standalone(nfapi_tx_request_t *tx_req) +{ + int num_pdus = tx_req->tx_request_body.number_of_pdus; + + nfapi_tx_req_pdu_list_t *list = calloc(1, sizeof(nfapi_tx_req_pdu_list_t) + num_pdus * sizeof(nfapi_tx_request_pdu_t)); + list->num_pdus = num_pdus; + nfapi_tx_request_pdu_t *p = list->pdus; + + for (int i = 0; i < num_pdus; i++) + { + p[i].num_segments = tx_req->tx_request_body.tx_pdu_list[i].num_segments; + p[i].pdu_index = tx_req->tx_request_body.tx_pdu_list[i].pdu_index; + p[i].pdu_length = tx_req->tx_request_body.tx_pdu_list[i].pdu_length; + for (int j = 0; j < tx_req->tx_request_body.tx_pdu_list[i].num_segments; j++) + { + p[i].segments[j].segment_length = tx_req->tx_request_body.tx_pdu_list[i].segments[j].segment_length; + if (p[i].segments[j].segment_length > 0) + { + p[i].segments[j].segment_data = calloc( + p[i].segments[j].segment_length, sizeof(uint8_t)); + memcpy(p[i].segments[j].segment_data, + tx_req->tx_request_body.tx_pdu_list[i].segments[j].segment_data, + p[i].segments[j].segment_length); + } + } + } + return list; +} + +static bool is_my_dl_config_req(const nfapi_dl_config_request_t *req) +{ + + const rnti_t my_rnti = UE_mac_inst[0].crnti; + int num_pdus = req->dl_config_request_body.number_pdu; + // look through list of pdus for rnti type 1 with my_rnti (normal dlsch case) + for (int i = 0; i < num_pdus; i++) + { + nfapi_dl_config_request_pdu_t *pdu = &req->dl_config_request_body.dl_config_pdu_list[i]; + const int pdu_type = pdu->pdu_type; + if (pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) + { + const rnti_t dci_rnti = pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti; + const int rnti_type = pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type; + if (rnti_type == 1 && dci_rnti == my_rnti) + { + return true; + } + } + else if(pdu_type != NFAPI_DL_CONFIG_DLSCH_PDU_TYPE) + { + return true; // Because these two pdu_types are coupled and we have to accept all other pdu_types + } + } + + // Look for broadcasted rnti types + for (int i = 0; i < num_pdus; i++) + { + nfapi_dl_config_request_pdu_t *pdu = &req->dl_config_request_body.dl_config_pdu_list[i]; + const int pdu_type = pdu->pdu_type; + if (pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) + { + const int rnti_type = pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type; + if (rnti_type != 1) + { + return true; + } + } + } + + + return false; +} + +void enqueue_dl_config_req_tx_req(nfapi_dl_config_request_t *dl_config_req, nfapi_tx_request_t *tx_req) +{ + if (!is_my_dl_config_req(dl_config_req)) + { + LOG_I(MAC, "Filtering dl_config_req and tx_req\n"); + return; + } + + nfapi_dl_config_request_t *dl_config_req_temp = memcpy_dl_config_req_standalone(dl_config_req); + nfapi_tx_req_pdu_list_t *tx_req_temp = memcpy_tx_req_standalone(tx_req); + LOG_I(MAC, "This is the num_pdus for tx_req: %d\n", tx_req_temp->num_pdus); + LOG_I(MAC, "This is the num_pdus for dl_config_req and the sfn_sf: %d, %d:%d\n", dl_config_req_temp->dl_config_request_body.number_pdu, + NFAPI_SFNSF2SFN(dl_config_req_temp->sfn_sf), NFAPI_SFNSF2SF(dl_config_req_temp->sfn_sf)); + + nfapi_dl_config_req_tx_req_t *req = malloc(sizeof(nfapi_dl_config_req_tx_req_t)); + req->dl_config_req = dl_config_req_temp; + req->tx_req_pdu_list = tx_req_temp; + + if (!put_queue(&dl_config_req_tx_req_queue, req)) + { + free(req->dl_config_req); + nfapi_free_tx_req_pdu_list(req->tx_req_pdu_list); + free(req); + } +} + + +__attribute__((unused)) +static void print_rx_ind(nfapi_rx_indication_t *p) +{ + printf("Printing RX_IND fields\n"); + printf("header.message_id: %u\n", p->header.message_id); + printf("header.phy_id: %u\n", p->header.phy_id); + printf("header.message_id: %u\n", p->header.message_id); + printf("header.m_segment_sequence: %u\n", p->header.m_segment_sequence); + printf("header.checksum: %u\n", p->header.checksum); + printf("header.transmit_timestamp: %u\n", p->header.transmit_timestamp); + printf("sfn_sf: %u\n", p->sfn_sf); + printf("rx_indication_body.tl.tag: 0x%x\n", p->rx_indication_body.tl.tag); + printf("rx_indication_body.tl.length: %u\n", p->rx_indication_body.tl.length); + printf("rx_indication_body.number_of_pdus: %u\n", p->rx_indication_body.number_of_pdus); + + assert(p->rx_indication_body.number_of_pdus <= NFAPI_RX_IND_MAX_PDU); + nfapi_rx_indication_pdu_t *pdu = p->rx_indication_body.rx_pdu_list; + for (int i = 0; i < p->rx_indication_body.number_of_pdus; i++) + { + printf("pdu %d nfapi_rx_ue_information.tl.tag: 0x%x\n", i, pdu->rx_ue_information.tl.tag); + printf("pdu %d nfapi_rx_ue_information.tl.length: %u\n", i, pdu->rx_ue_information.tl.length); + printf("pdu %d nfapi_rx_ue_information.handle: %u\n", i, pdu->rx_ue_information.handle); + printf("pdu %d nfapi_rx_ue_information.rnti: %u\n", i, pdu->rx_ue_information.rnti); + printf("pdu %d nfapi_rx_indication_rel8.tl.tag: 0x%x\n", i, pdu->rx_indication_rel8.tl.tag); + printf("pdu %d nfapi_rx_indication_rel8.tl.length: %u\n", i, pdu->rx_indication_rel8.tl.length); + printf("pdu %d nfapi_rx_indication_rel8.length: %u\n", i, pdu->rx_indication_rel8.length); + printf("pdu %d nfapi_rx_indication_rel8.offset: %u\n", i, pdu->rx_indication_rel8.offset); + printf("pdu %d nfapi_rx_indication_rel8.ul_cqi: %u\n", i, pdu->rx_indication_rel8.ul_cqi); + printf("pdu %d nfapi_rx_indication_rel8.timing_advance: %u\n", i, pdu->rx_indication_rel8.timing_advance); + printf("pdu %d nfapi_rx_indication_rel9.tl.tag: 0x%x\n", i, pdu->rx_indication_rel9.tl.tag); + printf("pdu %d nfapi_rx_indication_rel9.tl.length: %u\n", i, pdu->rx_indication_rel9.tl.length); + printf("pdu %d nfapi_rx_indication_rel9.timing_advance_r9: %u\n", i, pdu->rx_indication_rel9.timing_advance_r9); + } + + fflush(stdout); +} + + void send_standalone_msg(UL_IND_t *UL, nfapi_message_id_e msg_type) + { + int encoded_size = -1; + char buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE]; + + switch (msg_type) + { + case NFAPI_RACH_INDICATION: + encoded_size = nfapi_p7_message_pack(&UL->rach_ind, buffer, sizeof(buffer), NULL); + LOG_A(MAC, "RACH_IND sent to Proxy, Size: %d Frame %d Subframe %d\n", encoded_size, + NFAPI_SFNSF2SFN(UL->rach_ind.sfn_sf), NFAPI_SFNSF2SF(UL->rach_ind.sfn_sf)); + break; + case NFAPI_CRC_INDICATION: + encoded_size = nfapi_p7_message_pack(&UL->crc_ind, buffer, sizeof(buffer), NULL); + LOG_I(MAC, "CRC_IND sent to Proxy, Size: %d Frame %d Subframe %d num_crcs: %u\n", encoded_size, + NFAPI_SFNSF2SFN(UL->crc_ind.sfn_sf), NFAPI_SFNSF2SF(UL->crc_ind.sfn_sf), + UL->crc_ind.crc_indication_body.number_of_crcs); + break; + case NFAPI_RX_ULSCH_INDICATION: + encoded_size = nfapi_p7_message_pack(&UL->rx_ind, buffer, sizeof(buffer), NULL); + LOG_I(MAC, "RX_IND sent to Proxy, Size: %d Frame %d Subframe %d rx_ind.tl.length: %u num_pdus: %u\n", + encoded_size, NFAPI_SFNSF2SFN(UL->rx_ind.sfn_sf), NFAPI_SFNSF2SF(UL->rx_ind.sfn_sf), + UL->rx_ind.rx_indication_body.tl.length, UL->rx_ind.rx_indication_body.number_of_pdus); + break; + case NFAPI_RX_CQI_INDICATION: + encoded_size = nfapi_p7_message_pack(&UL->cqi_ind, buffer, sizeof(buffer), NULL); + LOG_I(MAC, "CQI_IND sent to Proxy, Size: %d num_cqis: %u\n", encoded_size, + UL->cqi_ind.cqi_indication_body.number_of_cqis); + break; + case NFAPI_HARQ_INDICATION: + encoded_size = nfapi_p7_message_pack(&UL->harq_ind, buffer, sizeof(buffer), NULL); + LOG_I(MAC, "HARQ_IND sent to Proxy, Size: %d Frame %d Subframe %d\n", encoded_size, + NFAPI_SFNSF2SFN(UL->harq_ind.sfn_sf), NFAPI_SFNSF2SF(UL->harq_ind.sfn_sf)); + break; + case NFAPI_RX_SR_INDICATION: + encoded_size = nfapi_p7_message_pack(&UL->sr_ind, buffer, sizeof(buffer), NULL); + LOG_I(MAC, "SR_IND sent to Proxy, Size: %d\n", encoded_size); + break; + default: + LOG_I(MAC, "%s Unknown Message msg_type :: %u\n", __func__, msg_type); + return; + } + if (encoded_size < 0) + { + LOG_E(MAC, "standalone pack failed\n"); + return; + } + if (send(ue_tx_sock_descriptor, buffer, encoded_size, 0) < 0) + { + LOG_E(MAC, "Send Proxy UE failed\n"); + return; + } + } + + void send_standalone_dummy() + { + static const uint16_t dummy[] = {0, 0}; + if (send(ue_tx_sock_descriptor, dummy, sizeof(dummy), 0) < 0) + { + LOG_E(MAC, "send dummy to OAI UE failed: %s\n", strerror(errno)); + return; + } + } + +const char *dl_pdu_type_to_string(uint8_t pdu_type) +{ + switch (pdu_type) + { + case NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE: + return "DCI_DL_PDU_TYPE"; + case NFAPI_DL_CONFIG_BCH_PDU_TYPE: + return "BCH_PDU_TYPE"; + case NFAPI_DL_CONFIG_MCH_PDU_TYPE: + return "MCH_PDU_TYPE"; + case NFAPI_DL_CONFIG_DLSCH_PDU_TYPE: + return "DLSCH_PDU_TYPE"; + case NFAPI_DL_CONFIG_PCH_PDU_TYPE: + return "PCH_PDU_TYPE"; + case NFAPI_DL_CONFIG_PRS_PDU_TYPE: + return "PRS_PDU_TYPE"; + case NFAPI_DL_CONFIG_CSI_RS_PDU_TYPE: + return "CSI_RS_PDU_TYPE"; + case NFAPI_DL_CONFIG_EPDCCH_DL_PDU_TYPE: + return "EPDCCH_DL_PDU_TYPE"; + case NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE: + return "MPDCCH_PDU_TYPE"; + case NFAPI_DL_CONFIG_NBCH_PDU_TYPE: + return "NBCH_PDU_TYPE"; + case NFAPI_DL_CONFIG_NPDCCH_PDU_TYPE: + return "NPDCCH_PDU_TYPE"; + case NFAPI_DL_CONFIG_NDLSCH_PDU_TYPE: + return "NDLSCH_PDU_TYPE"; + default: + LOG_E(MAC, "%s No corresponding PDU for type: %u\n", __func__, pdu_type); + return "UNKNOWN"; + } +} + +const char *ul_pdu_type_to_string(uint8_t pdu_type) +{ + switch (pdu_type) + { + case NFAPI_UL_CONFIG_ULSCH_PDU_TYPE: + return "UL_CONFIG_ULSCH_PDU_TYPE"; + case NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE: + return "UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE"; + case NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE: + return "UL_CONFIG_ULSCH_HARQ_PDU_TYPE"; + case NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE: + return "UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE"; + case NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE: + return "UL_CONFIG_UCI_CQI_PDU_TYPE"; + case NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE: + return "UCI_SR_PDU_TYPE"; + case NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE: + return "UCI_HARQ_PDU_TYPE"; + case NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE: + return "UCI_SR_HARQ_PDU_TYPE"; + case NFAPI_UL_CONFIG_UCI_CQI_HARQ_PDU_TYPE: + return "UCI_CQI_HARQ_PDU_TYPE"; + case NFAPI_UL_CONFIG_UCI_CQI_SR_PDU_TYPE: + return "UCI_CQI_SR_PDU_TYPE"; + case NFAPI_UL_CONFIG_UCI_CQI_SR_HARQ_PDU_TYPE: + return "UCI_CQI_SR_HARQ_PDU_TYPE"; + case NFAPI_UL_CONFIG_SRS_PDU_TYPE: + return "SRS_PDU_TYPE"; + case NFAPI_UL_CONFIG_HARQ_BUFFER_PDU_TYPE: + return "HARQ_BUFFER_PDU_TYPE"; + case NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE: + return "PDU_TYPE"; + case NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE: + return "ULSCH_UCI_HARQ_PDU_TYPE"; + case NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE: + return "ULSCH_CSI_UCI_HARQ_PDU_TYPE"; + case NFAPI_UL_CONFIG_NULSCH_PDU_TYPE: + return "NULSCH_PDU_TYPE"; + case NFAPI_UL_CONFIG_NRACH_PDU_TYPE: + return "NRACH_PDU_TYPE"; + default: + LOG_E(MAC, "%s No corresponding PDU for type: %u\n", __func__, pdu_type); + return "UNKNOWN"; + } +} + +char *nfapi_dl_config_req_to_string(nfapi_dl_config_request_t *req) +{ + const size_t max_result = 1024; + uint16_t num_pdus = req->dl_config_request_body.number_pdu; + int subframe = req->sfn_sf & 15; + int frame = req->sfn_sf >> 4; + char *result = malloc(max_result); + snprintf(result, max_result, "num_pdus=%u Frame=%d Subframe=%d", + num_pdus, frame, subframe); + for (size_t i = 0; i < num_pdus; ++i) + { + int len = strlen(result); + if (len >= max_result - 1) + { + break; + } + snprintf(result + len, max_result - len, " pdu_type=%s", + dl_pdu_type_to_string(req->dl_config_request_body.dl_config_pdu_list[i].pdu_type)); + } + return result; +} + +char *nfapi_ul_config_req_to_string(nfapi_ul_config_request_t *req) +{ + const size_t max_result = 1024; + uint16_t num_pdus = req->ul_config_request_body.number_of_pdus; + int subframe = req->sfn_sf & 15; + int frame = req->sfn_sf >> 4; + char *result = malloc(max_result); + snprintf(result, max_result, "num_pdus=%u Frame=%d Subframe=%d", + num_pdus, frame, subframe); + for (size_t i = 0; i < num_pdus; ++i) + { + int len = strlen(result); + if (len >= max_result - 1) + { + break; + } + snprintf(result + len, max_result - len, " pdu_type=%s", + ul_pdu_type_to_string(req->ul_config_request_body.ul_config_pdu_list[i].pdu_type)); + } + return result; +} + /* Dummy functions*/ -void handle_nfapi_hi_dci0_dci_pdu( - PHY_VARS_eNB *eNB, - int frame, - int subframe, - L1_rxtx_proc_t *proc, - nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu) { + void handle_nfapi_hi_dci0_dci_pdu( + PHY_VARS_eNB * eNB, + int frame, + int subframe, + L1_rxtx_proc_t *proc, + nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu) + { + } + + void handle_nfapi_hi_dci0_hi_pdu( + PHY_VARS_eNB * eNB, + int frame, + int subframe, + L1_rxtx_proc_t *proc, + nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu) + { + } + + void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB * eNB, + int frame, + int subframe, + L1_rxtx_proc_t *proc, + nfapi_dl_config_request_pdu_t *dl_config_pdu) + { + } + + void handle_nfapi_bch_pdu(PHY_VARS_eNB * eNB, + L1_rxtx_proc_t * proc, + nfapi_dl_config_request_pdu_t * dl_config_pdu, + uint8_t * sdu) + { + } + + void handle_nfapi_dlsch_pdu(PHY_VARS_eNB * eNB, + int frame, + int subframe, + L1_rxtx_proc_t *proc, + nfapi_dl_config_request_pdu_t *dl_config_pdu, + uint8_t codeword_index, + uint8_t *sdu) + { + } + + void handle_nfapi_ul_pdu(PHY_VARS_eNB * eNB, + L1_rxtx_proc_t * proc, + nfapi_ul_config_request_pdu_t * ul_config_pdu, + uint16_t frame, + uint8_t subframe, + uint8_t srs_present) + { + } + void handle_nfapi_mch_pdu(PHY_VARS_eNB * eNB, + L1_rxtx_proc_t * proc, + nfapi_dl_config_request_pdu_t * dl_config_pdu, + uint8_t * sdu) + { + } + + void phy_config_request(PHY_Config_t * phy_config) + { + } + + void phy_config_update_sib2_request(PHY_Config_t * phy_config) + { + } + + void phy_config_update_sib13_request(PHY_Config_t * phy_config) + { + } + + uint32_t from_earfcn(int eutra_bandP, uint32_t dl_earfcn) + { + return (0); + } + + int32_t get_uldl_offset(int eutra_bandP) + { + return (0); + } + + int l1_north_init_eNB(void) + { + return 0; + } + + void init_eNB_afterRU(void) + { + } + +static int get_mcs_from_sinr(float sinr) +{ + if (sinr < (bler_data[0].bler_table[0][0])) + { + LOG_I(MAC, "The SINR was found is smaller than first MCS table\n"); + return 0; + } + + if (sinr > (bler_data[NUM_MCS-1].bler_table[bler_data[NUM_MCS-1].length - 1][0])) + { + LOG_I(MAC, "The SINR was found is larger than last MCS table\n"); + return NUM_MCS-1; + } + + for (int n = NUM_MCS-1; n >= 0; n--) + { + CHECK_INDEX(bler_data, n); + float largest_sinr = (bler_data[n].bler_table[bler_data[n].length - 1][0]); + float smallest_sinr = (bler_data[n].bler_table[0][0]); + if (sinr < largest_sinr && sinr > smallest_sinr) + { + LOG_I(MAC, "The SINR was found in MCS %d table\n", n); + return n; + } + } + LOG_E(MAC, "Unable to get an MCS value.\n"); + abort(); } -void handle_nfapi_hi_dci0_hi_pdu( - PHY_VARS_eNB *eNB, - int frame, - int subframe, - L1_rxtx_proc_t *proc, - nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu) { +static int get_cqi_from_mcs(void) +{ + static const int mcs_to_cqi[] = {0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15}; + assert(NUM_ELEMENTS(mcs_to_cqi) == NUM_MCS); + int sf = 0; + while(sf < NUM_NFAPI_SUBFRAME) + { + if (sf_rnti_mcs[sf].latest) + { + int pdu_size = sf_rnti_mcs[sf].pdu_size; + if (pdu_size <= 0) + { + LOG_E(MAC, "%s: sf_rnti_mcs[%d].pdu_size = 0\n", __FUNCTION__, sf); + abort(); + } + + CHECK_INDEX(sf_rnti_mcs[sf].mcs, pdu_size); + int mcs = get_mcs_from_sinr(sf_rnti_mcs[sf].sinr); + CHECK_INDEX(mcs_to_cqi, mcs); + int cqi = mcs_to_cqi[mcs]; + LOG_I(MAC, "SINR: %f -> MCS: %d -> CQI: %d\n", sf_rnti_mcs[sf].sinr, mcs, cqi); + return cqi; + } + sf++; + } + LOG_E(MAC, "Unable to get CQI value because no MCS found\n"); + abort(); } -void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB, - int frame, - int subframe, - L1_rxtx_proc_t *proc, - nfapi_dl_config_request_pdu_t *dl_config_pdu) { +static void read_channel_param(const nfapi_dl_config_request_pdu_t * pdu, int sf, int index) +{ + if (pdu == NULL) + { + LOG_E(MAC,"PDU NULL\n"); + abort(); + } + + /* This function is executed for every dci pdu type in a dl_config_req. We save + the assocaited MCS and RNTI value for each. The 'index' passed in is a count of + how many times we have called this function for a particular dl_config_req. It + allows us to save MCS/RNTI data in correct indicies when multiple dci's are received.*/ + for (int i = 0; i < NUM_NFAPI_SUBFRAME; i++) + { + if (i == sf) + { + CHECK_INDEX(sf_rnti_mcs[sf].rnti, index); + CHECK_INDEX(sf_rnti_mcs[sf].mcs, index); + CHECK_INDEX(sf_rnti_mcs[sf].drop_flag, index); + sf_rnti_mcs[sf].rnti[index] = pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti; + sf_rnti_mcs[sf].mcs[index] = pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1; + sf_rnti_mcs[sf].drop_flag[index] = false; + sf_rnti_mcs[sf].pdu_size = index+1; //index starts at 0 so we incrament to get num of pdus + sf_rnti_mcs[sf].latest = true; + LOG_I(MAC, "Adding MCS %d and RNTI %x for sf_rnti_mcs[%d]\n", sf_rnti_mcs[sf].mcs[index], sf_rnti_mcs[sf].rnti[index], sf); + } + else + { + sf_rnti_mcs[i].latest = false; + } + } + return; } -void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB, - L1_rxtx_proc_t *proc, - nfapi_dl_config_request_pdu_t *dl_config_pdu, - uint8_t *sdu) { +static bool did_drop_transport_block(int sf, uint16_t rnti) +{ + int pdu_size = sf_rnti_mcs[sf].pdu_size; + if(pdu_size <= 0) + { + LOG_E(MAC, "Problem, the PDU size is <= 0. We dropped this packet\n"); + return true; + } + CHECK_INDEX(sf_rnti_mcs[sf].rnti, pdu_size); + CHECK_INDEX(sf_rnti_mcs[sf].drop_flag, pdu_size); + for (int n = 0; n < pdu_size; n++) + { + if (sf_rnti_mcs[sf].rnti[n] == rnti && sf_rnti_mcs[sf].drop_flag[n]) + { + return true; + } + } + return false; } -void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB, - int frame, - int subframe, - L1_rxtx_proc_t *proc, - nfapi_dl_config_request_pdu_t *dl_config_pdu, - uint8_t codeword_index, - uint8_t *sdu) { +static float get_bler_val(uint8_t mcs, int sinr) +{ + // 4th col = dropped packets, 5th col = total packets + float bler_val = 0.0; + CHECK_INDEX(bler_data, mcs); + if (sinr < (int)(bler_data[mcs].bler_table[0][0] * 10)) + { + LOG_I(MAC, "MCS %d table. SINR is smaller than lowest SINR, bler_val is set based on lowest SINR in table\n", mcs); + bler_val = bler_data[mcs].bler_table[0][4] / bler_data[mcs].bler_table[0][5]; + return bler_val; + } + if (sinr > (int)(bler_data[mcs].bler_table[bler_data[mcs].length - 1][0] * 10)) + { + LOG_I(MAC, "MCS %d table. SINR is greater than largest SINR. bler_val is set based on largest SINR in table\n", mcs); + bler_val = bler_data[mcs].bler_table[(bler_data[mcs].length - 1)][4] / bler_data[mcs].bler_table[(bler_data[mcs].length - 1)][5]; + return bler_val; + } + // Loop through bler table to find sinr_index + for (int i = 0; i < bler_data[mcs].length; i++) + { + int temp_sinr = (int)(bler_data[mcs].bler_table[i][0] * 10); + if (temp_sinr == sinr) + { + bler_val = bler_data[mcs].bler_table[i][4] / bler_data[mcs].bler_table[i][5]; + return bler_val; + } + // Linear interpolation when SINR is between indices + if (temp_sinr > sinr) + { + float bler_val1 = bler_data[mcs].bler_table[i - 1][4] / bler_data[mcs].bler_table[i - 1][5]; + float bler_val2 = bler_data[mcs].bler_table[i][4] / bler_data[mcs].bler_table[i][5]; + return ((bler_val1 + bler_val2) / 2); + } + } + LOG_E(MAC, "NO SINR INDEX FOUND!\n"); + abort(); + } -void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB, - L1_rxtx_proc_t *proc, - nfapi_ul_config_request_pdu_t *ul_config_pdu, - uint16_t frame, - uint8_t subframe, - uint8_t srs_present) { -} -void handle_nfapi_mch_pdu(PHY_VARS_eNB *eNB, - L1_rxtx_proc_t *proc, - nfapi_dl_config_request_pdu_t *dl_config_pdu, - uint8_t *sdu) { +static inline bool is_channel_modeling(void) +{ + /* TODO: For now we enable channel modeling based on the node_number. + Replace with a command line option to enable/disable channel modeling. + The LTE UE will crash when channel modeling is conducted for NSA + mode. It does not crash for LTE mode. We have not implemented channel + modeling for NSA mode yet. For now, we ensure only do do chanel modeling + in LTE mode. */ + return node_number == 0 && !get_softmodem_params()->nsa; } -void phy_config_request(PHY_Config_t *phy_config) { -} +static bool should_drop_transport_block(int sf, uint16_t rnti) +{ + if (!is_channel_modeling()) + { + return false; + } -void phy_config_update_sib2_request(PHY_Config_t *phy_config) { -} + /* We want to avoid dropping setup messages because this would be pathological. + This assumes were in standalone_pnf mode where + UE_rrc_inst[0] is module_id = 0 and Info[0] is eNB_index = 0. */ + UE_STATE_t state = UE_rrc_inst[0].Info[0].State; + if (state < RRC_CONNECTED) + { + LOG_I(MAC, "Not dropping because state: %d", state); + return false; + } -void phy_config_update_sib13_request(PHY_Config_t *phy_config) { -} + /* Get block error rate (bler_val) from table based on every saved + MCS and SINR to be used as the cutoff rate for dropping packets. + Generate random uniform vairable to compare against bler_val. */ + int pdu_size = sf_rnti_mcs[sf].pdu_size; + assert(sf < 10 && sf >= 0); + assert(pdu_size > 0); + CHECK_INDEX(sf_rnti_mcs[sf].rnti, pdu_size); + CHECK_INDEX(sf_rnti_mcs[sf].mcs, pdu_size); + CHECK_INDEX(sf_rnti_mcs[sf].drop_flag, pdu_size); + int n = 0; + uint8_t mcs = 99; + for (n = 0; n < pdu_size; n++) + { + if (sf_rnti_mcs[sf].rnti[n] == rnti) + { + mcs = sf_rnti_mcs[sf].mcs[n]; + } + if (mcs != 99) + { + /* Use MCS to get the bler value. Since there can be multiple MCS + values for a particular subframe, we verify that all PDUs are not + flagged for drop before returning. If even one is flagged for drop + we return immediately because we drop the entire packet. */ + float bler_val = get_bler_val(mcs, ((int)(sf_rnti_mcs[sf].sinr * 10))); + double drop_cutoff = ((double) rand() / (RAND_MAX)); + assert(drop_cutoff <= 1); + LOG_I(MAC, "SINR = %f, Bler_val = %f, MCS = %"PRIu8"\n", sf_rnti_mcs[sf].sinr, bler_val, sf_rnti_mcs[sf].mcs[n]); + if (drop_cutoff <= bler_val) + { + sf_rnti_mcs[sf].drop_flag[n] = true; + LOG_D(MAC, "We are dropping this packet. Bler_val = %f, MCS = %"PRIu8", sf = %d\n", bler_val, sf_rnti_mcs[sf].mcs[n], sf); + return sf_rnti_mcs[sf].drop_flag[n]; + } + } -uint32_t from_earfcn(int eutra_bandP, uint32_t dl_earfcn) { - return (0); -} + } -int32_t get_uldl_offset(int eutra_bandP) { - return (0); -} - -int l1_north_init_eNB(void) { - return 0; -} - -void init_eNB_afterRU(void) { + if (mcs == 99) + { + LOG_E(MAC, "NO MCS Found for rnti %x. sf_rnti_mcs[%d].mcs[%d] \n", rnti, sf, n); + abort(); + } + return false; } diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.h b/openair2/PHY_INTERFACE/phy_stub_UE.h index bdf8872371..ebaae6e667 100644 --- a/openair2/PHY_INTERFACE/phy_stub_UE.h +++ b/openair2/PHY_INTERFACE/phy_stub_UE.h @@ -13,16 +13,51 @@ #include "openair2/PHY_INTERFACE/IF_Module.h" #include "nfapi_interface.h" #include "nfapi_pnf_interface.h" +#include +#include +#include "nfapi/oai_integration/vendor_ext.h" //#include "openair1/PHY/LTE_TRANSPORT/defs.h" //#include "openair1/PHY/defs.h" //#include "openair1/PHY/LTE_TRANSPORT/defs.h" +#include "queue_t.h" +#define NUM_MCS 28 +#define NUM_SINR 100 +#define NUM_BLER_COL 13 + +// this mutex is used to set multiple UE's UL value in L2 FAPI simulator. +extern FILL_UL_INFO_MUTEX_t fill_ul_mutex; //below 2 difinitions move to phy_stub_UE.c to add initialization when difinition. extern UL_IND_t *UL_INFO; -extern nfapi_tx_request_pdu_t* tx_request_pdu_list; // New /// Pointers to config_request types. Used from nfapi callback functions. //below 3 difinitions move to phy_stub_UE.c to add initialization when difinition. + +//below 2 difinitions move to lte-ue.c to add initialization when difinition. +//int next_ra_frame; +//module_id_t next_Mod_id; + +typedef struct +{ + uint8_t sf; + uint16_t rnti[256]; + uint8_t mcs[256]; + float sinr; + uint16_t pdu_size; + bool drop_flag[256]; + bool latest; + +} sf_rnti_mcs_s; + +typedef struct +{ + uint16_t length; + float bler_table[NUM_SINR][NUM_BLER_COL]; +} bler_struct; + +extern bler_struct bler_data[NUM_MCS]; + + extern nfapi_dl_config_request_t* dl_config_req; extern nfapi_ul_config_request_t* ul_config_req; extern nfapi_hi_dci0_request_t* hi_dci0_req; @@ -52,16 +87,19 @@ void send_nfapi_UL_indications(UL_IND_t UL_INFO); //void fill_rx_indication_UE_MAC(module_id_t Mod_id,int frame,int subframe); -void fill_rx_indication_UE_MAC(module_id_t Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t *ulsch_buffer, uint16_t buflen, uint16_t rnti, int index); +void fill_rx_indication_UE_MAC(module_id_t Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t *ulsch_buffer, uint16_t buflen, uint16_t rnti, int index, + nfapi_ul_config_request_t *ul_config_req); // This function should be indicating directly to the eNB when there is a planned scheduling request at the MAC layer // of the UE. It should get called from ue_get_SR() -void fill_sr_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint16_t rnti); +void fill_sr_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint16_t rnti, + nfapi_ul_config_request_t *ul_config_req); // In our case the this function will be always indicating ACK to the MAC of the eNB (i.e. always assuming) // successful decoding. -void fill_crc_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t crc_flag, int index, uint16_t rnti); +void fill_crc_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t crc_flag, int index, uint16_t rnti, + nfapi_ul_config_request_t *ul_config_req); void fill_rach_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t ra_PreambleIndex, uint16_t ra_RNTI); @@ -70,9 +108,11 @@ void fill_rach_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL void fill_ulsch_cqi_indication_UE_MAC(int Mod_id, uint16_t frame,uint8_t subframe, UL_IND_t *UL_INFO, uint16_t rnti); -void fill_ulsch_harq_indication_UE_MAC(int Mod_id, int frame,int subframe, UL_IND_t *UL_INFO, nfapi_ul_config_ulsch_harq_information *harq_information, uint16_t rnti); +void fill_ulsch_harq_indication_UE_MAC(int Mod_id, int frame,int subframe, UL_IND_t *UL_INFO, nfapi_ul_config_ulsch_harq_information *harq_information, uint16_t rnti, + nfapi_ul_config_request_t *ul_config_req); -void fill_uci_harq_indication_UE_MAC(int Mod_id, int frame, int subframe, UL_IND_t *UL_INFO,nfapi_ul_config_harq_information *harq_information, uint16_t rnti +void fill_uci_harq_indication_UE_MAC(int Mod_id, int frame, int subframe, UL_IND_t *UL_INFO,nfapi_ul_config_harq_information *harq_information, uint16_t rnti, + nfapi_ul_config_request_t *ul_config_req /*uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask*/); @@ -80,13 +120,36 @@ int ul_config_req_UE_MAC(nfapi_ul_config_request_t* req, int frame, int subframe void handle_nfapi_ul_pdu_UE_MAC(module_id_t Mod_id, nfapi_ul_config_request_pdu_t *ul_config_pdu, - uint16_t frame,uint8_t subframe,uint8_t srs_present, int index); + uint16_t frame,uint8_t subframe,uint8_t srs_present, int index, + nfapi_ul_config_request_t *ul_config_req); + +typedef struct phy_channel_params_t +{ + uint16_t sfn_sf; + float sinr; + // Incomplete, need all channel parameters +} phy_channel_params_t; + +typedef struct nfapi_tx_req_pdu_list_t +{ + int num_pdus; /* number .pdus[] objects */ + nfapi_tx_request_pdu_t pdus[]; /* see "struct hack" */ +} nfapi_tx_req_pdu_list_t; + +typedef struct nfapi_dl_config_req_tx_req_t +{ + nfapi_dl_config_request_t *dl_config_req; + nfapi_tx_req_pdu_list_t *tx_req_pdu_list; +} nfapi_dl_config_req_tx_req_t; + +void nfapi_free_tx_req_pdu_list(nfapi_tx_req_pdu_list_t *); void dl_config_req_UE_MAC_dci(int sfn, int sf, nfapi_dl_config_request_pdu_t *dci, nfapi_dl_config_request_pdu_t *dlsch, - int num_ue); + int num_ue, + nfapi_tx_req_pdu_list_t *); void dl_config_req_UE_MAC_bch(int sfn, int sf, nfapi_dl_config_request_pdu_t *bch, @@ -94,7 +157,8 @@ void dl_config_req_UE_MAC_bch(int sfn, void dl_config_req_UE_MAC_mch(int sfn, int sf, nfapi_dl_config_request_pdu_t *bch, - int num_ue); + int num_ue, + nfapi_tx_req_pdu_list_t *); int tx_req_UE_MAC(nfapi_tx_request_t* req); @@ -107,19 +171,44 @@ void hi_dci0_req_UE_MAC(int sfn, // The following set of memcpy functions should be getting called as callback functions from // pnf_p7_subframe_ind. -int memcpy_dl_config_req (L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t* pnf_p7, nfapi_dl_config_request_t* req); - - int memcpy_ul_config_req (L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t* pnf_p7, nfapi_ul_config_request_t* req); - -int memcpy_tx_req (nfapi_pnf_p7_config_t* pnf_p7, nfapi_tx_request_t* req); - - int memcpy_hi_dci0_req (L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t* pnf_p7, nfapi_hi_dci0_request_t* req); void UE_config_stub_pnf(void); +void *memcpy_tx_req_standalone(nfapi_tx_request_t *tx_req); +void *memcpy_dl_config_req_standalone(nfapi_dl_config_request_t *dl_config_req); + +// open an SCTP socket with a standalone PNF module +void ue_init_standalone_socket(int tx_port, int rx_port); + +// read from standalone pnf socket call corresponding memcpy functions +void *ue_standalone_pnf_task(void *context); +void send_standalone_msg(UL_IND_t *UL, nfapi_message_id_e msg_type); +void send_standalone_dummy(void); +void enqueue_dl_config_req_tx_req(nfapi_dl_config_request_t *dl_config_req, nfapi_tx_request_t *tx_req); + +// Convert downlink nfapi messages to a string. +// Returned memory is malloc'ed, caller is responsible for freeing. +char *nfapi_dl_config_req_to_string(nfapi_dl_config_request_t *req); +char *nfapi_ul_config_req_to_string(nfapi_ul_config_request_t *req); + +// Convert downlink nfapi messages to a string. +// Returned memory is statically allocated. +const char *dl_pdu_type_to_string(uint8_t pdu_type); +const char *ul_pdu_type_to_string(uint8_t pdu_type); + +extern queue_t dl_config_req_tx_req_queue; +extern queue_t ul_config_req_queue; +extern queue_t hi_dci0_req_queue; + +extern nfapi_ul_config_request_t* ul_config_req; +extern nfapi_hi_dci0_request_t* hi_dci0_req; + +extern int current_sfn_sf; + +extern sem_t sfn_semaphore; #endif /* PHY_STUB_UE_H_ */ diff --git a/openair2/PHY_INTERFACE/queue_t.c b/openair2/PHY_INTERFACE/queue_t.c new file mode 100644 index 0000000000..fd4b870676 --- /dev/null +++ b/openair2/PHY_INTERFACE/queue_t.c @@ -0,0 +1,196 @@ +#include "queue_t.h" +#include +#include + +#ifdef UNITTEST +#include +#define LOG_ERROR(MSG) printf(MSG "\n") +#else +#include "common/utils/LOG/log.h" +#define LOG_ERROR(MSG) LOG_E(PHY, MSG "\n") +#endif + +void init_queue(queue_t *q) +{ + memset(q, 0, sizeof(*q)); + pthread_mutex_init(&q->mutex, NULL); +} + +void reset_queue(queue_t *q) +{ + void *p; + while ((p = get_queue(q)) != NULL) + { + free(p); + } +} + +void *put_queue_replace(queue_t *q, void *item) +{ + assert(item != NULL); + if (pthread_mutex_lock(&q->mutex) != 0) + { + LOG_ERROR("put_queue: mutex_lock failed"); + return false; + } + + void *evicted = NULL; + if (q->num_items >= MAX_QUEUE_SIZE) + { + evicted = q->items[q->read_index]; + assert(evicted != NULL); + q->items[q->read_index] = NULL; + q->read_index = (q->read_index + 1) % MAX_QUEUE_SIZE; + q->num_items--; + } + assert(q->items[q->write_index] == NULL); + q->items[q->write_index] = item; + q->write_index = (q->write_index + 1) % MAX_QUEUE_SIZE; + q->num_items++; + + pthread_mutex_unlock(&q->mutex); + return evicted; +} + + +bool put_queue(queue_t *q, void *item) +{ + assert(item != NULL); + if (pthread_mutex_lock(&q->mutex) != 0) + { + LOG_ERROR("put_queue: mutex_lock failed"); + return false; + } + + bool queued; + if (q->num_items >= MAX_QUEUE_SIZE) + { + LOG_ERROR("put_queue: queue is full"); + queued = false; + } + else + { + assert(q->items[q->write_index] == NULL); + q->items[q->write_index] = item; + q->write_index = (q->write_index + 1) % MAX_QUEUE_SIZE; + q->num_items++; + queued = true; + } + + pthread_mutex_unlock(&q->mutex); + return queued; +} + +void *get_queue(queue_t *q) +{ + void *item = NULL; + if (pthread_mutex_lock(&q->mutex) != 0) + { + LOG_ERROR("get_queue: mutex_lock failed"); + return NULL; + } + + if (q->num_items > 0) + { + item = q->items[q->read_index]; + assert(item != NULL); + q->items[q->read_index] = NULL; + q->read_index = (q->read_index + 1) % MAX_QUEUE_SIZE; + q->num_items--; + } + + pthread_mutex_unlock(&q->mutex); + return item; +} + +bool requeue(queue_t *q, void *item) +{ + assert(item != NULL); + if (pthread_mutex_lock(&q->mutex) != 0) + { + LOG_ERROR("requeue: mutex_lock failed"); + return false; + } + + bool queued; + if (q->num_items >= MAX_QUEUE_SIZE) + { + LOG_ERROR("requeue: queue is full"); + queued = false; + } + else + { + q->read_index = (q->read_index + MAX_QUEUE_SIZE - 1) % MAX_QUEUE_SIZE; + assert(q->items[q->read_index] == NULL); + q->items[q->read_index] = item; + q->num_items++; + queued = true; + } + + pthread_mutex_unlock(&q->mutex); + return queued; +} + +void *unqueue(queue_t *q) +{ + void *item = NULL; + if (pthread_mutex_lock(&q->mutex) != 0) { + LOG_ERROR("unqueue: mutex_lock failed"); + return NULL; + } + + if (q->num_items > 0) { + q->write_index = (q->write_index + MAX_QUEUE_SIZE - 1) % MAX_QUEUE_SIZE; + item = q->items[q->write_index]; + q->items[q->write_index] = NULL; + q->num_items--; + } + + pthread_mutex_unlock(&q->mutex); + return item; +} + +void *unqueue_matching(queue_t *q, size_t max_depth, queue_matcher_t *matcher, void *wanted) +{ + if (pthread_mutex_lock(&q->mutex) != 0) + { + LOG_ERROR("unqueue_matching: mutex_lock failed"); + return NULL; + } + + void *item = NULL; + size_t endi = q->write_index; + for (size_t i = 0; i < q->num_items; i++) + { + if (max_depth == 0) + { + break; + } + --max_depth; + + endi = (endi + MAX_QUEUE_SIZE - 1) % MAX_QUEUE_SIZE; + void *candidate = q->items[endi]; + if (matcher(wanted, candidate)) + { + item = candidate; + // delete item from the queue and move other items down + for (;;) + { + size_t j = (endi + 1) % MAX_QUEUE_SIZE; + if (j == q->write_index) + { + q->items[endi] = NULL; + q->write_index = endi; + q->num_items--; + break; + } + q->items[endi] = q->items[j]; + endi = j; + } + break; + } + } + + pthread_mutex_unlock(&q->mutex); + return item; +} diff --git a/openair2/PHY_INTERFACE/queue_t.h b/openair2/PHY_INTERFACE/queue_t.h new file mode 100644 index 0000000000..4678e31030 --- /dev/null +++ b/openair2/PHY_INTERFACE/queue_t.h @@ -0,0 +1,64 @@ +/* + queue_t is a basic thread-safe non-blocking fixed-size queue. + + put_queue returns false if the queue is full. + get_queue returns NULL if the queue is empty. + + Example usage: + + // Initialization: + queue_t fooq; + init_queue(&fooq); + + // Producer: + foo_t *item = new_foo(); + if (!put_queue(&fooq, item)) + delete_foo(item); + + // Consumer: + foo_t *item = get_queue(&fooq); + if (item) + { + do_something_with_foo(item); + delete_foo(item); + } +*/ + +#pragma once + +#include +#include +#include + +#define MAX_QUEUE_SIZE 512 + +typedef struct queue_t +{ + void *items[MAX_QUEUE_SIZE]; + size_t read_index, write_index; + size_t num_items; + pthread_mutex_t mutex; +} queue_t; + +void init_queue(queue_t *q); +void reset_queue(queue_t *q); +void *put_queue_replace(queue_t *q, void *item); +bool put_queue(queue_t *q, void *item); +void *get_queue(queue_t *q); + +/* Put the given item back onto this queue at the head. + (The next call to put_queue would return this item.) + Return true if successful, false if the queue was full */ +bool requeue(queue_t *q, void *item); + +/* Remove the last item queued. + Return the item or NULL if the queue was empty */ +void *unqueue(queue_t *q); + +typedef bool queue_matcher_t(void *wanted, void *candidate); + +/* Unqueue the most recently queued item for which `matcher(wanted, candidate)` + returns true where `candidate` is an item currently on the queue. + Look only at the last `max_depth` items on the queue, at most. + Returns the candidate item, or NULL if none matches */ +void *unqueue_matching(queue_t *q, size_t max_depth, queue_matcher_t *matcher, void *wanted); diff --git a/openair2/PHY_INTERFACE/queue_test.c b/openair2/PHY_INTERFACE/queue_test.c new file mode 100644 index 0000000000..542b6a676b --- /dev/null +++ b/openair2/PHY_INTERFACE/queue_test.c @@ -0,0 +1,226 @@ +#include "queue_t.h" +#include +#include + +#define FAIL do { \ + printf("\n*** FAILED at %s line %d\n", __FILE__, __LINE__); \ + pass = false; \ +} while (0) + +#define EQUAL(A, B) do { \ + if ((A) != (B)) \ + FAIL; \ +} while (0) + +typedef uint32_t Thing_t; /* actual type doesn't matter */ + +static Thing_t things[MAX_QUEUE_SIZE]; +static Thing_t thing1, thing2; + +static bool matcher(void *wanted, void *candidate) +{ + return wanted == candidate; +} + +int main(void) +{ + bool pass = true; + queue_t queue; + init_queue(&queue); + + for (int i = 0; i < MAX_QUEUE_SIZE; ++i) + { + if (!put_queue(&queue, &things[i])) + { + FAIL; + } + } + + /* queue is full */ + if (put_queue(&queue, &thing1)) + FAIL; + + Thing_t *p; + for (int i = 0; i < MAX_QUEUE_SIZE; ++i) + { + p = get_queue(&queue); + EQUAL(p, &things[i]); + } + + /* queue is empty */ + p = get_queue(&queue); + EQUAL(p, NULL); + + for (int i = 0; i < MAX_QUEUE_SIZE; ++i) + { + if (!put_queue(&queue, &things[i])) + { + FAIL; + } + } + + p = get_queue(&queue); + EQUAL(p, &things[0]); + + p = get_queue(&queue); + EQUAL(p, &things[1]); + + if (!requeue(&queue, &thing1)) + FAIL; + if (!requeue(&queue, &thing2)) + FAIL; + p = get_queue(&queue); + EQUAL(p, &thing2); + p = get_queue(&queue); + EQUAL(p, &thing1); + + if (!requeue(&queue, &things[1])) + FAIL; + if (!requeue(&queue, &things[0])) + FAIL; + + for (int i = 0; i < MAX_QUEUE_SIZE / 2; ++i) + { + p = get_queue(&queue); + EQUAL(p, &things[i]); + } + + for (int i = MAX_QUEUE_SIZE / 2; i < MAX_QUEUE_SIZE; ++i) + { + if (!put_queue(&queue, &things[i])) + FAIL; + } + + p = get_queue(&queue); + EQUAL(p, &things[MAX_QUEUE_SIZE / 2]); + p = get_queue(&queue); + EQUAL(p, &things[MAX_QUEUE_SIZE / 2 + 1]); + + // ---- unqueue ---- + + init_queue(&queue); + for (int i = 0; i < MAX_QUEUE_SIZE; ++i) + { + if (!put_queue(&queue, &things[i])) + { + FAIL; + } + } + for (int i = MAX_QUEUE_SIZE; --i >= 0;) + { + p = unqueue(&queue); + EQUAL(p, &things[i]); + EQUAL(queue.num_items, i); + } + EQUAL(queue.num_items, 0); + if (!put_queue(&queue, &thing1)) + FAIL; + if (!put_queue(&queue, &thing2)) + FAIL; + EQUAL(queue.num_items, 2); + p = get_queue(&queue); + EQUAL(p, &thing1); + p = get_queue(&queue); + EQUAL(p, &thing2); + + // ---- unqueue_matching ---- + + init_queue(&queue); + + // empty queue + p = unqueue_matching(&queue, MAX_QUEUE_SIZE, matcher, &thing1); + EQUAL(p, NULL); + EQUAL(queue.num_items, 0); + + // one item in queue + if (!put_queue(&queue, &thing1)) + FAIL; + EQUAL(queue.num_items, 1); + p = unqueue_matching(&queue, MAX_QUEUE_SIZE, matcher, &thing2); + EQUAL(p, NULL); + EQUAL(queue.num_items, 1); + + p = unqueue_matching(&queue, /*max_queue=*/ 0, matcher, &thing1); + EQUAL(p, NULL); + EQUAL(queue.num_items, 1); + + p = unqueue_matching(&queue, /*max_queue=*/ 1, matcher, &thing1); + EQUAL(p, &thing1); + EQUAL(queue.num_items, 0); + + // more max_queue values + for (int i = 0; i < MAX_QUEUE_SIZE; ++i) + { + if (!put_queue(&queue, &things[i])) + { + FAIL; + } + } + p = unqueue_matching(&queue, /*max_queue=*/ 0, matcher, &things[MAX_QUEUE_SIZE - 1]); + EQUAL(p, NULL); + p = unqueue_matching(&queue, /*max_queue=*/ 1, matcher, &things[MAX_QUEUE_SIZE - 1]); + EQUAL(p, &things[MAX_QUEUE_SIZE - 1]); + EQUAL(queue.num_items, MAX_QUEUE_SIZE - 1); + p = unqueue_matching(&queue, /*max_queue=*/ MAX_QUEUE_SIZE - 2, matcher, &things[0]); + EQUAL(p, NULL); + p = unqueue_matching(&queue, /*max_queue=*/ MAX_QUEUE_SIZE - 1, matcher, &things[0]); + EQUAL(p, &things[0]); + EQUAL(queue.num_items, MAX_QUEUE_SIZE - 2); + + // fill the queue then remove every other item + init_queue(&queue); + for (int i = 0; i < MAX_QUEUE_SIZE; ++i) + { + if (!put_queue(&queue, &things[i])) + { + FAIL; + } + } + p = unqueue_matching(&queue, MAX_QUEUE_SIZE, matcher, &thing1); + EQUAL(p, NULL); + for (int i = MAX_QUEUE_SIZE - 1; i >= 0; i -= 2) + { + p = unqueue_matching(&queue, MAX_QUEUE_SIZE, matcher, &things[i]); + EQUAL(p, &things[i]); + } + EQUAL(queue.num_items, MAX_QUEUE_SIZE / 2); + p = unqueue_matching(&queue, MAX_QUEUE_SIZE, matcher, &thing1); + EQUAL(p, NULL); + for (int i = 0; i < MAX_QUEUE_SIZE; i += 2) + { + p = get_queue(&queue); + EQUAL(p, &things[i]); + } + EQUAL(queue.num_items, 0); + + // fill the queue then remove every third item + for (int i = 0; i < MAX_QUEUE_SIZE; ++i) + { + if (!put_queue(&queue, &things[i])) + { + FAIL; + } + } + p = unqueue_matching(&queue, MAX_QUEUE_SIZE, matcher, &thing1); + EQUAL(p, NULL); + for (int i = 0; i < MAX_QUEUE_SIZE; i += 3) + { + p = unqueue_matching(&queue, MAX_QUEUE_SIZE, matcher, &things[i]); + EQUAL(p, &things[i]); + } + EQUAL(queue.num_items, MAX_QUEUE_SIZE * 2 / 3); + p = unqueue_matching(&queue, MAX_QUEUE_SIZE, matcher, &thing1); + EQUAL(p, NULL); + for (int i = 0; i < MAX_QUEUE_SIZE; ++i) + { + if (i % 3 == 0) + continue; + p = get_queue(&queue); + EQUAL(p, &things[i]); + } + EQUAL(queue.num_items, 0); + + if (!pass) + return EXIT_FAILURE; + return EXIT_SUCCESS; +} diff --git a/openair2/PHY_INTERFACE/queue_test_run b/openair2/PHY_INTERFACE/queue_test_run new file mode 100755 index 0000000000..afb3842eb3 --- /dev/null +++ b/openair2/PHY_INTERFACE/queue_test_run @@ -0,0 +1,18 @@ +#!/bin/bash + +opts=( + -Wall -Werror + -Wno-error=int-to-pointer-cast + -Wno-int-to-pointer-cast + -DUNITTEST +) + +set -x + +gcc "${opts[@]}" -fsanitize=address -o queue_test queue_test.c queue.c || exit +./queue_test || exit + +gcc "${opts[@]}" -o queue_test queue_test.c queue.c || exit +valgrind ./queue_test || exit + +: PASS diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index ce26aeef87..b1f2e6d9b3 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -2129,7 +2129,7 @@ uint8_t do_SIB23(uint8_t Mod_id, return((enc_rval.encoded+7)/8); } -uint8_t do_RRCConnectionRequest(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv) { +uint8_t do_RRCConnectionRequest(uint8_t Mod_id, uint8_t *buffer, size_t buffer_size, uint8_t *rv) { asn_enc_rval_t enc_rval; uint8_t buf[5],buf2=0; LTE_UL_CCCH_Message_t ul_ccch_msg; @@ -2178,7 +2178,7 @@ uint8_t do_RRCConnectionRequest(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv) { NULL, (void *)&ul_ccch_msg, buffer, - 100); + buffer_size); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); LOG_D(RRC,"[UE] RRCConnectionRequest Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8); return((enc_rval.encoded+7)/8); @@ -2378,12 +2378,39 @@ uint8_t do_RRCConnectionSetupComplete(uint8_t Mod_id, uint8_t *buffer, const uin return((enc_rval.encoded+7)/8); } +static void assign_scg_ConfigResponseNR_r15(LTE_RRCConnectionReconfigurationComplete_t *rrc, OCTET_STRING_t *str) +{ + LTE_RRCConnectionReconfigurationComplete_r8_IEs_t *rrc_r8 = &rrc->criticalExtensions.choice. + rrcConnectionReconfigurationComplete_r8; + typeof(rrc_r8->nonCriticalExtension) nce1; + rrc_r8->nonCriticalExtension = nce1 = CALLOC(1, sizeof(*nce1)); + + typeof(nce1->nonCriticalExtension) nce2; + nce1->nonCriticalExtension = nce2 = CALLOC(1, sizeof(*nce2)); + + typeof(nce2->nonCriticalExtension) nce3; + nce2->nonCriticalExtension = nce3 = CALLOC(1, sizeof(*nce3)); + + typeof(nce3->nonCriticalExtension) nce4; + nce3->nonCriticalExtension = nce4 = CALLOC(1, sizeof(*nce4)); + + typeof(nce4->nonCriticalExtension) nce5; + nce4->nonCriticalExtension = nce5 = CALLOC(1, sizeof(*nce5)); + + typeof(nce5->nonCriticalExtension) nce6; + nce5->nonCriticalExtension = nce6 = CALLOC(1, sizeof(*nce6)); + + nce6->scg_ConfigResponseNR_r15 = str; +} + //------------------------------------------------------------------------------ -uint8_t +size_t do_RRCConnectionReconfigurationComplete( const protocol_ctxt_t *const ctxt_pP, uint8_t *buffer, - const uint8_t Transaction_id + size_t buffer_size, + const uint8_t Transaction_id, + OCTET_STRING_t *str ) //------------------------------------------------------------------------------ { @@ -2397,7 +2424,13 @@ do_RRCConnectionReconfigurationComplete( rrcConnectionReconfigurationComplete->rrc_TransactionIdentifier = Transaction_id; rrcConnectionReconfigurationComplete->criticalExtensions.present = LTE_RRCConnectionReconfigurationComplete__criticalExtensions_PR_rrcConnectionReconfigurationComplete_r8; - rrcConnectionReconfigurationComplete->criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8.nonCriticalExtension=NULL; + if (str != NULL) { + assign_scg_ConfigResponseNR_r15(rrcConnectionReconfigurationComplete, str); + LOG_D(RRC, "Successfully assigned scg_ConfigResponseNR_r15\n"); + } + else { + rrcConnectionReconfigurationComplete->criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8.nonCriticalExtension=NULL; + } if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)&ul_dcch_msg); @@ -2407,7 +2440,7 @@ do_RRCConnectionReconfigurationComplete( NULL, (void *)&ul_dcch_msg, buffer, - 100); + buffer_size); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); LOG_D(RRC,"RRCConnectionReconfigurationComplete Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); @@ -3142,6 +3175,7 @@ uint8_t do_RRCConnectionSetup_BR( uint8_t do_SecurityModeCommand( const protocol_ctxt_t *const ctxt_pP, uint8_t *const buffer, + size_t buffer_size, const uint8_t Transaction_id, const uint8_t cipheringAlgorithm, const uint8_t integrityProtAlgorithm @@ -3171,7 +3205,7 @@ uint8_t do_SecurityModeCommand( NULL, (void *)&dl_dcch_msg, buffer, - 100); + buffer_size); if(enc_rval.encoded == -1) { LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", @@ -3200,6 +3234,7 @@ uint8_t do_SecurityModeCommand( //------------------------------------------------------------------------------ uint8_t do_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, uint8_t *const buffer, + size_t buffer_size, const uint8_t Transaction_id, int16_t eutra_band, uint32_t nr_band) @@ -3220,58 +3255,56 @@ uint8_t do_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list.count=0; ASN_SEQUENCE_ADD(&dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list, &rat); + + /* request NR configuration */ LTE_UECapabilityEnquiry_r8_IEs_t *r8 = &dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8; LTE_UECapabilityEnquiry_v8a0_IEs_t r8_a0; LTE_UECapabilityEnquiry_v1180_IEs_t r11_80; LTE_UECapabilityEnquiry_v1310_IEs_t r13_10; LTE_UECapabilityEnquiry_v1430_IEs_t r14_30; LTE_UECapabilityEnquiry_v1510_IEs_t r15_10; - OCTET_STRING_t req_freq; - if (nr_band>0) { + memset(&r8_a0, 0, sizeof(r8_a0)); + memset(&r11_80, 0, sizeof(r11_80)); + memset(&r13_10, 0, sizeof(r13_10)); + memset(&r14_30, 0, sizeof(r14_30)); + memset(&r15_10, 0, sizeof(r15_10)); - /* request NR configuration */ + r8->nonCriticalExtension = &r8_a0; + r8_a0.nonCriticalExtension = &r11_80; + r11_80.nonCriticalExtension = &r13_10; + r13_10.nonCriticalExtension = &r14_30; + r14_30.nonCriticalExtension = &r15_10; - memset(&r8_a0, 0, sizeof(r8_a0)); - memset(&r11_80, 0, sizeof(r11_80)); - memset(&r13_10, 0, sizeof(r13_10)); - memset(&r14_30, 0, sizeof(r14_30)); - memset(&r15_10, 0, sizeof(r15_10)); + /* TODO: no hardcoded values here */ - r8->nonCriticalExtension = &r8_a0; - r8_a0.nonCriticalExtension = &r11_80; - r11_80.nonCriticalExtension = &r13_10; - r13_10.nonCriticalExtension = &r14_30; - r14_30.nonCriticalExtension = &r15_10; + nsa_band_list = (NR_FreqBandList_t *)calloc(1, sizeof(NR_FreqBandList_t)); - /* TODO: no hardcoded values here */ + nsa_band = (NR_FreqBandInformation_t *) calloc(1,sizeof(NR_FreqBandInformation_t)); + nsa_band->present = NR_FreqBandInformation_PR_bandInformationEUTRA; + nsa_band->choice.bandInformationEUTRA = (NR_FreqBandInformationEUTRA_t *) calloc(1, sizeof(NR_FreqBandInformationEUTRA_t)); + nsa_band->choice.bandInformationEUTRA->bandEUTRA = eutra_band; + ASN_SEQUENCE_ADD(&nsa_band_list->list, nsa_band); - nsa_band_list = (NR_FreqBandList_t *)calloc(1, sizeof(NR_FreqBandList_t)); - - nsa_band = (NR_FreqBandInformation_t *) calloc(1,sizeof(NR_FreqBandInformation_t)); - nsa_band->present = NR_FreqBandInformation_PR_bandInformationEUTRA; - nsa_band->choice.bandInformationEUTRA = (NR_FreqBandInformationEUTRA_t *) calloc(1, sizeof(NR_FreqBandInformationEUTRA_t)); - nsa_band->choice.bandInformationEUTRA->bandEUTRA = eutra_band; - ASN_SEQUENCE_ADD(&nsa_band_list->list, nsa_band); - - nsa_band = (NR_FreqBandInformation_t *) calloc(1,sizeof(NR_FreqBandInformation_t)); - nsa_band->present = NR_FreqBandInformation_PR_bandInformationNR; - nsa_band->choice.bandInformationNR = (NR_FreqBandInformationNR_t *) calloc(1, sizeof(NR_FreqBandInformationNR_t)); - //if(nr_band > 0) + nsa_band = (NR_FreqBandInformation_t *) calloc(1,sizeof(NR_FreqBandInformation_t)); + nsa_band->present = NR_FreqBandInformation_PR_bandInformationNR; + nsa_band->choice.bandInformationNR = (NR_FreqBandInformationNR_t *) calloc(1, sizeof(NR_FreqBandInformationNR_t)); + if(nr_band > 0) nsa_band->choice.bandInformationNR->bandNR = nr_band; - //else - // nsa_band->choice.bandInformationNR->bandNR = 78; - ASN_SEQUENCE_ADD(&nsa_band_list->list, nsa_band); + else + nsa_band->choice.bandInformationNR->bandNR = 78; + ASN_SEQUENCE_ADD(&nsa_band_list->list, nsa_band); + OCTET_STRING_t req_freq; //unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x02, 0x68 }; // bands 7 & nr78 - unsigned char req_freq_buf[1024]; - enc_rval = uper_encode_to_buffer(&asn_DEF_NR_FreqBandList, - NULL, - (void *)nsa_band_list, - req_freq_buf, - 1024); + unsigned char req_freq_buf[1024]; + enc_rval = uper_encode_to_buffer(&asn_DEF_NR_FreqBandList, + NULL, + (void *)nsa_band_list, + req_freq_buf, + 1024); - xer_fprint(stdout, &asn_DEF_NR_FreqBandList, (void *)nsa_band_list); + xer_fprint(stdout, &asn_DEF_NR_FreqBandList, (void *)nsa_band_list); @@ -3282,22 +3315,20 @@ uint8_t do_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, //0x01, 0x60, 0x18, 0x05, 0x80, 0xc0, 0x04, 0x04, 0xc1, 0x2c, 0x10, 0x08, 0x20, 0x30, 0x40, 0xe0, 0x82, 0x40, 0x28, 0x80, 0x9a // }; - req_freq.buf = req_freq_buf; - req_freq.size = (enc_rval.encoded+7)/8; + req_freq.buf = req_freq_buf; + req_freq.size = (enc_rval.encoded+7)/8; // req_freq.size = 21; - r15_10.requestedFreqBandsNR_MRDC_r15 = &req_freq; - // Add request for eutra-nr - } -// if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + r15_10.requestedFreqBandsNR_MRDC_r15 = &req_freq; + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { xer_fprint(stdout, &asn_DEF_LTE_DL_DCCH_Message, (void *)&dl_dcch_msg); -// } + } enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_DCCH_Message, NULL, (void *)&dl_dcch_msg, buffer, - 100); + buffer_size); if(enc_rval.encoded == -1) { LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", @@ -3324,6 +3355,7 @@ uint8_t do_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, //------------------------------------------------------------------------------ uint8_t do_NR_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, uint8_t *const buffer, + size_t buffer_size, const uint8_t Transaction_id, int16_t eutra_band, uint32_t nr_band) @@ -3417,7 +3449,7 @@ uint8_t do_NR_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, NULL, (void *)&dl_dcch_msg, buffer, - 100); + buffer_size); if(enc_rval.encoded == -1) { LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", @@ -3444,6 +3476,7 @@ uint8_t do_NR_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, uint16_t do_RRCConnectionReconfiguration_BR(const protocol_ctxt_t *const ctxt_pP, uint8_t *buffer, + size_t buffer_size, uint8_t Transaction_id, LTE_SRB_ToAddModList_t *SRB_list, LTE_DRB_ToAddModList_t *DRB_list, @@ -3545,7 +3578,7 @@ uint16_t do_RRCConnectionReconfiguration_BR(const protocol_ctxt_t *const NULL, (void *)&dl_dcch_msg, buffer, - RRC_BUF_SIZE); + buffer_size); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed %s, %lu!\n", enc_rval.failed_type->name, enc_rval.encoded); if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { @@ -3562,6 +3595,7 @@ uint16_t do_RRCConnectionReconfiguration_BR(const protocol_ctxt_t *const */ uint16_t do_RRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP, uint8_t *buffer, + size_t buffer_size, uint8_t Transaction_id, LTE_SRB_ToAddModList_t *SRB_list, LTE_DRB_ToAddModList_t *DRB_list, @@ -3722,7 +3756,7 @@ uint16_t do_RRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP, NULL, (void *)&dl_dcch_msg, buffer, - RRC_BUF_SIZE); + buffer_size); if(enc_rval.encoded == -1) { LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", @@ -3977,6 +4011,7 @@ uint8_t do_RRCConnectionReject(uint8_t Mod_id, uint8_t do_RRCConnectionRelease(uint8_t Mod_id, uint8_t *buffer, + size_t buffer_size, uint8_t Transaction_id) { asn_enc_rval_t enc_rval; LTE_DL_DCCH_Message_t dl_dcch_msg; @@ -3998,7 +4033,7 @@ uint8_t do_RRCConnectionRelease(uint8_t Mod_id, NULL, (void *)&dl_dcch_msg, buffer, - RRC_BUF_SIZE); + buffer_size); return((enc_rval.encoded+7)/8); } @@ -4008,6 +4043,7 @@ uint8_t TMGI[5] = {4,3,2,1,0};//TMGI is a string of octet, ref. TS 24.008 fig. 1 uint8_t do_MBSFNAreaConfig(uint8_t Mod_id, uint8_t sync_area, uint8_t *buffer, + size_t buffer_size, LTE_MCCH_Message_t *mcch_message, LTE_MBSFNAreaConfiguration_r9_t **mbsfnAreaConfiguration) { asn_enc_rval_t enc_rval; @@ -4114,7 +4150,7 @@ uint8_t do_MBSFNAreaConfig(uint8_t Mod_id, NULL, (void *)mcch_message, buffer, - 100); + buffer_size); if(enc_rval.encoded == -1) { LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", @@ -4133,7 +4169,9 @@ uint8_t do_MBSFNAreaConfig(uint8_t Mod_id, } -uint8_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer,int measid,int phy_id,long rsrp_s,long rsrq_s,long rsrp_t,long rsrq_t) { +uint8_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer, size_t buffer_size, + int measid, int phy_id, long rsrp_s, long rsrq_s, + long rsrp_t, long rsrq_t) { asn_enc_rval_t enc_rval; LTE_UL_DCCH_Message_t ul_dcch_msg; LTE_MeasurementReport_t *measurementReport; @@ -4205,7 +4243,7 @@ uint8_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer,int measid,int phy_ NULL, (void *)&ul_dcch_msg, buffer, - 100); + buffer_size); if(enc_rval.encoded == -1) { LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", @@ -4220,6 +4258,64 @@ uint8_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer,int measid,int phy_ return((enc_rval.encoded+7)/8); } +#define asn1cCallocOne(VaR, VaLue) \ + VaR = calloc(1,sizeof(*VaR)); *VaR=VaLue; +#define asn1cCalloc(VaR, lOcPtr) \ + typeof(VaR) lOcPtr = VaR = calloc(1,sizeof(*VaR)); +#define asn1cSequenceAdd(VaR, TyPe, lOcPtr) \ + TyPe *lOcPtr= calloc(1,sizeof(TyPe)); \ + ASN_SEQUENCE_ADD(&VaR,lOcPtr); + +ssize_t do_nrMeasurementReport(uint8_t *buffer, + size_t bufsize, + LTE_MeasId_t measid, + LTE_PhysCellIdNR_r15_t phy_id, + long rsrp_s, + long rsrq_s, + long rsrp_tar, + long rsrq_tar) { + + LTE_UL_DCCH_Message_t ul_dcch_msg={0}; + ul_dcch_msg.message.present = LTE_UL_DCCH_MessageType_PR_c1; + ul_dcch_msg.message.choice.c1.present = LTE_UL_DCCH_MessageType__c1_PR_measurementReport; + + LTE_MeasurementReport_t *measurementReport = &ul_dcch_msg.message.choice.c1.choice.measurementReport; + measurementReport->criticalExtensions.present = LTE_MeasurementReport__criticalExtensions_PR_c1; + measurementReport->criticalExtensions.choice.c1.present = LTE_MeasurementReport__criticalExtensions__c1_PR_measurementReport_r8; + measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.nonCriticalExtension = + calloc(1, sizeof(*measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.nonCriticalExtension)); + measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.measResults.measId = measid; + measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.measResults.measResultPCell.rsrpResult = rsrp_s; + measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.measResults.measResultPCell.rsrqResult = rsrq_s; + asn1cCalloc(measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.measResults.measResultNeighCells, + measResultNeighCells); + measResultNeighCells->present = LTE_MeasResults__measResultNeighCells_PR_measResultNeighCellListNR_r15; + LTE_MeasResultListEUTRA_t *measResultListEUTRA2=&measResultNeighCells->choice.measResultListEUTRA; + asn1cSequenceAdd(measResultListEUTRA2->list, struct LTE_MeasResultEUTRA, measresulteutra_list); + measresulteutra_list->physCellId = phy_id; + asn1cCalloc(measresulteutra_list->cgi_Info, measresult_cgi2); + //measresult_cgi2->cellGlobalId= {0}; + //measresult_cgi2->trackingAreaCode= {0}; + struct LTE_MeasResultEUTRA__measResult* measResult= &measresulteutra_list->measResult; + asn1cCallocOne(measResult->rsrpResult, rsrp_tar); + asn1cCallocOne(measResult->rsrqResult, rsrq_tar); + + + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_UL_DCCH_Message, + NULL, + &ul_dcch_msg, + buffer, + bufsize); + if(enc_rval.encoded == -1) { + LOG_I(RRC, "[eNB AssertFatal] ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + SEQUENCE_free(&asn_DEF_LTE_UL_DCCH_Message, &ul_dcch_msg, ASFM_FREE_UNDERLYING_AND_RESET); + return -1; + } + + return((enc_rval.encoded+7)/8); +} + uint8_t do_DLInformationTransfer(uint8_t Mod_id, uint8_t **buffer, uint8_t transaction_id, uint32_t pdu_length, uint8_t *pdu_buffer) { ssize_t encoded; LTE_DL_DCCH_Message_t dl_dcch_msg; @@ -4237,7 +4333,8 @@ uint8_t do_DLInformationTransfer(uint8_t Mod_id, uint8_t **buffer, uint8_t trans return encoded; } -uint8_t do_Paging(uint8_t Mod_id, uint8_t *buffer, ue_paging_identity_t ue_paging_identity, cn_domain_t cn_domain) { +uint8_t do_Paging(uint8_t Mod_id, uint8_t *buffer, size_t buffer_size, + ue_paging_identity_t ue_paging_identity, cn_domain_t cn_domain) { LOG_D(RRC, "[eNB %d] do_Paging start\n", Mod_id); asn_enc_rval_t enc_rval; LTE_PCCH_Message_t pcch_msg; @@ -4289,7 +4386,8 @@ uint8_t do_Paging(uint8_t Mod_id, uint8_t *buffer, ue_paging_identity_t ue_pagin ASN_SEQUENCE_ADD(&pcch_msg.message.choice.c1.choice.paging.pagingRecordList->list, paging_record_p); LOG_D(RRC, "[eNB %d] do_Paging paging_record: cn_Domain %ld, ue_paging_identity.presenceMask %d, PagingRecordList.count %d\n", Mod_id, paging_record_p->cn_Domain, ue_paging_identity.presenceMask, pcch_msg.message.choice.c1.choice.paging.pagingRecordList->list.count); - enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_PCCH_Message, NULL, (void *)&pcch_msg, buffer, RRC_BUF_SIZE); + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_PCCH_Message, NULL, (void *)&pcch_msg, + buffer, buffer_size); if(enc_rval.encoded == -1) { LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", @@ -4378,7 +4476,161 @@ int do_HandoverCommand(char *ho_buf, int ho_size, char *rrc_buf, int rrc_size) { return((enc_rval.encoded+7)/8); } -OAI_UECapability_t *fill_ue_capability(char *UE_EUTRA_Capability_xer_fname) { +//----------------------------------------------------------------------------- +int +is_en_dc_supported( + LTE_UE_EUTRA_Capability_t *c +) +//----------------------------------------------------------------------------- +{ + LOG_D(RRC, "Entered %s \n", __FUNCTION__); + /* to be refined - check that the bands supported by the UE include + * the band of the gNB + */ +#define NCE nonCriticalExtension + return c != NULL + && c->NCE != NULL + && c->NCE->NCE != NULL + && c->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->irat_ParametersNR_r15 != NULL + && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->irat_ParametersNR_r15->en_DC_r15 != NULL + && *c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->irat_ParametersNR_r15->en_DC_r15 == + LTE_IRAT_ParametersNR_r15__en_DC_r15_supported; +#undef NCE +} + +void allocate_en_DC_r15(LTE_UE_EUTRA_Capability_t *cap) +{ + LOG_D(RRC, "Entered %s\n", __FUNCTION__); + if (!cap->nonCriticalExtension) + cap->nonCriticalExtension = CALLOC(1, sizeof(*cap->nonCriticalExtension)); + + typeof(cap->nonCriticalExtension) nce1 = cap->nonCriticalExtension; + if (!nce1->nonCriticalExtension) + nce1->nonCriticalExtension = CALLOC(1, sizeof(*nce1->nonCriticalExtension)); + + typeof(nce1->nonCriticalExtension) nce2 = nce1->nonCriticalExtension; + if (!nce2->nonCriticalExtension) + nce2->nonCriticalExtension = CALLOC(1, sizeof(*nce2->nonCriticalExtension)); + + typeof(nce2->nonCriticalExtension) nce3 = nce2->nonCriticalExtension; + if (!nce3->nonCriticalExtension) + nce3->nonCriticalExtension = CALLOC(1, sizeof(*nce3->nonCriticalExtension)); + + typeof(nce3->nonCriticalExtension) nce4 = nce3->nonCriticalExtension; + if (!nce4->nonCriticalExtension) + nce4->nonCriticalExtension = CALLOC(1, sizeof(*nce4->nonCriticalExtension)); + + typeof(nce4->nonCriticalExtension) nce5 = nce4->nonCriticalExtension; + if (!nce5->nonCriticalExtension) + nce5->nonCriticalExtension = CALLOC(1, sizeof(*nce5->nonCriticalExtension)); + + typeof(nce5->nonCriticalExtension) nce6 = nce5->nonCriticalExtension; + if (!nce6->nonCriticalExtension) + nce6->nonCriticalExtension = CALLOC(1, sizeof(*nce6->nonCriticalExtension)); + + typeof(nce6->nonCriticalExtension) nce7 = nce6->nonCriticalExtension; + if (!nce7->nonCriticalExtension) + nce7->nonCriticalExtension = CALLOC(1, sizeof(*nce7->nonCriticalExtension)); + + typeof(nce7->nonCriticalExtension) nce8 = nce7->nonCriticalExtension; + if (!nce8->nonCriticalExtension) + nce8->nonCriticalExtension = CALLOC(1, sizeof(*nce8->nonCriticalExtension)); + + typeof(nce8->nonCriticalExtension) nce9 = nce8->nonCriticalExtension; + if (!nce9->nonCriticalExtension) + nce9->nonCriticalExtension = CALLOC(1, sizeof(*nce9->nonCriticalExtension)); + + typeof(nce9->nonCriticalExtension) nce10 = nce9->nonCriticalExtension; + if (!nce10->nonCriticalExtension) + nce10->nonCriticalExtension = CALLOC(1, sizeof(*nce10->nonCriticalExtension)); + + typeof(nce10->nonCriticalExtension) nce11 = nce10->nonCriticalExtension; + if (!nce11->nonCriticalExtension) + nce11->nonCriticalExtension = CALLOC(1, sizeof(*nce11->nonCriticalExtension)); + + typeof(nce11->nonCriticalExtension) nce12 = nce11->nonCriticalExtension; + if (!nce12->nonCriticalExtension) + nce12->nonCriticalExtension = CALLOC(1, sizeof(*nce12->nonCriticalExtension)); + + typeof(nce12->nonCriticalExtension) nce13 = nce12->nonCriticalExtension; + if (!nce13->nonCriticalExtension) + nce13->nonCriticalExtension = CALLOC(1, sizeof(*nce13->nonCriticalExtension)); + + typeof(nce13->nonCriticalExtension) nce14 = nce13->nonCriticalExtension; + if (!nce14->nonCriticalExtension) + nce14->nonCriticalExtension = CALLOC(1, sizeof(*nce14->nonCriticalExtension)); + + typeof(nce14->nonCriticalExtension) nce15 = nce14->nonCriticalExtension; + if (!nce15->nonCriticalExtension) + nce15->nonCriticalExtension = CALLOC(1, sizeof(*nce15->nonCriticalExtension)); + + typeof(nce15->nonCriticalExtension) nce16 = nce15->nonCriticalExtension; + if (!nce16->nonCriticalExtension) + nce16->nonCriticalExtension = CALLOC(1, sizeof(*nce16->nonCriticalExtension)); + + typeof(nce16->nonCriticalExtension) nce17 = nce16->nonCriticalExtension; + if (!nce17->nonCriticalExtension) + nce17->nonCriticalExtension = CALLOC(1, sizeof(*nce17->nonCriticalExtension)); + + typeof(nce17->nonCriticalExtension) nce18 = nce17->nonCriticalExtension; + if (!nce18->nonCriticalExtension) + nce18->nonCriticalExtension = CALLOC(1, sizeof(*nce18->nonCriticalExtension)); + + typeof(nce18->nonCriticalExtension) nce19 = nce18->nonCriticalExtension; + if (!nce19->nonCriticalExtension) + nce19->nonCriticalExtension = CALLOC(1, sizeof(*nce19->nonCriticalExtension)); + + typeof(nce19->nonCriticalExtension) nce20 = nce19->nonCriticalExtension; + if (!nce20->nonCriticalExtension) + nce20->nonCriticalExtension = CALLOC(1, sizeof(*nce20->nonCriticalExtension)); + + typeof(nce20->nonCriticalExtension) nce21 = nce20->nonCriticalExtension; + if (!nce21->nonCriticalExtension) + nce21->nonCriticalExtension = CALLOC(1, sizeof(*nce21->nonCriticalExtension)); + + typeof(nce21->nonCriticalExtension) nce22 = nce21->nonCriticalExtension; + if (!nce22->nonCriticalExtension) + nce22->nonCriticalExtension = CALLOC(1, sizeof(*nce22->nonCriticalExtension)); + + typeof(nce22->nonCriticalExtension) nce23 = nce22->nonCriticalExtension; + if (!nce23->nonCriticalExtension) + nce23->nonCriticalExtension = CALLOC(1, sizeof(*nce23->nonCriticalExtension)); + + typeof(nce23->nonCriticalExtension) nce24 = nce23->nonCriticalExtension; + if (!nce24->irat_ParametersNR_r15) + nce24->irat_ParametersNR_r15 = CALLOC(1, sizeof(*nce24->irat_ParametersNR_r15)); + + typeof(nce24->irat_ParametersNR_r15) irat = nce24->irat_ParametersNR_r15; + if (!irat->en_DC_r15) + irat->en_DC_r15 = CALLOC(1, sizeof(*irat->en_DC_r15)); + + *irat->en_DC_r15 = LTE_IRAT_ParametersNR_r15__en_DC_r15_supported; + +} + +OAI_UECapability_t *fill_ue_capability(char *UE_EUTRA_Capability_xer_fname, bool received_nr_msg) { static OAI_UECapability_t UECapability; /* TODO declared static to allow returning this has an address should be allocated in a cleaner way. */ static LTE_SupportedBandEUTRA_t Bandlist[4]; // the macro ASN_SEQUENCE_ADD() does not copy the source, but only stores a reference to it static LTE_InterFreqBandInfo_t InterFreqBandInfo[4][4]; // the macro ASN_SEQUENCE_ADD() does not copy the source, but only stores a reference to it @@ -4476,7 +4728,13 @@ OAI_UECapability_t *fill_ue_capability(char *UE_EUTRA_Capability_xer_fname) { UE_EUTRA_Capability->featureGroupIndicators = bit_string; } - // UE_EUTRA_Capability->interRAT_Parameters // null + if (get_softmodem_params()->nsa && received_nr_msg) + { + allocate_en_DC_r15(UE_EUTRA_Capability); + if (!is_en_dc_supported(UE_EUTRA_Capability)){ + LOG_E(RRC, "We did not properly allocate en_DC_r15 for UE_EUTRA_Capability\n"); + } + } } else { FILE *f = fopen(UE_EUTRA_Capability_xer_fname, "r"); assert(f); diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.h b/openair2/RRC/LTE/MESSAGES/asn1_msg.h index 28eb91a5b0..d1d1d3febe 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.h +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.h @@ -41,6 +41,7 @@ #include "RRC/LTE/rrc_defs.h" #include "LTE_SL-DestinationInfoList-r12.h" +#include "OctetString.h" /* * The variant of the above function which dumps the BASIC-XER (XER_F_BASIC) @@ -137,7 +138,7 @@ routine only generates an mo-data establishment cause. @param rv 5 byte random string or S-TMSI @returns Size of encoded bit stream in bytes*/ -uint8_t do_RRCConnectionRequest(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv); +uint8_t do_RRCConnectionRequest(uint8_t Mod_id, uint8_t *buffer, size_t buffer_size, uint8_t *rv); /** \brief Generate an SidelinkUEInformation UL-DCCH-Message (UE). @@ -164,7 +165,9 @@ uint8_t do_RRCConnectionReconfigurationComplete( const protocol_ctxt_t *const ctxt_pP, uint8_t *buffer, - const uint8_t Transaction_id + size_t buffer_size, + const uint8_t Transaction_id, + OCTET_STRING_t *str ); /** @@ -212,6 +215,7 @@ uint16_t do_RRCConnectionReconfiguration_BR( const protocol_ctxt_t *const ctxt_pP, uint8_t *buffer, + size_t buffer_size, uint8_t Transaction_id, LTE_SRB_ToAddModList_t *SRB_list, LTE_DRB_ToAddModList_t *DRB_list, @@ -257,6 +261,7 @@ uint16_t do_RRCConnectionReconfiguration( const protocol_ctxt_t *const ctxt_pP, uint8_t *buffer, + size_t buffer_size, uint8_t Transaction_id, LTE_SRB_ToAddModList_t *SRB_list, LTE_DRB_ToAddModList_t *DRB_list, @@ -330,14 +335,8 @@ routine only generates an mo-data establishment cause. @param transaction_id Transaction index @returns Size of encoded bit stream in bytes*/ -uint8_t do_RRCConnectionRelease(uint8_t Mod_id, uint8_t *buffer,int Transaction_id); +uint8_t do_RRCConnectionRelease(uint8_t Mod_id, uint8_t *buffer, size_t buffer_size, int Transaction_id); -/*** - * \brief Generate an MCCH-Message (eNB). This routine configures MBSFNAreaConfiguration (PMCH-InfoList and Subframe Allocation for MBMS data) - * @param buffer Pointer to PER-encoded ASN.1 description of MCCH-Message PDU - * @returns Size of encoded bit stream in bytes -*/ -uint8_t do_MCCHMessage(uint8_t *buffer); /*** * \brief Generate an MCCH-Message (eNB). This routine configures MBSFNAreaConfiguration (PMCH-InfoList and Subframe Allocation for MBMS data) * @param buffer Pointer to PER-encoded ASN.1 description of MCCH-Message PDU @@ -346,14 +345,28 @@ uint8_t do_MCCHMessage(uint8_t *buffer); uint8_t do_MBSFNAreaConfig(uint8_t Mod_id, uint8_t sync_area, uint8_t *buffer, + size_t buffer_size, LTE_MCCH_Message_t *mcch_message, LTE_MBSFNAreaConfiguration_r9_t **mbsfnAreaConfiguration); -uint8_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer,int measid,int phy_id,long rsrp_s,long rsrq_s,long rsrp_t,long rsrq_t); +ssize_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer, size_t buffer_size, + int measid, int phy_id, + long rsrp_s, long rsrq_s, + long rsrp_t, long rsrq_t); + +ssize_t do_nrMeasurementReport(uint8_t *buffer, + size_t bufsize, + LTE_MeasId_t measid, + LTE_PhysCellIdNR_r15_t phy_id, + long rsrp_s, + long rsrq_s, + long rsrp_tar, + long rsrq_tar); uint8_t do_DLInformationTransfer(uint8_t Mod_id, uint8_t **buffer, uint8_t transaction_id, uint32_t pdu_length, uint8_t *pdu_buffer); -uint8_t do_Paging(uint8_t Mod_id, uint8_t *buffer, ue_paging_identity_t ue_paging_identity, cn_domain_t cn_domain); +uint8_t do_Paging(uint8_t Mod_id, uint8_t *buffer, size_t buffer_size, + ue_paging_identity_t ue_paging_identity, cn_domain_t cn_domain); uint8_t do_ULInformationTransfer(uint8_t **buffer, uint32_t pdu_length, uint8_t *pdu_buffer); @@ -361,12 +374,17 @@ int do_HandoverPreparation(char *ho_buf, int ho_size, LTE_UE_EUTRA_Capability_t int do_HandoverCommand(char *ho_buf, int ho_size, char *rrc_buf, int rrc_size); -OAI_UECapability_t *fill_ue_capability(char *LTE_UE_EUTRA_Capability_xer); +OAI_UECapability_t *fill_ue_capability(char *LTE_UE_EUTRA_Capability_xer, bool received_nr_msg); + +int is_en_dc_supported(LTE_UE_EUTRA_Capability_t *c); + +void allocate_en_DC_r15(LTE_UE_EUTRA_Capability_t *cap); uint8_t do_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, uint8_t *const buffer, + size_t buffer_size, const uint8_t Transaction_id, int16_t eutra_band, uint32_t nr_band); @@ -375,6 +393,7 @@ uint8_t do_NR_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, uint8_t *const buffer, + size_t buffer_size, const uint8_t Transaction_id, int16_t eutra_band, uint32_t nr_band); @@ -382,6 +401,7 @@ do_NR_UECapabilityEnquiry( uint8_t do_SecurityModeCommand( const protocol_ctxt_t *const ctxt_pP, uint8_t *const buffer, + size_t buffer_size, const uint8_t Transaction_id, const uint8_t cipheringAlgorithm, const uint8_t integrityProtAlgorithm); diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.c b/openair2/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.c index 350a8baf77..d13dcb9918 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.c @@ -834,6 +834,7 @@ uint8_t do_UECapabilityEnquiry_NB_IoT( uint16_t do_RRCConnectionReconfiguration_NB_IoT( const protocol_ctxt_t *const ctxt_pP, uint8_t *buffer, + size_t buffer_size, uint8_t Transaction_id, LTE_SRB_ToAddModList_NB_r13_t *SRB1_list_NB, //SRB_ConfigList2 (default)--> only SRB1 LTE_DRB_ToAddModList_NB_r13_t *DRB_list_NB_IoT, //DRB_ConfigList (default) @@ -886,7 +887,7 @@ uint16_t do_RRCConnectionReconfiguration_NB_IoT( NULL, (void *)&dl_dcch_msg_NB_IoT, buffer, - RRC_BUF_SIZE); + buffer_size); if (enc_rval.encoded <= 0) { LOG_E(RRC, "ASN1 message encoding failed %s, %li\n", @@ -1020,7 +1021,8 @@ uint8_t do_DLInformationTransfer_NB_IoT( /*do_RRCConnectionReestablishment_NB-->used to re-establish SRB1*/ //which parameter to use? uint8_t do_RRCConnectionReestablishment_NB_IoT( uint8_t Mod_id, - uint8_t *const buffer, + uint8_t *buffer, + size_t buffer_size, const uint8_t Transaction_id, const NB_IoT_DL_FRAME_PARMS *const frame_parms, //to be changed LTE_SRB_ToAddModList_NB_r13_t *SRB_list_NB_IoT) { //should contain SRB1 already configured? @@ -1046,7 +1048,7 @@ uint8_t do_RRCConnectionReestablishment_NB_IoT( NULL, (void *)&dl_ccch_msg_NB_IoT, buffer, - RRC_BUF_SIZE); + buffer_size); if (enc_rval.encoded <= 0) { LOG_E(RRC, "ASN1 message encoding failed (%s, %li)!\n", @@ -1065,6 +1067,7 @@ uint8_t do_RRCConnectionReestablishment_NB_IoT( uint8_t do_RRCConnectionRelease_NB_IoT( uint8_t Mod_id, uint8_t *buffer, + size_t buffer_size, const uint8_t Transaction_id) { asn_enc_rval_t enc_rval; LTE_DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; @@ -1087,7 +1090,7 @@ uint8_t do_RRCConnectionRelease_NB_IoT( NULL, (void *)&dl_dcch_msg_NB_IoT, buffer, - RRC_BUF_SIZE);//check + buffer_size); return((enc_rval.encoded+7)/8); } diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.h b/openair2/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.h index a862af7836..b52fdb76e0 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.h +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.h @@ -125,10 +125,12 @@ uint8_t do_RRCConnectionSetupComplete_NB_IoT(uint8_t Mod_id, uint8_t* buffer, co @param Transaction_id @returns Size of encoded bit stream in bytes*/ -uint8_t do_RRCConnectionReconfigurationComplete_NB_IoT( +size_t do_RRCConnectionReconfigurationComplete_NB_IoT( const protocol_ctxt_t* const ctxt_pP, uint8_t* buffer, - const uint8_t Transaction_id + size_t buffer_size, + const uint8_t Transaction_id, + OCTET_STRING_t *str ); /** @@ -178,6 +180,7 @@ uint16_t do_RRCConnectionReconfiguration_NB_IoT( const protocol_ctxt_t* const ctxt_pP, uint8_t *buffer, + size_t buffer_size, uint8_t Transaction_id, SRB_ToAddModList_NB_r13_t *SRB_list_NB_IoT, DRB_ToAddModList_NB_r13_t *DRB_list_NB_IoT, @@ -249,8 +252,8 @@ do_RRCConnectionReject_NB_IoT( @param transaction_id Transaction index @returns Size of encoded bit stream in bytes*/ -uint8_t do_RRCConnectionRelease_NB_IoT(uint8_t Mod_id, uint8_t *buffer,int Transaction_id); - +uint8_t do_RRCConnectionRelease_NB_IoT(uint8_t Mod_id, uint8_t *buffer, size_t buffer_size, + int Transaction_id); uint8_t do_DLInformationTransfer_NB_IoT( uint8_t Mod_id, @@ -273,7 +276,8 @@ uint8_t do_DLInformationTransfer_NB_IoT( uint8_t do_RRCConnectionReestablishment_NB_IoT( uint8_t Mod_id, - uint8_t* const buffer, + uint8_t* buffer, + size_t buffer_size, const uint8_t Transaction_id, const NB_IoT_DL_FRAME_PARMS* const frame_parms, //to be changed SRB_ToAddModList_NB_r13_t** SRB_configList_NB_IoT diff --git a/openair2/RRC/LTE/defs_NB_IoT.h b/openair2/RRC/LTE/defs_NB_IoT.h index 3907d2321d..37a26086b5 100644 --- a/openair2/RRC/LTE/defs_NB_IoT.h +++ b/openair2/RRC/LTE/defs_NB_IoT.h @@ -148,7 +148,7 @@ typedef struct UE_RRC_INFO_NB_IoT_s { //Measurement Report not supported in NB-IoT #define PAYLOAD_SIZE_MAX 1024 -#define RRC_BUF_SIZE 8192 +#define RRC_BUF_SIZE 512 #define UNDEF_SECURITY_MODE 0xff #define NO_SECURITY_MODE 0x20 diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c index 4b862fa11d..d0b89abb51 100644 --- a/openair2/RRC/LTE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -75,7 +75,7 @@ #include #include "intertask_interface.h" - +#include "targets/RT/USER/lte-softmodem.h" #include "SIMULATION/TOOLS/sim.h" // for taus @@ -92,8 +92,10 @@ //for D2D int ctrl_sock_fd; -#define BUFSIZE 1024 struct sockaddr_in prose_app_addr; +static const char nsa_ipaddr[] = "127.0.0.1"; +static int from_nr_ue_fd = -1; +static int to_nr_ue_fd = -1; int slrb_id; int send_ue_information = 0; @@ -123,6 +125,26 @@ 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; +} rrc_dcch_data_copy_t; + +typedef struct rrc_nrue_cap_info_t +{ + uint8_t mesg[RRC_BUF_SIZE]; + size_t mesg_len; + LTE_DL_DCCH_Message_t *dl_dcch_msg; +} rrc_nrue_cap_info_t; + +static void rrc_ue_process_ueCapabilityEnquiry(const protocol_ctxt_t *const ctxt_pP, + LTE_UECapabilityEnquiry_t *UECapabilityEnquiry, + uint8_t eNB_index); + +static void rrc_ue_process_nrueCapabilityEnquiry(const protocol_ctxt_t *const ctxt_pP, + LTE_UECapabilityEnquiry_t *UECapabilityEnquiry, + rrc_nrue_cap_info_t *nrue_cap_info, + uint8_t eNB_index); /** \brief Generates/Encodes RRCConnnectionSetupComplete message at UE * \param ctxt_pP Running context @@ -141,10 +163,15 @@ static void rrc_ue_generate_RRCConnectionSetupComplete( * \param eNB_index Index of corresponding eNB/CH * \param Transaction_id RRC transaction identifier */ -static void rrc_ue_generate_RRCConnectionReconfigurationComplete( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, const uint8_t Transaction_id ); +static void rrc_ue_generate_RRCConnectionReconfigurationComplete(const protocol_ctxt_t *const ctxt_pP, + const uint8_t eNB_index, + const uint8_t Transaction_id, + OCTET_STRING_t *str); static void rrc_ue_generate_MeasurementReport(protocol_ctxt_t *const ctxt_pP, uint8_t eNB_index ); +static void rrc_ue_generate_nrMeasurementReport(protocol_ctxt_t *const ctxt_pP, uint8_t eNB_index ); + static uint8_t check_trigger_meas_event( module_id_t module_idP, frame_t frameP, @@ -166,7 +193,9 @@ rrc_ue_process_MBMSCountingRequest( LTE_MBMSCountingRequest_r10_t *MBMSCountingRequest, uint8_t eNB_index ); - + +static void process_nr_nsa_msg(nsa_msg_t *msg, int msg_len); +static void nsa_sendmsg_to_nrue(const void *message, size_t msg_len, Rrc_Msg_Type_t msg_type); protocol_ctxt_t ctxt_pP_local; @@ -399,12 +428,12 @@ char openair_rrc_ue_init( const module_id_t ue_mod_idP, const unsigned char eNB_ //----------------------------------------------------------------------------- void rrc_ue_generate_RRCConnectionRequest( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index ) { - uint8_t i=0,rv[6]; + uint8_t rv[6]; if(UE_rrc_inst[ctxt_pP->module_id].Srb0[eNB_index].Tx_buffer.payload_size ==0) { // Get RRCConnectionRequest, fill random for now // Generate random byte stream for contention resolution - for (i=0; i<6; i++) { + for (int i=0; i<6; i++) { #ifdef SMBV // if SMBV is configured the contention resolution needs to be fix for the connection procedure to succeed rv[i]=i; @@ -419,12 +448,13 @@ void rrc_ue_generate_RRCConnectionRequest( const protocol_ctxt_t *const ctxt_pP, do_RRCConnectionRequest( ctxt_pP->module_id, (uint8_t *)UE_rrc_inst[ctxt_pP->module_id].Srb0[eNB_index].Tx_buffer.Payload, + sizeof(UE_rrc_inst[ctxt_pP->module_id].Srb0[eNB_index].Tx_buffer.Payload), rv); LOG_I(RRC,"[UE %d] : Frame %d, Logical Channel UL-CCCH (SRB0), Generating RRCConnectionRequest (bytes %d, eNB %d)\n", ctxt_pP->module_id, ctxt_pP->frame, UE_rrc_inst[ctxt_pP->module_id].Srb0[eNB_index].Tx_buffer.payload_size, eNB_index); - for (i=0; imodule_id].Srb0[eNB_index].Tx_buffer.payload_size; i++) { - LOG_T(RRC,"%x.",UE_rrc_inst[ctxt_pP->module_id].Srb0[eNB_index].Tx_buffer.Payload[i]); + for (int i=0; imodule_id].Srb0[eNB_index].Tx_buffer.payload_size; i++) { + LOG_T(RRC,"%x.\n",UE_rrc_inst[ctxt_pP->module_id].Srb0[eNB_index].Tx_buffer.Payload[i]); } LOG_T(RRC,"\n"); @@ -529,13 +559,16 @@ static void rrc_ue_generate_RRCConnectionSetupComplete( } //----------------------------------------------------------------------------- -void rrc_ue_generate_RRCConnectionReconfigurationComplete( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, const uint8_t Transaction_id ) { - uint8_t buffer[32], size; - size = do_RRCConnectionReconfigurationComplete(ctxt_pP, buffer, Transaction_id); - LOG_I(RRC,PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel UL-DCCH (SRB1), Generating RRCConnectionReconfigurationComplete (bytes %d, eNB_index %d)\n", +void rrc_ue_generate_RRCConnectionReconfigurationComplete(const protocol_ctxt_t *const ctxt_pP, + const uint8_t eNB_index, + const uint8_t Transaction_id, + OCTET_STRING_t *str) { + uint8_t buffer[RRC_BUF_SIZE]; + size_t size = do_RRCConnectionReconfigurationComplete(ctxt_pP, buffer, sizeof(buffer), Transaction_id, str); + LOG_I(RRC,PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel UL-DCCH (SRB1), Generating RRCConnectionReconfigurationComplete (bytes %zu, eNB_index %d)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), size, eNB_index); LOG_D(RLC, - "[FRAME %05d][RRC_UE][INST %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCConnectionReconfigurationComplete to eNB %d MUI %d) --->][PDCP][INST %02d][RB %02d]\n", + "[FRAME %05d][RRC_UE][INST %02d][][--- PDCP_DATA_REQ/%zu Bytes (RRCConnectionReconfigurationComplete to eNB %d MUI %d) --->][PDCP][INST %02d][RB %02d]\n", ctxt_pP->frame, UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), size, @@ -614,7 +647,7 @@ int rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const SRB_INFO *co break; case LTE_DL_CCCH_MessageType__c1_PR_rrcConnectionSetup: - LOG_I(RRC, + LOG_A(RRC, "[UE%d][RAPROC] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCConnectionSetup RNTI %x\n", ctxt_pP->module_id, ctxt_pP->frame, @@ -761,38 +794,60 @@ rrc_ue_process_measConfig( int i; long ind; LTE_MeasObjectToAddMod_t *measObj; + UE_RRC_INST *ue = &UE_rrc_inst[ctxt_pP->module_id]; if (measConfig->measObjectToRemoveList != NULL) { - for (i=0; imeasObjectToRemoveList->list.count; i++) { - ind = *measConfig->measObjectToRemoveList->list.array[i]; - free(UE_rrc_inst[ctxt_pP->module_id].MeasObj[eNB_index][ind-1]); + for (i = 0; i < measConfig->measObjectToRemoveList->list.count; i++) { + ind = *measConfig->measObjectToRemoveList->list.array[i]; + free(ue->MeasObj[eNB_index][ind-1]); + ue->MeasObj[eNB_index][ind-1] = NULL; } } if (measConfig->measObjectToAddModList != NULL) { - LOG_D(RRC,"Measurement Object List is present\n"); + LOG_I(RRC,"Measurement Object List is present\n"); - for (i=0; imeasObjectToAddModList->list.count; i++) { + for (i = 0; i < measConfig->measObjectToAddModList->list.count; i++) { measObj = measConfig->measObjectToAddModList->list.array[i]; - ind = measConfig->measObjectToAddModList->list.array[i]->measObjectId; - - if (UE_rrc_inst[ctxt_pP->module_id].MeasObj[eNB_index][ind-1]) { - LOG_D(RRC,"Modifying measurement object %ld\n",ind); - memcpy((char *)UE_rrc_inst[ctxt_pP->module_id].MeasObj[eNB_index][ind-1], + ind = measConfig->measObjectToAddModList->list.array[i]->measObjectId; + AssertFatal(ind > 0 && ind <= MAX_MEAS_OBJ && eNB_index >= 0 && eNB_index < NB_CNX_UE, + "measObjectId is out of bounds. ind = %ld, eNB_index = %d, i = %d.\n", ind, eNB_index, i); + if (ue->MeasObj[eNB_index][ind-1]) { + LOG_D(RRC, "Modifying measurement object [%d][%ld]\n", eNB_index, ind); + memcpy((char *)ue->MeasObj[eNB_index][ind-1], (char *)measObj, sizeof(LTE_MeasObjectToAddMod_t)); } else { - LOG_I(RRC,"Adding measurement object %ld\n",ind); - - if (measObj->measObject.present == LTE_MeasObjectToAddMod__measObject_PR_measObjectEUTRA) { - LOG_I(RRC,"EUTRA Measurement : carrierFreq %ld, allowedMeasBandwidth %ld,presenceAntennaPort1 %d, neighCellConfig %d\n", - measObj->measObject.choice.measObjectEUTRA.carrierFreq, - measObj->measObject.choice.measObjectEUTRA.allowedMeasBandwidth, - measObj->measObject.choice.measObjectEUTRA.presenceAntennaPort1, - measObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf[0]); - UE_rrc_inst[ctxt_pP->module_id].MeasObj[eNB_index][ind-1]=measObj; + if (measObj->measObject.present == LTE_MeasObjectToAddMod__measObject_PR_measObjectEUTRA) { + LOG_I(RRC,"EUTRA Measurement : carrierFreq %ld, allowedMeasBandwidth %ld,presenceAntennaPort1 %d, neighCellConfig %d\n", + measObj->measObject.choice.measObjectEUTRA.carrierFreq, + measObj->measObject.choice.measObjectEUTRA.allowedMeasBandwidth, + measObj->measObject.choice.measObjectEUTRA.presenceAntennaPort1, + measObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf[0]); + } else if (measObj->measObject.present == LTE_MeasObjectToAddMod__measObject_PR_measObjectNR_r15) { + ue->subframeCount = 0; + LOG_I(RRC, "NR_r15 Measurement: carrierFreq: %ld\n", + measObj->measObject.choice.measObjectNR_r15.carrierFreq_r15); + if (!get_softmodem_params()->nsa) { + LOG_E(RRC, "Not in NSA mode but attempting to send measurement request to NR-UE\n"); + return; + } + uint8_t buffer[RRC_BUF_SIZE]; + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_MeasObjectToAddMod, + NULL, + measObj, + buffer, + sizeof(buffer)); + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %zu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + nsa_sendmsg_to_nrue(buffer, (enc_rval.encoded + 7)/8, RRC_MEASUREMENT_PROCEDURE); + LOG_A(RRC, "Encoded measurement object %zu bits (%zu bytes) and sent to NR UE\n", + enc_rval.encoded, (enc_rval.encoded + 7)/8); + } + LOG_D(RRC, "Adding measurement object [%d][%ld]\n", eNB_index, ind); + ue->MeasObj[eNB_index][ind-1]=measObj; } - } + measConfig->measObjectToAddModList->list.array[i] = NULL; } LOG_I(RRC,"call rrc_mac_config_req \n"); @@ -800,7 +855,7 @@ rrc_ue_process_measConfig( (LTE_RadioResourceConfigCommonSIB_t *)NULL, (struct LTE_PhysicalConfigDedicated *)NULL, (LTE_SCellToAddMod_r10_t *)NULL, - UE_rrc_inst[ctxt_pP->module_id].MeasObj[eNB_index], + ue->MeasObj[eNB_index], (LTE_MAC_MainConfig_t *)NULL, 0, (struct LTE_LogicalChannelConfig *)NULL, @@ -828,109 +883,120 @@ rrc_ue_process_measConfig( if (measConfig->reportConfigToRemoveList != NULL) { for (i=0; ireportConfigToRemoveList->list.count; i++) { ind = *measConfig->reportConfigToRemoveList->list.array[i]; - free(UE_rrc_inst[ctxt_pP->module_id].ReportConfig[eNB_index][ind-1]); + free(ue->ReportConfig[eNB_index][ind-1]); + ue->ReportConfig[eNB_index][ind-1] = NULL; } } if (measConfig->reportConfigToAddModList != NULL) { LOG_I(RRC,"Report Configuration List is present\n"); - for (i=0; ireportConfigToAddModList->list.count; i++) { - ind = measConfig->reportConfigToAddModList->list.array[i]->reportConfigId; - - if (UE_rrc_inst[ctxt_pP->module_id].ReportConfig[eNB_index][ind-1]) { - LOG_I(RRC,"Modifying Report Configuration %ld\n",ind-1); - memcpy((char *)UE_rrc_inst[ctxt_pP->module_id].ReportConfig[eNB_index][ind-1], + for (i=0; i < measConfig->reportConfigToAddModList->list.count; i++) { + ind = measConfig->reportConfigToAddModList->list.array[i]->reportConfigId; + AssertFatal(ind > 0 && ind <= MAX_MEAS_CONFIG && eNB_index >= 0 && eNB_index < NB_CNX_UE, + "ReportConfigId is out of bounds. ind = %ld, eNB_index = %d, i = %d.\n", ind, eNB_index, i); + if (ue->ReportConfig[eNB_index][ind-1]) { + LOG_D(RRC,"Modifying ReportConfig [%d][%ld]\n", eNB_index, ind-1); + memcpy((char *)ue->ReportConfig[eNB_index][ind-1], (char *)measConfig->reportConfigToAddModList->list.array[i], sizeof(LTE_ReportConfigToAddMod_t)); } else { - LOG_D(RRC,"Adding Report Configuration %ld %p \n",ind-1,measConfig->reportConfigToAddModList->list.array[i]); - UE_rrc_inst[ctxt_pP->module_id].ReportConfig[eNB_index][ind-1] = measConfig->reportConfigToAddModList->list.array[i]; + LOG_D(RRC,"Adding ReportConfig [%d][%ld]\n", eNB_index, ind-1); + ue->ReportConfig[eNB_index][ind-1] = measConfig->reportConfigToAddModList->list.array[i]; } + measConfig->reportConfigToAddModList->list.array[i] = NULL; } } if (measConfig->quantityConfig != NULL) { - if (UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index]) { + if (ue->QuantityConfig[eNB_index]) { LOG_D(RRC,"Modifying Quantity Configuration \n"); - memcpy((char *)UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index], + memcpy((char *)ue->QuantityConfig[eNB_index], (char *)measConfig->quantityConfig, sizeof(LTE_QuantityConfig_t)); } else { LOG_D(RRC,"Adding Quantity configuration\n"); - UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index] = measConfig->quantityConfig; + ue->QuantityConfig[eNB_index] = measConfig->quantityConfig; } + measConfig->quantityConfig = NULL; } if (measConfig->measIdToRemoveList != NULL) { for (i=0; imeasIdToRemoveList->list.count; i++) { ind = *measConfig->measIdToRemoveList->list.array[i]; - free(UE_rrc_inst[ctxt_pP->module_id].MeasId[eNB_index][ind-1]); + free(ue->MeasId[eNB_index][ind-1]); + ue->MeasId[eNB_index][ind-1] = NULL; } } if (measConfig->measIdToAddModList != NULL) { for (i=0; imeasIdToAddModList->list.count; i++) { ind = measConfig->measIdToAddModList->list.array[i]->measId; - - if (UE_rrc_inst[ctxt_pP->module_id].MeasId[eNB_index][ind-1]) { - LOG_D(RRC,"Modifying Measurement ID %ld\n",ind-1); - memcpy((char *)UE_rrc_inst[ctxt_pP->module_id].MeasId[eNB_index][ind-1], + AssertFatal(ind > 0 && ind <= MAX_MEAS_ID && eNB_index >= 0 && eNB_index < NB_CNX_UE, + "measId is out of bounds. ind = %ld, eNB_index = %d, i = %d.\n", ind, eNB_index, i); + if (ue->MeasId[eNB_index][ind-1]) { + LOG_I(RRC,"Modifying Measurement ID [%d][%ld]\n", eNB_index, ind-1); + memcpy((char *)ue->MeasId[eNB_index][ind-1], (char *)measConfig->measIdToAddModList->list.array[i], sizeof(LTE_MeasIdToAddMod_t)); } else { - LOG_D(RRC,"Adding Measurement ID %ld %p\n",ind-1,measConfig->measIdToAddModList->list.array[i]); - UE_rrc_inst[ctxt_pP->module_id].MeasId[eNB_index][ind-1] = measConfig->measIdToAddModList->list.array[i]; + LOG_I(RRC,"Adding Measurement ID [%d][%ld]\n", eNB_index, ind-1); + ue->MeasId[eNB_index][ind-1] = measConfig->measIdToAddModList->list.array[i]; } + measConfig->measIdToAddModList->list.array[i] = NULL; } } if (measConfig->measGapConfig !=NULL) { - if (UE_rrc_inst[ctxt_pP->module_id].measGapConfig[eNB_index]) { - memcpy((char *)UE_rrc_inst[ctxt_pP->module_id].measGapConfig[eNB_index], + if (ue->measGapConfig[eNB_index]) { + memcpy((char *)ue->measGapConfig[eNB_index], (char *)measConfig->measGapConfig, sizeof(LTE_MeasGapConfig_t)); } else { - UE_rrc_inst[ctxt_pP->module_id].measGapConfig[eNB_index] = measConfig->measGapConfig; + ue->measGapConfig[eNB_index] = measConfig->measGapConfig; } + measConfig->measGapConfig = NULL; } if (measConfig->quantityConfig != NULL) { - if (UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index]) { + if (ue->QuantityConfig[eNB_index]) { LOG_I(RRC,"Modifying Quantity Configuration \n"); - memcpy((char *)UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index], + memcpy((char *)ue->QuantityConfig[eNB_index], (char *)measConfig->quantityConfig, sizeof(LTE_QuantityConfig_t)); } else { LOG_I(RRC,"Adding Quantity configuration\n"); - UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index] = measConfig->quantityConfig; + ue->QuantityConfig[eNB_index] = measConfig->quantityConfig; } + measConfig->quantityConfig = NULL; - UE_rrc_inst[ctxt_pP->module_id].filter_coeff_rsrp = 1./pow(2, - (*UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index]->quantityConfigEUTRA->filterCoefficientRSRP)/4); - UE_rrc_inst[ctxt_pP->module_id].filter_coeff_rsrq = 1./pow(2, - (*UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index]->quantityConfigEUTRA->filterCoefficientRSRQ)/4); + ue->filter_coeff_rsrp = 1./pow(2, + (*ue->QuantityConfig[eNB_index]->quantityConfigEUTRA->filterCoefficientRSRP)/4); + ue->filter_coeff_rsrq = 1./pow(2, + (*ue->QuantityConfig[eNB_index]->quantityConfigEUTRA->filterCoefficientRSRQ)/4); LOG_I(RRC,"[UE %d] set rsrp-coeff for eNB %d: %ld rsrq-coeff: %ld rsrp_factor: %f rsrq_factor: %f \n", ctxt_pP->module_id, eNB_index, // UE_rrc_inst[ue_mod_idP].Info[eNB_index].UE_index, - *UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index]->quantityConfigEUTRA->filterCoefficientRSRP, - *UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index]->quantityConfigEUTRA->filterCoefficientRSRQ, - UE_rrc_inst[ctxt_pP->module_id].filter_coeff_rsrp, - UE_rrc_inst[ctxt_pP->module_id].filter_coeff_rsrq); + *ue->QuantityConfig[eNB_index]->quantityConfigEUTRA->filterCoefficientRSRP, + *ue->QuantityConfig[eNB_index]->quantityConfigEUTRA->filterCoefficientRSRQ, + ue->filter_coeff_rsrp, + ue->filter_coeff_rsrq); } if (measConfig->s_Measure != NULL) { - UE_rrc_inst[ctxt_pP->module_id].s_measure = *measConfig->s_Measure; + ue->s_measure = *measConfig->s_Measure; } + measConfig->s_Measure = NULL; if (measConfig->speedStatePars != NULL) { - if (UE_rrc_inst[ctxt_pP->module_id].speedStatePars) { - memcpy((char *)UE_rrc_inst[ctxt_pP->module_id].speedStatePars,(char *)measConfig->speedStatePars,sizeof(struct LTE_MeasConfig__speedStatePars)); + if (ue->speedStatePars) { + memcpy((char *)ue->speedStatePars,(char *)measConfig->speedStatePars,sizeof(struct LTE_MeasConfig__speedStatePars)); } else { - UE_rrc_inst[ctxt_pP->module_id].speedStatePars = measConfig->speedStatePars; + ue->speedStatePars = measConfig->speedStatePars; } + measConfig->speedStatePars = NULL; LOG_I(RRC,"[UE %d] Configuring mobility optimization params for UE %d \n", - ctxt_pP->module_id,UE_rrc_inst[ctxt_pP->module_id].Info[0].UE_index); + ctxt_pP->module_id,ue->Info[0].UE_index); } } @@ -1141,6 +1207,7 @@ rrc_ue_process_radioResourceConfigDedicated( LOG_I(RRC,"Init physicalConfigDedicated UE_rrc_inst to radioResourceConfigDedicated->physicalConfigDedicated\n"); UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index] = radioResourceConfigDedicated->physicalConfigDedicated; } + radioResourceConfigDedicated->physicalConfigDedicated = NULL; } // Apply macMainConfig if present @@ -1163,6 +1230,7 @@ rrc_ue_process_radioResourceConfigDedicated( } else { UE_rrc_inst[ctxt_pP->module_id].sps_Config[eNB_index] = radioResourceConfigDedicated->sps_Config; } + radioResourceConfigDedicated->sps_Config = NULL; } // Establish SRBs if present @@ -1211,7 +1279,7 @@ rrc_ue_process_radioResourceConfigDedicated( } else { UE_rrc_inst[ctxt_pP->module_id].SRB1_config[eNB_index] = radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt]; rrc_ue_establish_srb1(ctxt_pP->module_id,ctxt_pP->frame,eNB_index,radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt]); - + radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt] = NULL; if (UE_rrc_inst[ctxt_pP->module_id].SRB1_config[eNB_index]->logicalChannelConfig) { if (UE_rrc_inst[ctxt_pP->module_id].SRB1_config[eNB_index]->logicalChannelConfig->present == LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) { SRB1_logicalChannelConfig = &UE_rrc_inst[ctxt_pP->module_id].SRB1_config[eNB_index]->logicalChannelConfig->choice.explicitValue; @@ -1259,7 +1327,7 @@ rrc_ue_process_radioResourceConfigDedicated( } else { UE_rrc_inst[ctxt_pP->module_id].SRB2_config[eNB_index] = radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt]; rrc_ue_establish_srb2(ctxt_pP->module_id,ctxt_pP->frame,eNB_index,radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt]); - + radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt] = NULL; if (UE_rrc_inst[ctxt_pP->module_id].SRB2_config[eNB_index]->logicalChannelConfig) { if (UE_rrc_inst[ctxt_pP->module_id].SRB2_config[eNB_index]->logicalChannelConfig->present == LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) { LOG_I(RRC,"Applying Explicit SRB2 logicalChannelConfig\n"); @@ -1368,6 +1436,7 @@ rrc_ue_process_radioResourceConfigDedicated( radioResourceConfigDedicated->drb_ToAddModList->list.array[i]->drb_Identity, eNB_index, ctxt_pP->module_id); + radioResourceConfigDedicated->drb_ToAddModList->list.array[i] = NULL; rrc_mac_config_req_ue(ctxt_pP->module_id,0,eNB_index, (LTE_RadioResourceConfigCommonSIB_t *)NULL, UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index], @@ -1629,6 +1698,101 @@ rrc_ue_process_MBMSCountingRequest( } +//----------------------------------------------------------------------------- +void +rrc_ue_process_nrueCapabilityEnquiry( + const protocol_ctxt_t *const ctxt_pP, + LTE_UECapabilityEnquiry_t *UECapabilityEnquiry, + rrc_nrue_cap_info_t *nrue_cap_info, + uint8_t eNB_index +) +//----------------------------------------------------------------------------- +{ + asn_enc_rval_t enc_rval; + uint8_t buffer[RRC_BUF_SIZE]; + LOG_I(RRC,"[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), Processing NRUECapabilityEnquiry (eNB %d)\n", + ctxt_pP->module_id, + ctxt_pP->frame, + eNB_index); + LTE_UL_DCCH_Message_t ul_dcch_msg; + memset(&ul_dcch_msg, 0, sizeof(ul_dcch_msg)); + LTE_UECapabilityInformation_t *ue_cap = &ul_dcch_msg.message.choice.c1.choice.ueCapabilityInformation; + ul_dcch_msg.message.present = LTE_UL_DCCH_MessageType_PR_c1; + ul_dcch_msg.message.choice.c1.present = LTE_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation; + ue_cap->rrc_TransactionIdentifier = UECapabilityEnquiry->rrc_TransactionIdentifier; + + NR_UE_CapabilityRAT_Container_t ue_CapabilityRAT_Container; + memset(&ue_CapabilityRAT_Container, 0, sizeof(ue_CapabilityRAT_Container)); + ue_CapabilityRAT_Container.rat_Type = NR_RAT_Type_nr; + OCTET_STRING_fromBuf(&ue_CapabilityRAT_Container.ue_CapabilityRAT_Container, + (const char *)nrue_cap_info->mesg, + nrue_cap_info->mesg_len); + # if(1) // TODO: The MRDC capabilites should be filled in the NR UE + NR_UE_CapabilityRAT_Container_t ue_CapabilityRAT_Container_mrdc; + memset(&ue_CapabilityRAT_Container_mrdc, 0, sizeof(ue_CapabilityRAT_Container_mrdc)); + uint8_t buffer_mrdc[RRC_BUF_SIZE]; + NR_UE_MRDC_Capability_t *UE_Capability_MRDC = CALLOC(1, sizeof(NR_UE_MRDC_Capability_t)); + asn_enc_rval_t enc_rval_mrdc = uper_encode_to_buffer(&asn_DEF_NR_UE_MRDC_Capability, + NULL, + (void *)UE_Capability_MRDC, + &buffer_mrdc, + sizeof(buffer_mrdc)); + AssertFatal (enc_rval_mrdc.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval_mrdc.failed_type->name, enc_rval_mrdc.encoded); + LOG_I(RRC, "[NR_RRC] NRUE MRDC Capability encoded, %ld bytes (%ld bits)\n", + (enc_rval_mrdc.encoded + 7) / 8, enc_rval_mrdc.encoded + 7); + + ue_CapabilityRAT_Container_mrdc.rat_Type = NR_RAT_Type_eutra_nr; + OCTET_STRING_fromBuf(&ue_CapabilityRAT_Container_mrdc.ue_CapabilityRAT_Container, + (const char *)buffer_mrdc, + (enc_rval_mrdc.encoded + 7) / 8); + #endif + + ue_cap->criticalExtensions.present = LTE_UECapabilityInformation__criticalExtensions_PR_c1; + ue_cap->criticalExtensions.choice.c1.present = LTE_UECapabilityInformation__criticalExtensions__c1_PR_ueCapabilityInformation_r8; + ue_cap->criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.count = 0; + int count = UECapabilityEnquiry->criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list.count; + xer_fprint(stdout, &asn_DEF_NR_UE_CapabilityRAT_Container, (void *)&ue_CapabilityRAT_Container); + LTE_UE_CapabilityRequest_t *cap_req = &UECapabilityEnquiry->criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest; + for (int i = 0; i < count; i++) { + enc_rval.encoded = 0; + if (*cap_req->list.array[i] == LTE_RAT_Type_nr) { + ASN_SEQUENCE_ADD(&ue_cap->criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list, + &ue_CapabilityRAT_Container); + ue_cap->criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.array[i]->rat_Type = LTE_RAT_Type_nr; + asn_enc_rval_t enc_rval_nr = uper_encode_to_buffer(&asn_DEF_LTE_UL_DCCH_Message, NULL, (void *) &ul_dcch_msg, buffer, sizeof(buffer)); + AssertFatal (enc_rval_nr.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", + enc_rval_nr.failed_type->name, enc_rval_nr.encoded); + enc_rval.encoded = enc_rval.encoded + enc_rval_nr.encoded; + xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)&ul_dcch_msg); + LOG_A(RRC, "%s: NR_UECapInfo LTE_RAT_Type_nr Encoded %zd bits (%zd bytes)\n", + __FUNCTION__, enc_rval.encoded, (enc_rval.encoded+7)/8); + } + else if (*cap_req->list.array[i] == LTE_RAT_Type_eutra_nr) { + ASN_SEQUENCE_ADD(&ue_cap->criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list, + &ue_CapabilityRAT_Container_mrdc); + ue_cap->criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.array[i]->rat_Type = LTE_RAT_Type_eutra_nr; + asn_enc_rval_t enc_rval_eutra_nr = uper_encode_to_buffer(&asn_DEF_LTE_UL_DCCH_Message, NULL, (void *) &ul_dcch_msg, buffer, sizeof(buffer)); + AssertFatal (enc_rval_eutra_nr.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", + enc_rval_eutra_nr.failed_type->name, enc_rval_eutra_nr.encoded); + enc_rval.encoded = enc_rval.encoded + enc_rval_eutra_nr.encoded; + xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)&ul_dcch_msg); + LOG_A(RRC, "%s: NR_UECapInfo LTE_RAT_Type_eutra_nr Encoded %zd bits (%zd bytes)\n", + __FUNCTION__, enc_rval.encoded, (enc_rval.encoded+7)/8); + } + rrc_data_req_ue ( + ctxt_pP, + DCCH, + rrc_mui++, + SDU_CONFIRM_NO, + (enc_rval.encoded + 7) / 8, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); + } +} + + + //----------------------------------------------------------------------------- void rrc_ue_process_ueCapabilityEnquiry( @@ -1686,7 +1850,8 @@ rrc_ue_process_ueCapabilityEnquiry( xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)&ul_dcch_msg); } - LOG_I(RRC,"UECapabilityInformation Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); + LOG_A(RRC, "%s: UECapabilityInformation Encoded %zd bits (%zd bytes)\n", + __FUNCTION__, enc_rval.encoded,(enc_rval.encoded+7)/8); rrc_data_req_ue ( ctxt_pP, DCCH, @@ -1696,9 +1861,57 @@ rrc_ue_process_ueCapabilityEnquiry( buffer, PDCP_TRANSMISSION_MODE_CONTROL); } + else if (*UECapabilityEnquiry->criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list.array[i] + == LTE_RAT_Type_nr) { + ASN_SEQUENCE_ADD( + &ul_dcch_msg.message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list, + &ue_CapabilityRAT_Container); + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_UL_DCCH_Message, NULL, (void *) &ul_dcch_msg, buffer, 100); + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)&ul_dcch_msg); + } + + LOG_A(RRC, "%s: NR_UECapabilityInformation Encoded %zd bits (%zd bytes)\n", + __FUNCTION__, enc_rval.encoded,(enc_rval.encoded+7)/8); + rrc_data_req_ue ( + ctxt_pP, + DCCH, + rrc_mui++, + SDU_CONFIRM_NO, + (enc_rval.encoded + 7) / 8, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); + } } } +static bool is_nr_r15_config_present(LTE_RRCConnectionReconfiguration_r8_IEs_t *c) +{ +#define NCE nonCriticalExtension +#define chk(x) do { \ + if ((x) == NULL) { \ + LOG_I(RRC, "NULL at %d\n", __LINE__); \ + return false; \ + } \ +} while(0) + chk(c); + chk(c->NCE); + chk(c->NCE->NCE); + chk(c->NCE->NCE->NCE); + chk(c->NCE->NCE->NCE->NCE); + chk(c->NCE->NCE->NCE->NCE->NCE); + chk(c->NCE->NCE->NCE->NCE->NCE->NCE); + chk(c->NCE->NCE->NCE->NCE->NCE->NCE->NCE); + chk(c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE); + return c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->nr_Config_r15->present == + LTE_RRCConnectionReconfiguration_v1510_IEs__nr_Config_r15_PR_setup; + +#undef NCE +#undef chk +} //----------------------------------------------------------------------------- void @@ -1712,53 +1925,89 @@ rrc_ue_process_rrcConnectionReconfiguration( LOG_I(RRC,"[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), Processing RRCConnectionReconfiguration (eNB %d)\n", ctxt_pP->module_id,ctxt_pP->frame,eNB_index); - if (rrcConnectionReconfiguration->criticalExtensions.present == LTE_RRCConnectionReconfiguration__criticalExtensions_PR_c1) { + if (rrcConnectionReconfiguration->criticalExtensions.present == + LTE_RRCConnectionReconfiguration__criticalExtensions_PR_c1) { if (rrcConnectionReconfiguration->criticalExtensions.choice.c1.present == LTE_RRCConnectionReconfiguration__criticalExtensions__c1_PR_rrcConnectionReconfiguration_r8) { - LTE_RRCConnectionReconfiguration_r8_IEs_t *rrcConnectionReconfiguration_r8 = - &rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8; + LTE_RRCConnectionReconfiguration_r8_IEs_t *r_r8 = &rrcConnectionReconfiguration-> + criticalExtensions.choice.c1. + choice.rrcConnectionReconfiguration_r8; - if (rrcConnectionReconfiguration_r8->mobilityControlInfo) { + if (is_nr_r15_config_present(r_r8)) { + OCTET_STRING_t *nr_RadioBearer = r_r8->nonCriticalExtension->nonCriticalExtension-> + nonCriticalExtension->nonCriticalExtension->nonCriticalExtension-> + nonCriticalExtension->nonCriticalExtension->nonCriticalExtension-> + nr_RadioBearerConfig1_r15; + OCTET_STRING_t *nr_SecondaryCellGroup = r_r8->nonCriticalExtension->nonCriticalExtension-> + nonCriticalExtension->nonCriticalExtension->nonCriticalExtension-> + nonCriticalExtension->nonCriticalExtension->nonCriticalExtension-> + nr_Config_r15->choice.setup.nr_SecondaryCellGroupConfig_r15; + uint32_t total_size = nr_RadioBearer->size + nr_SecondaryCellGroup->size; + struct msg { + uint32_t RadioBearer_size; + uint32_t SecondaryCellGroup_size; + uint8_t trans_id; + uint8_t padding[3]; + uint8_t buffer[total_size]; + } msg; + + msg.RadioBearer_size = nr_RadioBearer->size; + msg.SecondaryCellGroup_size = nr_SecondaryCellGroup->size; + msg.trans_id = rrcConnectionReconfiguration->rrc_TransactionIdentifier; + memcpy(msg.buffer, nr_RadioBearer->buf, nr_RadioBearer->size); + memcpy(msg.buffer + nr_RadioBearer->size, nr_SecondaryCellGroup->buf, nr_SecondaryCellGroup->size); + + LOG_D(RRC, "nr_RadioBearerConfig1_r15 size %ld nr_SecondaryCellGroupConfig_r15 size %ld, sizeof(msg) = %zu\n", + nr_RadioBearer->size, + nr_SecondaryCellGroup->size, + sizeof(msg)); + + nsa_sendmsg_to_nrue(&msg, sizeof(msg), RRC_CONFIG_COMPLETE_REQ); + LOG_A(RRC, "Sent RRC_CONFIG_COMPLETE_REQ to the NR UE\n"); + } + + if (r_r8->mobilityControlInfo) { LOG_I(RRC,"Mobility Control Information is present\n"); rrc_ue_process_mobilityControlInfo( ctxt_pP, eNB_index, - rrcConnectionReconfiguration_r8->mobilityControlInfo); + r_r8->mobilityControlInfo); } - if (rrcConnectionReconfiguration_r8->measConfig != NULL) { + if (r_r8->measConfig != NULL) { LOG_I(RRC,"Measurement Configuration is present\n"); rrc_ue_process_measConfig(ctxt_pP, eNB_index, - rrcConnectionReconfiguration_r8->measConfig); + r_r8->measConfig); + r_r8->measConfig = NULL; } - if (rrcConnectionReconfiguration_r8->radioResourceConfigDedicated) { + if (r_r8->radioResourceConfigDedicated) { LOG_I(RRC,"Radio Resource Configuration is present\n"); - rrc_ue_process_radioResourceConfigDedicated(ctxt_pP,eNB_index, rrcConnectionReconfiguration_r8->radioResourceConfigDedicated); + rrc_ue_process_radioResourceConfigDedicated(ctxt_pP, + eNB_index, + r_r8->radioResourceConfigDedicated); + r_r8->radioResourceConfigDedicated = NULL; } //TTN for D2D //if RRCConnectionReconfiguration message includes the sl-CommConfig - if ((rrcConnectionReconfiguration_r8->nonCriticalExtension != NULL) - && (rrcConnectionReconfiguration_r8->nonCriticalExtension->nonCriticalExtension + if ((r_r8->nonCriticalExtension != NULL) + && (r_r8->nonCriticalExtension->nonCriticalExtension != NULL) + && (r_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension != NULL) + && (r_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension != NULL) + && (r_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension != NULL) - && (rrcConnectionReconfiguration_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension - != NULL) - && (rrcConnectionReconfiguration_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension - != NULL) - && (rrcConnectionReconfiguration_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension - != NULL) - && (rrcConnectionReconfiguration_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_CommConfig_r12 + && (r_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_CommConfig_r12 != NULL)) { - if (rrcConnectionReconfiguration_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_CommConfig_r12->commTxResources_r12->present != + if (r_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_CommConfig_r12->commTxResources_r12->present != LTE_SL_CommConfig_r12__commTxResources_r12_PR_NOTHING) { LOG_I(RRC,"sl-CommConfig is present\n"); //process sl-CommConfig rrc_ue_process_sidelink_radioResourceConfig(ctxt_pP->module_id,eNB_index, (LTE_SystemInformationBlockType18_r12_t *)NULL, (LTE_SystemInformationBlockType19_r12_t *)NULL, - rrcConnectionReconfiguration_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_CommConfig_r12, + r_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_CommConfig_r12, (LTE_SL_DiscConfig_r12_t *)NULL ); } @@ -1766,36 +2015,37 @@ rrc_ue_process_rrcConnectionReconfiguration( /* //if RRCConnectionReconfiguration message includes the sl-DiscConfig - if (rrcConnectionReconfiguration_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_DiscConfig_r12->discTxResources_r12->present != SL_DiscConfig_r12__discTxResources_r12_PR_NOTHING ){ + if (r_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_DiscConfig_r12->discTxResources_r12->present != SL_DiscConfig_r12__discTxResources_r12_PR_NOTHING ){ LOG_I(RRC,"sl-DiscConfig is present\n"); //process sl-DiscConfig rrc_ue_process_sidelink_radioResourceConfig(ctxt_pP->module_id,eNB_index, (SystemInformationBlockType18_r12_t *)NULL, (SystemInformationBlockType19_r12_t *)NULL, (SL_CommConfig_r12_t* )NULL, - rrcConnectionReconfiguration_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_DiscConfig_r12 + r_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_DiscConfig_r12 ); } */ /* Check if there is dedicated NAS information to forward to NAS */ - if (rrcConnectionReconfiguration_r8->dedicatedInfoNASList != NULL) { + if (r_r8->dedicatedInfoNASList != NULL) { int list_count; uint32_t pdu_length; uint8_t *pdu_buffer; MessageDef *msg_p; - for (list_count = 0; list_count < rrcConnectionReconfiguration_r8->dedicatedInfoNASList->list.count; list_count++) { - pdu_length = rrcConnectionReconfiguration_r8->dedicatedInfoNASList->list.array[list_count]->size; - pdu_buffer = rrcConnectionReconfiguration_r8->dedicatedInfoNASList->list.array[list_count]->buf; + for (list_count = 0; list_count < r_r8->dedicatedInfoNASList->list.count; list_count++) { + pdu_length = r_r8->dedicatedInfoNASList->list.array[list_count]->size; + pdu_buffer = r_r8->dedicatedInfoNASList->list.array[list_count]->buf; msg_p = itti_alloc_new_message(TASK_RRC_UE, 0, NAS_CONN_ESTABLI_CNF); NAS_CONN_ESTABLI_CNF(msg_p).errCode = AS_SUCCESS; NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length = pdu_length; NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.data = pdu_buffer; itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p); } + LOG_D(RRC, "Sent NAS_CONN_ESTABLI_CNF to NAS layer via itti!\n"); - free (rrcConnectionReconfiguration_r8->dedicatedInfoNASList); + free (r_r8->dedicatedInfoNASList); } #if ENABLE_RAL @@ -1945,6 +2195,7 @@ rrc_ue_decode_dcch( const protocol_ctxt_t *const ctxt_pP, const rb_id_t Srb_id, const uint8_t *const Buffer, + const uint32_t Buffer_size, const uint8_t eNB_indexP ) //----------------------------------------------------------------------------- @@ -1962,11 +2213,18 @@ rrc_ue_decode_dcch( return; } - uper_decode(NULL, + asn_dec_rval_t dec_rval = uper_decode(NULL, &asn_DEF_LTE_DL_DCCH_Message, (void **)&dl_dcch_msg, (uint8_t *)Buffer, - RRC_BUF_SIZE,0,0); + Buffer_size, 0, 0); + + if (dec_rval.code != RC_OK && dec_rval.consumed == 0) + { + LOG_E(RRC, "%s: Failed to decode LTE_DL_DCC_Msg\n", __FUNCTION__); + SEQUENCE_free(&asn_DEF_LTE_DL_DCCH_Message, dl_dcch_msg, ASFM_FREE_EVERYTHING); + return; + } if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { xer_fprint(stdout,&asn_DEF_LTE_DL_DCCH_Message,(void *)dl_dcch_msg); @@ -2055,7 +2313,8 @@ rrc_ue_decode_dcch( rrc_ue_generate_RRCConnectionReconfigurationComplete( ctxt_pP, target_eNB_index, - dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.rrc_TransactionIdentifier); + dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.rrc_TransactionIdentifier, + NULL); UE_rrc_inst[ctxt_pP->module_id].Info[eNB_indexP].State = RRC_HO_EXECUTION; UE_rrc_inst[ctxt_pP->module_id].Info[target_eNB_index].State = RRC_RECONFIGURED; LOG_I(RRC, "[UE %d] State = RRC_RECONFIGURED during HO (eNB %d)\n", @@ -2109,7 +2368,8 @@ rrc_ue_decode_dcch( rrc_ue_generate_RRCConnectionReconfigurationComplete( ctxt_pP, eNB_indexP, - dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.rrc_TransactionIdentifier); + dl_dcch_msg->message.choice.c1.choice.rrcConnectionReconfiguration.rrc_TransactionIdentifier, + NULL); UE_rrc_inst[ctxt_pP->module_id].Info[eNB_indexP].State = RRC_RECONFIGURED; LOG_I(RRC, "[UE %d] State = RRC_RECONFIGURED (eNB %d)\n", ctxt_pP->module_id, @@ -2178,6 +2438,12 @@ rrc_ue_decode_dcch( send_ue_information ++; } + UE_RRC_INFO *info = &UE_rrc_inst[ctxt_pP->module_id].Info[eNB_indexP]; + if (info->dl_dcch_msg != NULL) { + SEQUENCE_free(&asn_DEF_LTE_DL_DCCH_Message, info->dl_dcch_msg, ASFM_FREE_EVERYTHING); + } + info->dl_dcch_msg = dl_dcch_msg; + dl_dcch_msg = NULL; break; case LTE_DL_DCCH_MessageType__c1_PR_rrcConnectionRelease: @@ -2212,10 +2478,53 @@ rrc_ue_decode_dcch( LOG_I(RRC, "[UE %d] Received Capability Enquiry (eNB %d)\n", ctxt_pP->module_id, eNB_indexP); - rrc_ue_process_ueCapabilityEnquiry( - ctxt_pP, - &dl_dcch_msg->message.choice.c1.choice.ueCapabilityEnquiry, - eNB_indexP); + + LTE_UE_CapabilityRequest_t *ue_cap = &dl_dcch_msg->message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions. + choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest; + bool have_received_nrue_cap = false; + for (int i = 0; i < ue_cap->list.count; i++) { + if (*ue_cap->list.array[i] == LTE_RAT_Type_nr || *ue_cap->list.array[i] == LTE_RAT_Type_eutra_nr) { + have_received_nrue_cap = true; + break; + } + } + if (have_received_nrue_cap) { + LTE_UECapabilityEnquiry_t *ueCapabilityEnquiry_nsa = &dl_dcch_msg->message.choice.c1.choice.ueCapabilityEnquiry; + OCTET_STRING_t * requestedFreqBandsNR = ueCapabilityEnquiry_nsa-> + criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.nonCriticalExtension-> + nonCriticalExtension->nonCriticalExtension->nonCriticalExtension-> + nonCriticalExtension->requestedFreqBandsNR_MRDC_r15; + nsa_sendmsg_to_nrue(requestedFreqBandsNR->buf, requestedFreqBandsNR->size, NRUE_CAPABILITY_ENQUIRY); + LOG_A(RRC, "Second ueCapabilityEnquiry (request for NR capabilities) sent to NR UE with size %zu\n", + requestedFreqBandsNR->size); + // Save ueCapabilityEnquiry so we can use in nsa mode after nrUE response is received + UE_RRC_INFO *info = &UE_rrc_inst[ctxt_pP->module_id].Info[eNB_indexP]; + if (info->dl_dcch_msg != NULL) { + info->dl_dcch_msg = NULL; + } + info->dl_dcch_msg = dl_dcch_msg; + dl_dcch_msg = NULL; + } else if (get_softmodem_params()->nsa && !have_received_nrue_cap) { + LTE_UECapabilityEnquiry_t *ueCapabilityEnquiry_nsa = &dl_dcch_msg->message.choice.c1.choice.ueCapabilityEnquiry; + OCTET_STRING_t * requestedFreqBandsNR = ueCapabilityEnquiry_nsa-> + criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.nonCriticalExtension-> + nonCriticalExtension->nonCriticalExtension->nonCriticalExtension-> + nonCriticalExtension->requestedFreqBandsNR_MRDC_r15; + nsa_sendmsg_to_nrue(requestedFreqBandsNR->buf, requestedFreqBandsNR->size, UE_CAPABILITY_ENQUIRY); + LOG_A(RRC, "Initial ueCapabilityEnquiry sent to NR UE with size %zu\n", requestedFreqBandsNR->size); + // Save ueCapabilityEnquiry so we can use in nsa mode after nrUE response is received + UE_RRC_INFO *info = &UE_rrc_inst[ctxt_pP->module_id].Info[eNB_indexP]; + if (info->dl_dcch_msg != NULL) { + info->dl_dcch_msg = NULL; + } + info->dl_dcch_msg = dl_dcch_msg; + dl_dcch_msg = NULL; + } else { + rrc_ue_process_ueCapabilityEnquiry( + ctxt_pP, + &dl_dcch_msg->message.choice.c1.choice.ueCapabilityEnquiry, + eNB_indexP); + } break; case LTE_DL_DCCH_MessageType__c1_PR_counterCheck: @@ -2872,16 +3181,18 @@ int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, } LOG_I( RRC, "PLMN %d MCC %0*d, MNC %0*d\n", i + 1, mccdigits, mcc, mncdigits, mnc); - // search internal table for provider name - int plmn_ind = 0; - while (plmn_data[plmn_ind].mcc > 0) { + // search internal table for provider name + const size_t num_plmn_data = sizeof(plmn_data) / sizeof(plmn_data[0]); + for (size_t plmn_ind = 0;; ++plmn_ind) { + if (plmn_ind == num_plmn_data) { + LOG_E( RRC, "Did not find name from internal table for %u %u\n", mcc, mnc); + break; + } if ((plmn_data[plmn_ind].mcc == mcc) && (plmn_data[plmn_ind].mnc == mnc)) { LOG_I( RRC, "Found %s (name from internal table)\n", plmn_data[plmn_ind].oper_short ); break; } - - plmn_ind++; } } LOG_I( RRC, "TAC 0x%04x\n", @@ -4019,12 +4330,48 @@ void ue_meas_filtering( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_ } } } +//Below routine implements Measurement Reporting procedure from 36.331 Section 5.5.5 +//----------------------------------------------------------------------------- +void rrc_ue_generate_nrMeasurementReport(protocol_ctxt_t *const ctxt_pP, uint8_t eNB_index ) { + uint8_t buffer[RRC_BUF_SIZE]; + UE_RRC_INST *ue = &UE_rrc_inst[ctxt_pP->module_id]; + uint8_t target_eNB_offset = ue->Info[0].handoverTarget; + LTE_PhysCellId_t targetCellId = ue->HandoverInfoUe.targetCellId; + + for (int i = 0; i < MAX_MEAS_ID; i++) { + if (ue->measReportList[eNB_index][i] != NULL) { + LTE_MeasId_t measId = ue->measReportList[eNB_index][i]->measId; + long rsrp_s = binary_search_float(RSRP_meas_mapping, 98, ue->rsrp_db_filtered[eNB_index]); + long rsrq_s = binary_search_float(RSRQ_meas_mapping, 35, ue->rsrq_db_filtered[eNB_index]); + long rsrp_tar = binary_search_float(RSRP_meas_mapping, 98, ue->rsrp_db_filtered[target_eNB_offset]); + long rsrq_tar = binary_search_float(RSRQ_meas_mapping, 35, ue->rsrq_db_filtered[target_eNB_offset]); + + LOG_I(RRC,"[UE %d] Frame %d: source eNB: %d target eNB: %d servingCell(%d) targetCell(%ld)\n", + ctxt_pP->module_id, + ctxt_pP->frame, + eNB_index, + target_eNB_offset, + get_adjacent_cell_id(ctxt_pP->module_id, eNB_index), + targetCellId); + + if (ctxt_pP->frame != 0) { + LOG_I(RRC, "measId %ld, targetCellId %ld, rsrp_s %ld, rsrq_s %ld, rsrp_t %ld, rsrq_t %ld\n", + measId, targetCellId, rsrp_s, rsrq_s, rsrp_tar, rsrq_tar); + ssize_t size = do_nrMeasurementReport(buffer, sizeof(buffer), measId, targetCellId, rsrp_s, rsrq_s, rsrp_tar, rsrq_tar); + AssertFatal(size >= 0, "do_nrMeasurementReport failed \n"); + LOG_I(RRC, "[UE %d] Frame %d : Generating Measurement Report for eNB %d\n", + ctxt_pP->module_id, ctxt_pP->frame, eNB_index); + int result = pdcp_data_req(ctxt_pP, SRB_FLAG_YES, DCCH, rrc_mui++, 0, size, buffer, PDCP_TRANSMISSION_MODE_DATA,NULL, NULL); + AssertFatal (result == TRUE, "PDCP data request failed!\n"); + } + } + } +} //Below routine implements Measurement Reporting procedure from 36.331 Section 5.5.5 //----------------------------------------------------------------------------- void rrc_ue_generate_MeasurementReport(protocol_ctxt_t *const ctxt_pP, uint8_t eNB_index ) { - uint8_t buffer[32], size; - uint8_t i; + uint8_t buffer[RRC_BUF_SIZE]; uint8_t target_eNB_offset; LTE_MeasId_t measId; LTE_PhysCellId_t targetCellId; @@ -4038,7 +4385,7 @@ void rrc_ue_generate_MeasurementReport(protocol_ctxt_t *const ctxt_pP, uint8_t e nElem1 = 35; target_eNB_offset = UE_rrc_inst[ctxt_pP->module_id].Info[0].handoverTarget; // eNB_offset of target eNB: used to obtain the mod_id of target eNB - for (i=0; imodule_id].measReportList[0][i] != NULL) { measId = UE_rrc_inst[ctxt_pP->module_id].measReportList[0][i]->measId; // Note: Values in the meas report have to be the mapped values...to implement binary search for LUT @@ -4046,7 +4393,7 @@ void rrc_ue_generate_MeasurementReport(protocol_ctxt_t *const ctxt_pP, uint8_t e rsrp_s = binary_search_float(RSRP_meas_mapping,nElem, rsrp_filtered); rsrq_filtered = UE_rrc_inst[ctxt_pP->module_id].rsrq_db_filtered[eNB_index];//nid_cell]; //RSRQ of serving cell rsrq_s = binary_search_float(RSRQ_meas_mapping,nElem1,rsrq_filtered);//mapped RSRQ of serving cell - LOG_D(RRC,"[UE %d] Frame %d: source eNB %d :rsrp_s: %ld rsrq_s: %ld rsrp_filtered: %f rsrq_filtered: %f \n", + LOG_I(RRC,"[UE %d] Frame %d: source eNB %d :rsrp_s: %ld rsrq_s: %ld rsrp_filtered: %f rsrq_filtered: %f \n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index, @@ -4056,7 +4403,7 @@ void rrc_ue_generate_MeasurementReport(protocol_ctxt_t *const ctxt_pP, uint8_t e rsrq_filtered); rsrp_t = binary_search_float(RSRP_meas_mapping,nElem,UE_rrc_inst[ctxt_pP->module_id].rsrp_db_filtered[target_eNB_offset]); //RSRP of target cell rsrq_t = binary_search_float(RSRQ_meas_mapping,nElem1,UE_rrc_inst[ctxt_pP->module_id].rsrq_db_filtered[target_eNB_offset]); //RSRQ of target cell - LOG_D(RRC,"[UE %d] Frame %d: target eNB %d :rsrp_t: %ld rsrq_t: %ld rsrp_filtered: %f rsrq_filtered: %f \n", + LOG_I(RRC,"[UE %d] Frame %d: target eNB %d :rsrp_t: %ld rsrq_t: %ld rsrp_filtered: %f rsrq_filtered: %f \n", ctxt_pP->module_id, ctxt_pP->frame, target_eNB_offset, @@ -4069,7 +4416,7 @@ void rrc_ue_generate_MeasurementReport(protocol_ctxt_t *const ctxt_pP, uint8_t e if (pframe!=ctxt_pP->frame) { pframe=ctxt_pP->frame; - LOG_D(RRC, "[UE %d] Frame %ld: doing MeasReport: servingCell(%ld) targetCell(%ld) rsrp_s(%ld) rsrq_s(%ld) rsrp_t(%ld) rsrq_t(%ld) \n", + LOG_I(RRC, "[UE %d] Frame %ld: doing MeasReport: servingCell(%ld) targetCell(%ld) rsrp_s(%ld) rsrq_s(%ld) rsrp_t(%ld) rsrq_t(%ld) \n", ctxt_pP->module_id, (long int)ctxt_pP->frame, (long int)get_adjacent_cell_id(ctxt_pP->module_id, eNB_index), @@ -4078,9 +4425,11 @@ void rrc_ue_generate_MeasurementReport(protocol_ctxt_t *const ctxt_pP, uint8_t e (long int)rsrq_s, (long int)rsrp_t, (long int)rsrq_t); - size = do_MeasurementReport(ctxt_pP->module_id, buffer,measId,targetCellId,rsrp_s,rsrq_s,rsrp_t,rsrq_t); - LOG_I(RRC, "[UE %d] Frame %d : Generating Measurement Report for eNB %d\n", - ctxt_pP->module_id, ctxt_pP->frame, eNB_index); + ssize_t size = do_MeasurementReport(ctxt_pP->module_id, buffer, sizeof(buffer), + measId, targetCellId, rsrp_s, rsrq_s, rsrp_t, rsrq_t); + AssertFatal(size >= 0, "do_MeasurementReport failed \n"); + LOG_I(RRC, "[UE %d] Frame %d : Generating Measurement Report for eNB %d. Size is %zu\n", + ctxt_pP->module_id, ctxt_pP->frame, eNB_index, size); result = pdcp_data_req(ctxt_pP, SRB_FLAG_YES, DCCH, rrc_mui++, 0, size, buffer, PDCP_TRANSMISSION_MODE_DATA,NULL, NULL); AssertFatal (result == TRUE, "PDCP data request failed!\n"); //LOG_D(RRC, "[UE %d] Frame %d Sending MeasReport (%d bytes) through DCCH%d to PDCP \n",ue_mod_idP,frameP, size, DCCH); @@ -4092,6 +4441,39 @@ void rrc_ue_generate_MeasurementReport(protocol_ctxt_t *const ctxt_pP, uint8_t e } } +static bool does_rrcConnReconfig_have_nr(const UE_RRC_INST *ue) { + for (int i = 0; i < NB_CNX_UE; i++) { + for (int j = 0; j < MAX_MEAS_ID; j++) { + LTE_ReportConfigId_t reportConfigId = ue->MeasId[i][j]->reportConfigId; + AssertFatal(reportConfigId >= 1 && reportConfigId <= MAX_MEAS_CONFIG, "Bad index\n"); + const LTE_ReportConfigToAddMod_t *rc = ue->ReportConfig[i][reportConfigId-1]; + if (rc == NULL) { + LOG_D(RRC, "UE_rrc_inst[ctxt_pP->module_id]->ReportConfig[%d][%ld] = NULL\n", i, reportConfigId-1); + continue; + } + if (rc->reportConfig.present != LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigInterRAT) { + LOG_D(RRC, "reportConfig.present = %d, not LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigInterRAT\n", + rc->reportConfig.present); + continue; + } + LTE_ReportConfigInterRAT_t irat = rc->reportConfig.choice.reportConfigInterRAT; + if (irat.triggerType.present != LTE_ReportConfigInterRAT__triggerType_PR_event) { + LOG_D(RRC, "irat.triggerType.present = %d, not LTE_ReportConfigInterRAT__triggerType_PR_event\n", + irat.triggerType.present); + continue; + } + if (irat.triggerType.choice.event.eventId.present != LTE_ReportConfigInterRAT__triggerType__event__eventId_PR_eventB1_NR_r15) { + LOG_D(RRC, "irat.triggerType.choice.event.eventId.present = %d\n", + irat.triggerType.choice.event.eventId.present); + continue; + } + return true; + } + } + return false; +} + + // Measurement report triggering, described in 36.331 Section 5.5.4.1: called periodically //----------------------------------------------------------------------------- void ue_measurement_report_triggering(protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index ) { @@ -4105,35 +4487,34 @@ void ue_measurement_report_triggering(protocol_ctxt_t *const ctxt_pP, const uint long a3_offset; LTE_MeasObjectId_t measObjId; LTE_ReportConfigId_t reportConfigId; - + UE_RRC_INST *ue = &UE_rrc_inst[ctxt_pP->module_id]; for(i=0 ; imodule_id].MeasId[i][j] != NULL) { - measObjId = UE_rrc_inst[ctxt_pP->module_id].MeasId[i][j]->measObjectId; - reportConfigId = UE_rrc_inst[ctxt_pP->module_id].MeasId[i][j]->reportConfigId; + if(ue->MeasId[i][j] != NULL) { + measObjId = ue->MeasId[i][j]->measObjectId; + reportConfigId = ue->MeasId[i][j]->reportConfigId; - if( /*UE_rrc_inst[ctxt_pP->module_id].MeasId[i][j] != NULL && */ UE_rrc_inst[ctxt_pP->module_id].MeasObj[i][measObjId-1] != NULL) { - if(UE_rrc_inst[ctxt_pP->module_id].MeasObj[i][measObjId-1]->measObject.present == LTE_MeasObjectToAddMod__measObject_PR_measObjectEUTRA) { + if(ue->MeasObj[i][measObjId-1] != NULL) { + if(ue->MeasObj[i][measObjId-1]->measObject.present == LTE_MeasObjectToAddMod__measObject_PR_measObjectEUTRA) { /* consider any neighboring cell detected on the associated frequency to be * applicable when the concerned cell is not included in the blackCellsToAddModList * defined within the VarMeasConfig for this measId */ - // LOG_I(RRC,"event %d %d %p \n", measObjId,reportConfigId, UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][reportConfigId-1]); - if((UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][reportConfigId-1] != NULL) && - (UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][reportConfigId-1]->reportConfig.present == LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA) && - (UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][reportConfigId-1]->reportConfig.choice.reportConfigEUTRA.triggerType.present == + // LOG_I(RRC,"event %d %d %p \n", measObjId,reportConfigId, ue->ReportConfig[i][reportConfigId-1]); + if((ue->ReportConfig[i][reportConfigId-1] != NULL) && + (ue->ReportConfig[i][reportConfigId-1]->reportConfig.present == LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA) && + (ue->ReportConfig[i][reportConfigId-1]->reportConfig.choice.reportConfigEUTRA.triggerType.present == LTE_ReportConfigEUTRA__triggerType_PR_event)) { - hys = UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][reportConfigId-1]->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.hysteresis; - ttt_ms = timeToTrigger_ms[UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][reportConfigId + hys = ue->ReportConfig[i][reportConfigId-1]->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.hysteresis; + ttt_ms = timeToTrigger_ms[ue->ReportConfig[i][reportConfigId -1]->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.timeToTrigger]; // Freq specific offset of neighbor cell freq - ofn = 5;//((UE_rrc_inst[ctxt_pP->module_id].MeasObj[i][measObjId-1]->measObject.choice.measObjectEUTRA.offsetFreq != NULL) ? - // *UE_rrc_inst[ctxt_pP->module_id].MeasObj[i][measObjId-1]->measObject.choice.measObjectEUTRA.offsetFreq : 15); // /* 15 is the Default */ + ofn = 5;//((ue->MeasObj[i][measObjId-1]->measObject.choice.measObjectEUTRA.offsetFreq != NULL) ? + // *ue->MeasObj[i][measObjId-1]->measObject.choice.measObjectEUTRA.offsetFreq : 15); // /* 15 is the Default */ // cellIndividualOffset of neighbor cell - not defined yet ocn = 0; - a3_offset = UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][reportConfigId - -1]->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA3.a3_Offset; + a3_offset = ue->ReportConfig[i][reportConfigId-1]->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA3.a3_Offset; - switch (UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][reportConfigId-1]->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present) { + switch (ue->ReportConfig[i][reportConfigId-1]->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present) { case LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA1: LOG_D(RRC,"[UE %d] Frame %d : A1 event: check if serving becomes better than threshold\n", ctxt_pP->module_id, ctxt_pP->frame); @@ -4153,28 +4534,25 @@ void ue_measurement_report_triggering(protocol_ctxt_t *const ctxt_pP, const uint ctxt_pP->frame, eNB_index, i,j,ofn,ocn,hys,ofs,ocs,a3_offset,ttt_ms)) && - (UE_rrc_inst[ctxt_pP->module_id].Info[0].State >= RRC_CONNECTED) && - (UE_rrc_inst[ctxt_pP->module_id].Info[0].T304_active == 0 ) && - (UE_rrc_inst[ctxt_pP->module_id].HandoverInfoUe.measFlag == 1)) { + (ue->Info[0].State >= RRC_CONNECTED) && + (ue->Info[0].T304_active == 0 ) && + (ue->HandoverInfoUe.measFlag == 1)) { //trigger measurement reporting procedure (36.331, section 5.5.5) - if (UE_rrc_inst[ctxt_pP->module_id].measReportList[i][j] == NULL) { - UE_rrc_inst[ctxt_pP->module_id].measReportList[i][j] = malloc(sizeof(MEAS_REPORT_LIST)); + if (ue->measReportList[i][j] == NULL) { + ue->measReportList[i][j] = malloc(sizeof(MEAS_REPORT_LIST)); } - UE_rrc_inst[ctxt_pP->module_id].measReportList[i][j]->measId = UE_rrc_inst[ctxt_pP->module_id].MeasId[i][j]->measId; - UE_rrc_inst[ctxt_pP->module_id].measReportList[i][j]->numberOfReportsSent = 0; + ue->measReportList[i][j]->measId = ue->MeasId[i][j]->measId; + ue->measReportList[i][j]->numberOfReportsSent = 0; rrc_ue_generate_MeasurementReport( ctxt_pP, eNB_index); - UE_rrc_inst[ctxt_pP->module_id].HandoverInfoUe.measFlag = 1; - LOG_I(RRC,"[UE %d] Frame %d: A3 event detected, state: %d \n", - ctxt_pP->module_id, ctxt_pP->frame, UE_rrc_inst[ctxt_pP->module_id].Info[0].State); + ue->HandoverInfoUe.measFlag = 1; } else { - if(UE_rrc_inst[ctxt_pP->module_id].measReportList[i][j] != NULL) { - free(UE_rrc_inst[ctxt_pP->module_id].measReportList[i][j]); + if(ue->measReportList[i][j] != NULL) { + free(ue->measReportList[i][j]); } - - UE_rrc_inst[ctxt_pP->module_id].measReportList[i][j] = NULL; + ue->measReportList[i][j] = NULL; } break; @@ -4191,11 +4569,54 @@ void ue_measurement_report_triggering(protocol_ctxt_t *const ctxt_pP, const uint default: LOG_D(RRC,"Invalid ReportConfigEUTRA__triggerType__event__eventId: %d", - UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][j]->reportConfig.choice.reportConfigEUTRA.triggerType.present); + ue->ReportConfig[i][j]->reportConfig.choice.reportConfigEUTRA.triggerType.present); break; } } } + + if (ue->MeasObj[i][measObjId-1]->measObject.present == LTE_MeasObjectToAddMod__measObject_PR_measObjectNR_r15) { + if (!does_rrcConnReconfig_have_nr(ue)) + break; + LTE_ReportConfigInterRAT_t *rc = &ue->ReportConfig[i][reportConfigId-1]->reportConfig.choice.reportConfigInterRAT; + LTE_TimeToTrigger_t trig_per = rc->triggerType.choice.event.timeToTrigger; + ttt_ms = timeToTrigger_ms[trig_per]; + LOG_D(RRC, "[UE %d] Frame %d: B1_NR_r15 event. count %d, ttt %ld\n", + ctxt_pP->module_id, ctxt_pP->frame, ue->subframeCount, ttt_ms); + if (ue->subframeCount < ttt_ms) { + ++ue->subframeCount; + break; + } + ue->subframeCount = 0; + bool is_state_connected = false; + bool is_t304_inactive = false; + bool have_meas_flag = false; + if (ue->Info[0].State >= RRC_CONNECTED) + is_state_connected = true; + if (ue->Info[0].T304_active == 0) + is_t304_inactive = true; + if (ue->HandoverInfoUe.measFlag == 1) + have_meas_flag = true; + + if (is_state_connected && is_t304_inactive && have_meas_flag) { + LOG_I(RRC,"[UE %d] Frame %d: Triggering generation of Meas Report for NR_r15. count = %d\n", + ctxt_pP->module_id, ctxt_pP->frame, ue->subframeCount); + if (ue->measReportList[i][j] == NULL) { + ue->measReportList[i][j] = malloc(sizeof(MEAS_REPORT_LIST)); + } + ue->measReportList[i][j]->measId = ue->MeasId[i][j]->measId; + ue->measReportList[i][j]->numberOfReportsSent = 0; + rrc_ue_generate_nrMeasurementReport(ctxt_pP, eNB_index); + ue->HandoverInfoUe.measFlag = 1; + LOG_I(RRC,"[UE %d] Frame %d: RSRB detected, state: %d \n", + ctxt_pP->module_id, ctxt_pP->frame, ue->Info[0].State); + } else { + if(ue->measReportList[i][j] != NULL) { + free(ue->measReportList[i][j]); + } + ue->measReportList[i][j] = NULL; + } + } } } } @@ -4221,10 +4642,12 @@ uint8_t check_trigger_meas_event( uint8_t eNB_offset; // uint8_t currentCellIndex = frame_parms->Nid_cell; uint8_t tmp_offset; - LOG_D(RRC,"[UE %d] ofn(%ld) ocn(%ld) hys(%ld) ofs(%ld) ocs(%ld) a3_offset(%ld) ttt(%ld) rssi %3.1f\n", + LOG_D(RRC,"[UE %d] ofn(%ld) ocn(%ld) hys(%ld) ofs(%ld) ocs(%ld) ttt(%ld) rssi %3.1f\n", ue_mod_idP, - ofn,ocn,hys,ofs,ocs,a3_offset,ttt, + ofn,ocn,hys,ofs,ocs,ttt, 10*log10(get_RSSI(ue_mod_idP,0))-get_rx_total_gain_dB(ue_mod_idP,0)); + LOG_D(RRC, "[UE %d] Frame %d: num_adj: %d eNB_idx: %d, NB_eNB_INST: %d\n", + ue_mod_idP, frameP, get_n_adj_cells(ue_mod_idP,0), eNB_index, NB_eNB_INST); for (eNB_offset = 0; eNB_offset<1+get_n_adj_cells(ue_mod_idP,0); eNB_offset++) { /* RHS: Verify that idx 0 corresponds to currentCellIndex in rsrp array */ @@ -4447,6 +4870,7 @@ void *rrc_ue_task( void *args_p ) { instance = ITTI_MSG_DESTINATION_INSTANCE (msg_p); ue_mod_id = UE_INSTANCE_TO_MODULE_ID(instance); + /* TODO: Add case to handle nr-UE messages we want from nrUE RRC layer */ switch (ITTI_MSG_ID(msg_p)) { case TERMINATE_MESSAGE: LOG_W(RRC, " *** Exiting RRC thread\n"); @@ -4566,12 +4990,66 @@ void *rrc_ue_task( void *args_p ) { &ctxt, RRC_DCCH_DATA_IND (msg_p).dcch_index, RRC_DCCH_DATA_IND (msg_p).sdu_p, + RRC_DCCH_DATA_IND (msg_p).sdu_size, RRC_DCCH_DATA_IND (msg_p).eNB_index); // Message buffer has been processed, free it now. result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), RRC_DCCH_DATA_IND (msg_p).sdu_p); AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); break; + case RRC_DCCH_DATA_COPY_IND: + { + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, RRC_DCCH_DATA_COPY_IND (msg_p).module_id, + ENB_FLAG_NO, RRC_DCCH_DATA_COPY_IND (msg_p).rnti, + RRC_DCCH_DATA_COPY_IND (msg_p).frame, + 0, + RRC_DCCH_DATA_COPY_IND (msg_p).eNB_index); + LOG_I(RRC, "[UE %d] Received %s. Now calling rrc_ue_process_ueCapabilityEnquiry\n", + ue_mod_id, ITTI_MSG_NAME (msg_p)); + rrc_dcch_data_copy_t *dl_dcch_buffer = (void *)RRC_DCCH_DATA_COPY_IND (msg_p).sdu_p; + AssertFatal(RRC_DCCH_DATA_COPY_IND (msg_p).sdu_size == sizeof(*dl_dcch_buffer), "Size of dl_dcch_buffer incorrect\n"); + rrc_ue_process_ueCapabilityEnquiry( + &ctxt, + &dl_dcch_buffer->dl_dcch_msg->message.choice.c1.choice.ueCapabilityEnquiry, + RRC_DCCH_DATA_COPY_IND (msg_p).eNB_index); + SEQUENCE_free(&asn_DEF_LTE_DL_DCCH_Message, dl_dcch_buffer->dl_dcch_msg, ASFM_FREE_EVERYTHING); + result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), RRC_DCCH_DATA_COPY_IND (msg_p).sdu_p); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + break; + } + + case RRC_NRUE_CAP_INFO_IND: + { + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, RRC_NRUE_CAP_INFO_IND (msg_p).module_id, + ENB_FLAG_NO, RRC_NRUE_CAP_INFO_IND (msg_p).rnti, + RRC_NRUE_CAP_INFO_IND (msg_p).frame, + 0, + RRC_NRUE_CAP_INFO_IND (msg_p).eNB_index); + LOG_I(RRC, "[UE %d] Received %s. Now calling rrc_ue_process_nrueCapabilityEnquiry\n", + ue_mod_id, ITTI_MSG_NAME (msg_p)); + rrc_nrue_cap_info_t *nrue_cap_info = (void *)RRC_NRUE_CAP_INFO_IND (msg_p).sdu_p; + AssertFatal(RRC_NRUE_CAP_INFO_IND (msg_p).sdu_size == sizeof(*nrue_cap_info), "Size of nrue_cap_info incorrect\n"); + rrc_ue_process_nrueCapabilityEnquiry( + &ctxt, + &nrue_cap_info->dl_dcch_msg->message.choice.c1.choice.ueCapabilityEnquiry, + nrue_cap_info, + RRC_NRUE_CAP_INFO_IND (msg_p).eNB_index); + SEQUENCE_free(&asn_DEF_LTE_DL_DCCH_Message, nrue_cap_info->dl_dcch_msg, ASFM_FREE_EVERYTHING); + result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), RRC_NRUE_CAP_INFO_IND (msg_p).sdu_p); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + break; + } + case NAS_OAI_TUN_NSA: + { + LOG_D(NAS, "Received %s: length %lu. About to send this to the NR UE\n", ITTI_MSG_NAME (msg_p), + sizeof(NAS_OAI_TUN_NSA (msg_p).buffer)); + char buffer[RRC_BUF_SIZE]; + memcpy(buffer, NAS_OAI_TUN_NSA(msg_p).buffer, sizeof(buffer)); + nsa_sendmsg_to_nrue(buffer, sizeof(buffer), OAI_TUN_IFACE_NSA); + break; + } + + case NAS_KENB_REFRESH_REQ: memcpy((void *)UE_rrc_inst[ue_mod_id].kenb, (void *)NAS_KENB_REFRESH_REQ(msg_p).kenb, sizeof(UE_rrc_inst[ue_mod_id].kenb)); LOG_D(RRC, "[UE %d] Received %s: refreshed RRC::KeNB = " @@ -4900,7 +5378,8 @@ openair_rrc_top_init_ue( memset (UE_rrc_inst, 0, NB_UE_INST * sizeof(UE_RRC_INST)); LOG_D(RRC, "ALLOCATE %d Bytes for UE_RRC_INST @ %p\n", (unsigned int)(NB_UE_INST*sizeof(UE_RRC_INST)), UE_rrc_inst); // fill UE capability - UECap = fill_ue_capability (uecap_xer); + bool received_nr_msg = false; + UECap = fill_ue_capability (uecap_xer, received_nr_msg); for (module_id = 0; module_id < NB_UE_INST; module_id++) { UE_rrc_inst[module_id].UECap = UECap; @@ -5191,9 +5670,6 @@ void rrc_control_socket_init() { //-------------------------------------------------------- void *rrc_control_socket_thread_fct(void *arg) { - int prose_addr_len; - char send_buf[BUFSIZE]; - char receive_buf[BUFSIZE]; //int optval; int n; struct sidelink_ctrl_element *sl_ctrl_msg_recv = NULL; @@ -5212,20 +5688,28 @@ void *rrc_control_socket_thread_fct(void *arg) { int j = 0; int i = 0; //from the main program, listen for the incoming messages from control socket (ProSe App) - prose_addr_len = sizeof(prose_app_addr); //int enable_notification = 1; while (1) { LOG_I(RRC,"Listening to incoming connection from ProSe App \n"); // receive a message from ProSe App - memset(receive_buf, 0, BUFSIZE); - n = recvfrom(ctrl_sock_fd, receive_buf, BUFSIZE, 0, - (struct sockaddr *) &prose_app_addr, (socklen_t *)&prose_addr_len); + char receive_buf[MAX_MESSAGE_SIZE]; + memset(receive_buf, 0, sizeof(receive_buf)); + socklen_t prose_addr_len = sizeof(prose_app_addr); + n = recvfrom(ctrl_sock_fd, receive_buf, sizeof(receive_buf), MSG_TRUNC, + (struct sockaddr *) &prose_app_addr, &prose_addr_len); if (n < 0) { LOG_E(RRC, "ERROR: Failed to receive from ProSe App\n"); exit(EXIT_FAILURE); } + if (n == 0) { + LOG_E(RRC, "%s(%d). EOF for ctrl_sock_fd\n", __FUNCTION__, __LINE__); + } + if (n > MAX_MESSAGE_SIZE) { + LOG_E(RRC, "%s(%d). Message truncated. %d\n", __FUNCTION__, __LINE__, n); + exit(EXIT_FAILURE); + } //TODO: should store the address of ProSeApp [UE_rrc_inst] to be able to send UE state notification to the App //sl_ctrl_msg_recv = (struct sidelink_ctrl_element *) receive_buf; @@ -5233,6 +5717,7 @@ void *rrc_control_socket_thread_fct(void *arg) { memcpy((void *)sl_ctrl_msg_recv, (void *)receive_buf, sizeof(struct sidelink_ctrl_element)); //process the message + char send_buf[MAX_MESSAGE_SIZE]; switch (sl_ctrl_msg_recv->type) { case SESSION_INIT_REQ: if (LOG_DEBUGFLAG(DEBUG_CTRLSOCKET)) { @@ -5241,14 +5726,14 @@ void *rrc_control_socket_thread_fct(void *arg) { //TODO: get SL_UE_STATE from lower layer LOG_I(RRC,"Send UEStateInformation to ProSe App \n"); - memset(send_buf, 0, BUFSIZE); + memset(send_buf, 0, MAX_MESSAGE_SIZE); sl_ctrl_msg_send = calloc(1, sizeof(struct sidelink_ctrl_element)); sl_ctrl_msg_send->type = UE_STATUS_INFO; sl_ctrl_msg_send->sidelinkPrimitive.ue_state = UE_STATE_OFF_NETWORK; //off-network memcpy((void *)send_buf, (void *)sl_ctrl_msg_send, sizeof(struct sidelink_ctrl_element)); free(sl_ctrl_msg_send); - prose_addr_len = sizeof(prose_app_addr); - n = sendto(ctrl_sock_fd, (char *)send_buf, sizeof(struct sidelink_ctrl_element), 0, (struct sockaddr *)&prose_app_addr, prose_addr_len); + n = sendto(ctrl_sock_fd, (char *)send_buf, sizeof(struct sidelink_ctrl_element), 0, + (struct sockaddr *)&prose_app_addr, sizeof(prose_app_addr)); if (n < 0) { LOG_E(RRC, "ERROR: Failed to send to ProSe App\n"); @@ -5394,14 +5879,14 @@ void *rrc_control_socket_thread_fct(void *arg) { (LTE_MBSFN_AreaInfoList_r9_t *)NULL ); LOG_I(RRC,"Send GroupCommunicationEstablishResp to ProSe App\n"); - memset(send_buf, 0, BUFSIZE); + memset(send_buf, 0, MAX_MESSAGE_SIZE); sl_ctrl_msg_send = calloc(1, sizeof(struct sidelink_ctrl_element)); sl_ctrl_msg_send->type = GROUP_COMMUNICATION_ESTABLISH_RSP; sl_ctrl_msg_send->sidelinkPrimitive.slrb_id = 3; //slrb_id memcpy((void *)send_buf, (void *)sl_ctrl_msg_send, sizeof(struct sidelink_ctrl_element)); free(sl_ctrl_msg_send); - prose_addr_len = sizeof(prose_app_addr); - n = sendto(ctrl_sock_fd, (char *)send_buf, sizeof(struct sidelink_ctrl_element), 0, (struct sockaddr *)&prose_app_addr, prose_addr_len); + n = sendto(ctrl_sock_fd, (char *)send_buf, sizeof(struct sidelink_ctrl_element), 0, + (struct sockaddr *)&prose_app_addr, sizeof(prose_app_addr)); if (n < 0) { LOG_E(RRC, "ERROR: Failed to send to ProSe App\n"); @@ -5455,7 +5940,7 @@ void *rrc_control_socket_thread_fct(void *arg) { (LTE_MBSFN_AreaInfoList_r9_t *)NULL ); LOG_I(RRC,"Send GroupCommunicationReleaseResponse to ProSe App \n"); - memset(send_buf, 0, BUFSIZE); + memset(send_buf, 0, MAX_MESSAGE_SIZE); sl_ctrl_msg_send = calloc(1, sizeof(struct sidelink_ctrl_element)); sl_ctrl_msg_send->type = GROUP_COMMUNICATION_RELEASE_RSP; @@ -5469,8 +5954,8 @@ void *rrc_control_socket_thread_fct(void *arg) { memcpy((void *)send_buf, (void *)sl_ctrl_msg_send, sizeof(struct sidelink_ctrl_element)); free(sl_ctrl_msg_send); - prose_addr_len = sizeof(prose_app_addr); - n = sendto(ctrl_sock_fd, (char *)send_buf, sizeof(struct sidelink_ctrl_element), 0, (struct sockaddr *)&prose_app_addr, prose_addr_len); + n = sendto(ctrl_sock_fd, (char *)send_buf, sizeof(struct sidelink_ctrl_element), 0, + (struct sockaddr *)&prose_app_addr, sizeof(prose_app_addr)); if (n < 0) { LOG_E(RRC, "ERROR: Failed to send to ProSe App\n"); @@ -5598,14 +6083,14 @@ void *rrc_control_socket_thread_fct(void *arg) { (LTE_MBSFN_AreaInfoList_r9_t *)NULL ); LOG_I(RRC,"Send DirectCommunicationEstablishResp to ProSe App\n"); - memset(send_buf, 0, BUFSIZE); + memset(send_buf, 0, MAX_MESSAGE_SIZE); sl_ctrl_msg_send = calloc(1, sizeof(struct sidelink_ctrl_element)); sl_ctrl_msg_send->type = DIRECT_COMMUNICATION_ESTABLISH_RSP; sl_ctrl_msg_send->sidelinkPrimitive.slrb_id = 3; //slrb_id memcpy((void *)send_buf, (void *)sl_ctrl_msg_send, sizeof(struct sidelink_ctrl_element)); free(sl_ctrl_msg_send); - prose_addr_len = sizeof(prose_app_addr); - n = sendto(ctrl_sock_fd, (char *)send_buf, sizeof(struct sidelink_ctrl_element), 0, (struct sockaddr *)&prose_app_addr, prose_addr_len); + n = sendto(ctrl_sock_fd, (char *)send_buf, sizeof(struct sidelink_ctrl_element), 0, + (struct sockaddr *)&prose_app_addr, sizeof(prose_app_addr)); if (n < 0) { LOG_E(RRC, "ERROR: Failed to send to ProSe App\n"); @@ -5785,15 +6270,15 @@ void *rrc_control_socket_thread_fct(void *arg) { } LOG_I(RRC,"Send PC5EstablishRsp to ProSe App\n"); - memset(send_buf, 0, BUFSIZE); + memset(send_buf, 0, MAX_MESSAGE_SIZE); sl_ctrl_msg_send = calloc(1, sizeof(struct sidelink_ctrl_element)); sl_ctrl_msg_send->type = PC5S_ESTABLISH_RSP; sl_ctrl_msg_send->sidelinkPrimitive.pc5s_establish_rsp.slrbid_lcid28 = 10; sl_ctrl_msg_send->sidelinkPrimitive.pc5s_establish_rsp.slrbid_lcid29 = 10; sl_ctrl_msg_send->sidelinkPrimitive.pc5s_establish_rsp.slrbid_lcid30 = 10; memcpy((void *)send_buf, (void *)sl_ctrl_msg_send, sizeof(struct sidelink_ctrl_element)); - prose_addr_len = sizeof(prose_app_addr); - n = sendto(ctrl_sock_fd, (char *)send_buf, sizeof(struct sidelink_ctrl_element), 0, (struct sockaddr *)&prose_app_addr, prose_addr_len); + n = sendto(ctrl_sock_fd, (char *)send_buf, sizeof(struct sidelink_ctrl_element), 0, + (struct sockaddr *)&prose_app_addr, sizeof(prose_app_addr)); // free(sl_ctrl_msg_send); if (n < 0) { @@ -5833,27 +6318,24 @@ int decode_SL_Discovery_Message( const uint8_t eNB_index, const uint8_t *Sdu, const uint8_t Sdu_len) { - int prose_addr_len; - char send_buf[BUFSIZE]; + char send_buf[MAX_MESSAGE_SIZE]; int n; struct sidelink_ctrl_element *sl_ctrl_msg_send = NULL; //from the main program, listen for the incoming messages from control socket (ProSe App) - prose_addr_len = sizeof(prose_app_addr); //Store in Rx_buffer memcpy((void *)&UE_rrc_inst[ctxt_pP->module_id].SL_Discovery[0].Rx_buffer.Payload[0], (void *)Sdu, Sdu_len); UE_rrc_inst[ctxt_pP->module_id].SL_Discovery[0].Rx_buffer.payload_size = Sdu_len; - memset(send_buf, 0, BUFSIZE); + memset(send_buf, 0, MAX_MESSAGE_SIZE); //send to ProSeApp memcpy((void *)send_buf, (void *)Sdu, Sdu_len); - prose_addr_len = sizeof(prose_app_addr); sl_ctrl_msg_send = calloc(1, sizeof(struct sidelink_ctrl_element)); sl_ctrl_msg_send->type = PC5_DISCOVERY_MESSAGE; // TODO: Add a check for the SDU size. memcpy((void *)&sl_ctrl_msg_send->sidelinkPrimitive.pc5_discovery_message.payload[0], (void *) Sdu, PC5_DISCOVERY_PAYLOAD_SIZE); memcpy((void *)send_buf, (void *)sl_ctrl_msg_send, sizeof(struct sidelink_ctrl_element)); free(sl_ctrl_msg_send); - prose_addr_len = sizeof(prose_app_addr); - n = sendto(ctrl_sock_fd, (char *)send_buf, sizeof(struct sidelink_ctrl_element), 0, (struct sockaddr *)&prose_app_addr, prose_addr_len); + n = sendto(ctrl_sock_fd, (char *)send_buf, sizeof(struct sidelink_ctrl_element), 0, + (struct sockaddr *)&prose_app_addr, sizeof(prose_app_addr)); if (n < 0) { // TODO: We should not just exit if the Prose App has not yet attached. It creates a race condition. @@ -5977,3 +6459,235 @@ rrc_rx_tx_ue( return (RRC_OK); } +void *recv_msgs_from_nr_ue(void *args_p) +{ + itti_mark_task_ready (TASK_RRC_NSA_UE); + for (;;) + { + nsa_msg_t msg; + int recvLen = recvfrom(from_nr_ue_fd, &msg, sizeof(msg), + MSG_WAITALL | MSG_TRUNC, NULL, NULL); + if (recvLen == -1) + { + LOG_E(RRC, "%s: recvfrom: %s\n", __func__, strerror(errno)); + continue; + } + if (recvLen > sizeof(msg)) + { + LOG_E(NR_RRC, "%s: Received a truncated message %d\n", __func__, recvLen); + continue; + } + LOG_D(RRC, "We have received a %d msg (%d bytes). Calling process_nr_nsa_msg\n", msg.msg_type, recvLen); + process_nr_nsa_msg(&msg, recvLen); + } + +} + +void nsa_sendmsg_to_nrue(const void *message, size_t msg_len, Rrc_Msg_Type_t msg_type) +{ + LOG_I(RRC, "Entered %s \n", __FUNCTION__); + nsa_msg_t n_msg; + if (msg_len > sizeof(n_msg.msg_buffer)) + { + LOG_E(RRC, "%s: message too big: %zu\n", __func__, msg_len); + abort(); + } + n_msg.msg_type = msg_type; + memcpy(n_msg.msg_buffer, message, msg_len); + size_t to_send = sizeof(n_msg.msg_type) + msg_len; + + struct sockaddr_in sa = + { + .sin_family = AF_INET, + .sin_port = htons(6008 + ue_id_g * 2), + }; + int sent = sendto(to_nr_ue_fd, &n_msg, to_send, 0, + (struct sockaddr *)&sa, sizeof(sa)); + if (sent == -1) + { + LOG_E(RRC, "%s: sendto: %s\n", __func__, strerror(errno)); + return; + } + if (sent != to_send) + { + LOG_E(RRC, "%s: Short send %d != %zu\n", __func__, sent, to_send); + return; + } + LOG_I(RRC, "Sent a %d message to the nrUE (%d bytes) \n", msg_type, sent); +} + +void init_connections_with_nr_ue() +{ + struct sockaddr_in sa = + { + .sin_family = AF_INET, + .sin_port = htons(6007 + ue_id_g * 2), + }; + AssertFatal(from_nr_ue_fd == -1, "from_nr_ue_fd was assigned already"); + from_nr_ue_fd = socket(AF_INET, SOCK_DGRAM, 0); + if (from_nr_ue_fd == -1) + { + LOG_E(RRC, "%s: Error opening socket %d (%d:%s)\n", __FUNCTION__, from_nr_ue_fd, errno, strerror(errno)); + abort(); + } + + if (inet_aton(nsa_ipaddr, &sa.sin_addr) == 0) + { + LOG_E(RRC, "Bad nsa_ipaddr '%s'\n", nsa_ipaddr); + abort(); + } + + if (bind(from_nr_ue_fd, (struct sockaddr *) &sa, sizeof(sa)) == -1) + { + LOG_E(RRC,"%s: Failed to bind the socket\n", __FUNCTION__); + abort(); + } + + AssertFatal(to_nr_ue_fd == -1, "to_nr_ue_fd was assigned already"); + to_nr_ue_fd = socket(AF_INET, SOCK_DGRAM, 0); + if (to_nr_ue_fd == -1) + { + LOG_E(RRC, "%s: Error opening socket %d (%d:%s)\n", __FUNCTION__, to_nr_ue_fd, errno, strerror(errno)); + abort(); + } + +} + +void process_nr_nsa_msg(nsa_msg_t *msg, int msg_len) +{ + if (msg_len < sizeof(msg->msg_type)) + { + LOG_E(RRC, "Msg_len = %d\n", msg_len); + return; + } + LOG_D(RRC, "We are processing an NSA message %d \n", msg->msg_type); + Rrc_Msg_Type_t msg_type = msg->msg_type; + uint8_t *const msg_buffer = msg->msg_buffer; + msg_len -= sizeof(msg->msg_type); + bool received_nr_msg = true; + protocol_ctxt_t ctxt; + module_id_t module_id = 0; + eNB_index_t eNB_index = 0; + + switch (msg_type) + { + case NRUE_CAPABILITY_INFO: + { + LOG_I(RRC, "Create itti msg to send received NRUE_CAPABILITY_INFO to eNB\n"); + + MessageDef *message_p; + rrc_nrue_cap_info_t *nrue_cap_buf = itti_malloc (TASK_RRC_NSA_UE, + TASK_RRC_UE, + sizeof(rrc_nrue_cap_info_t)); + AssertFatal(msg_len <= sizeof(nrue_cap_buf->mesg), "msg_len = %d\n", msg_len); + memcpy(nrue_cap_buf->mesg, msg_buffer, msg_len); + nrue_cap_buf->mesg_len = msg_len; + UE_RRC_INFO *info = &UE_rrc_inst[module_id].Info[eNB_index]; + nrue_cap_buf->dl_dcch_msg = info->dl_dcch_msg; + info->dl_dcch_msg = NULL; + message_p = itti_alloc_new_message (TASK_RRC_UE, 0, RRC_NRUE_CAP_INFO_IND); + RRC_NRUE_CAP_INFO_IND (message_p).sdu_p = (void *)nrue_cap_buf; + RRC_NRUE_CAP_INFO_IND (message_p).sdu_size = sizeof(*nrue_cap_buf); + RRC_NRUE_CAP_INFO_IND (message_p).module_id = module_id; + RRC_NRUE_CAP_INFO_IND (message_p).rnti = info->rnti; + RRC_NRUE_CAP_INFO_IND (message_p).eNB_index = eNB_index; + itti_send_msg_to_task (TASK_RRC_UE, 0, message_p); + LOG_I(RRC, "Sent itti RRC_NRUE_CAP_INFO_IND\n"); + break; + } + case UE_CAPABILITY_DUMMY: + { + fill_ue_capability(NULL, received_nr_msg); + UE_rrc_inst[module_id].UECap = UE_rrc_inst->UECap; + UE_rrc_inst[module_id].UECapability = UE_rrc_inst->UECap->sdu; + UE_rrc_inst[module_id].UECapability_size = UE_rrc_inst->UECap->sdu_size; + + if (!is_en_dc_supported(UE_rrc_inst->UECap->UE_EUTRA_Capability)) + { + LOG_E(RRC, "en_dc is NOT supported! Not sending RRC_DCCH_DATA_COPY_IND to update UE_Capability_INFO\n"); + break; + } + + LOG_I(RRC, "Send itti msg to trigger processing of capabilites b/c we have a UE_CAPABILITY_DUMMY\n"); + MessageDef *message_p; + rrc_dcch_data_copy_t *dl_dcch_buffer = itti_malloc (TASK_RRC_NSA_UE, + TASK_RRC_UE, + sizeof(rrc_dcch_data_copy_t)); + UE_RRC_INFO *info = &UE_rrc_inst[module_id].Info[eNB_index]; + dl_dcch_buffer->dl_dcch_msg = info->dl_dcch_msg; + info->dl_dcch_msg = NULL; + message_p = itti_alloc_new_message (TASK_RRC_UE, 0, RRC_DCCH_DATA_COPY_IND); + RRC_DCCH_DATA_COPY_IND (message_p).sdu_p = (void *)dl_dcch_buffer; + RRC_DCCH_DATA_COPY_IND (message_p).sdu_size = sizeof(rrc_dcch_data_copy_t); + RRC_DCCH_DATA_COPY_IND (message_p).module_id = module_id; + RRC_DCCH_DATA_COPY_IND (message_p).rnti = info->rnti; + RRC_DCCH_DATA_COPY_IND (message_p).eNB_index = eNB_index; + itti_send_msg_to_task (TASK_RRC_UE, 0, message_p); + LOG_I(RRC, "Sent itti RRC_DCCH_DATA_COPY_IND\n"); + break; + } + + case NR_UE_RRC_MEASUREMENT: + { + nfapi_p7_message_header_t header; + if (nfapi_p7_message_header_unpack((void *)msg_buffer, msg_len, &header, sizeof(header), NULL) < 0) + { + LOG_E(MAC, "Header unpack failed in %s \n", __FUNCTION__); + break; + } + if (header.message_id != NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST) + { + LOG_E(MAC, "%s: Unexpected nfapi message type: %d\n", __FUNCTION__, header.message_id); + break; + } + + nfapi_nr_dl_tti_request_t dl_tti_request; + int unpack_len = nfapi_nr_p7_message_unpack((void *)msg_buffer, + msg_len, + &dl_tti_request, + sizeof(nfapi_nr_dl_tti_request_t), + NULL); + if (unpack_len < 0) + { + LOG_E(RRC, "%s: SSB PDU unpack failed \n", __FUNCTION__); + break; + } + int num_pdus = dl_tti_request.dl_tti_request_body.nPDUs; + if (num_pdus <= 0) + { + LOG_E(RRC, "%s: dl_tti_request number of PDUS <= 0\n", __FUNCTION__); + abort(); + } + for (int i = 0; i < num_pdus; i++) + { + nfapi_nr_dl_tti_request_pdu_t *pdu_list = &dl_tti_request.dl_tti_request_body.dl_tti_pdu_list[i]; + if (pdu_list->PDUType == NFAPI_NR_DL_TTI_SSB_PDU_TYPE) + { + LOG_I(RRC, "Got an NR_UE_RRC_MEASUREMENT. pdulist[%d].ssbRsrp = %d\n", + i, pdu_list->ssb_pdu.ssb_pdu_rel15.ssbRsrp); + } + } + break; + } + + case NR_RRC_CONFIG_COMPLETE_REQ: + { + LOG_I(RRC, "Got an NR_RRC_CONFIG_COMPLETE_REQ. Now make octet string and call below!\n"); + OCTET_STRING_t rrcConfigurationComplete; + memset(&rrcConfigurationComplete, 0, sizeof(rrcConfigurationComplete)); + OCTET_STRING_fromBuf(&rrcConfigurationComplete, + (const char *)msg_buffer, + msg_len); + UE_RRC_INFO *info = &UE_rrc_inst[module_id].Info[eNB_index]; + uint8_t t_id = info->dl_dcch_msg->message.choice.c1.choice. + rrcConnectionReconfiguration.rrc_TransactionIdentifier; + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_id, + ENB_FLAG_NO, info->rnti, + 0, 0, eNB_index); + rrc_ue_generate_RRCConnectionReconfigurationComplete(&ctxt, ctxt.eNB_index, t_id, &rrcConfigurationComplete); + break; + } + default: + LOG_E(RRC, "No NSA Message Found\n"); + } +} diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index 40aad67a06..f537dcbbd2 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -52,7 +52,7 @@ //for D2D #define DEBUG_CTRL_SOCKET -#define BUFSIZE 1024 + #define CONTROL_SOCKET_PORT_NO 8888 #define MAX_NUM_DEST 10 //netlink @@ -311,12 +311,12 @@ typedef enum SL_TRIGGER_e { #define RRM_CALLOC(t,n) (t *) malloc16( sizeof(t) * n) #define RRM_CALLOC2(t,s) (t *) malloc16( s ) -#define MAX_MEAS_OBJ 6 -#define MAX_MEAS_CONFIG 6 -#define MAX_MEAS_ID 6 +#define MAX_MEAS_OBJ 7 +#define MAX_MEAS_CONFIG 7 +#define MAX_MEAS_ID 7 #define PAYLOAD_SIZE_MAX 1024 -#define RRC_BUF_SIZE 8192 +#define RRC_BUF_SIZE 512 #define UNDEF_SECURITY_MODE 0xff #define NO_SECURITY_MODE 0x20 @@ -363,6 +363,7 @@ typedef struct UE_RRC_INFO_s { uint32_t N310_cnt; uint32_t N311_cnt; rnti_t rnti; + struct LTE_DL_DCCH_Message *dl_dcch_msg; } __attribute__ ((__packed__)) UE_RRC_INFO; typedef struct UE_S_TMSI_s { @@ -916,6 +917,7 @@ typedef struct UE_RRC_INST_s { float rsrq_db[7]; float rsrp_db_filtered[7]; float rsrq_db_filtered[7]; + int subframeCount; /* KeNB as computed from parameters within USIM card */ uint8_t kenb[32]; uint8_t nh[32]; diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 548e52b09a..1c740e8441 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -90,6 +90,7 @@ #include #include "intertask_interface.h" +#include "softmodem-common.h" #if ENABLE_RAL #include "rrc_eNB_ral.h" @@ -100,7 +101,6 @@ #define ASN_MAX_ENCODE_SIZE 4096 #define NUMBEROF_DRBS_TOBE_ADDED 1 static int encode_CG_ConfigInfo(char *buffer,int buffer_size,rrc_eNB_ue_context_t *const ue_context_pP,int *enc_size); -static int is_en_dc_supported(LTE_UE_EUTRA_Capability_t *c); extern RAN_CONTEXT_t RC; @@ -152,7 +152,7 @@ init_SI( LOG_D(RRC,"%s()\n\n\n\n",__FUNCTION__); if(configuration->radioresourceconfig[CC_id].mbms_dedicated_serving_cell == TRUE) { - LOG_I(RRC, "Configuring MIB FeMBMS (N_RB_DL %d)\n", + LOG_A(RRC, "Configuring MIB FeMBMS (N_RB_DL %d)\n", (int)configuration->N_RB_DL[CC_id]); RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MIB_FeMBMS = (uint8_t *) malloc16(4); do_MIB_FeMBMS(&RC.rrc[ctxt_pP->module_id]->carrier[CC_id], @@ -253,7 +253,7 @@ init_SI( carrier->N_RB_DL = configuration->N_RB_DL[CC_id]; carrier->pbch_repetition = configuration->pbch_repetition[CC_id]; LOG_I(RRC, "configuration->schedulingInfoSIB1_BR_r13[CC_id] %d\n",(int)configuration->schedulingInfoSIB1_BR_r13[CC_id]); - LOG_I(RRC, "Configuring MIB (N_RB_DL %d,phich_Resource %d,phich_Duration %d)\n", + LOG_A(RRC, "Configuring MIB (N_RB_DL %d,phich_Resource %d,phich_Duration %d)\n", (int)configuration->N_RB_DL[CC_id], (int)configuration->radioresourceconfig[CC_id].phich_resource, (int)configuration->radioresourceconfig[CC_id].phich_duration); @@ -538,6 +538,7 @@ init_MCCH( RC.rrc[enb_mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[sync_area] = do_MBSFNAreaConfig(enb_mod_idP, sync_area, (uint8_t *)RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE[sync_area], + 100, /* TODO: what is the actual size of .MCCH_MESSAGE[sync_area]? */ &RC.rrc[enb_mod_idP]->carrier[CC_id].mcch, &RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message); LOG_I(RRC, "mcch message pointer %p for sync area %d \n", @@ -1196,7 +1197,7 @@ rrc_eNB_process_RRCConnectionSetupComplete( ) //----------------------------------------------------------------------------- { - LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, " "processing LTE_RRCConnectionSetupComplete from UE (SRB1 Active)\n", + LOG_A(RRC, PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, " "processing LTE_RRCConnectionSetupComplete from UE (SRB1 Active)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); ue_context_pP->ue_context.Srb1.Active = 1; ue_context_pP->ue_context.StatusRrc = RRC_CONNECTED; @@ -1231,6 +1232,7 @@ rrc_eNB_generate_SecurityModeCommand( size = do_SecurityModeCommand( ctxt_pP, buffer, + sizeof(buffer), rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id), ue_context_pP->ue_context.ciphering_algorithm, ue_context_pP->ue_context.integrity_algorithm); @@ -1285,6 +1287,7 @@ rrc_eNB_generate_UECapabilityEnquiry( size = do_UECapabilityEnquiry( ctxt_pP, buffer, + sizeof(buffer), rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id), eutra_band, nr_band); @@ -1335,10 +1338,11 @@ rrc_eNB_generate_NR_UECapabilityEnquiry( size = do_NR_UECapabilityEnquiry( ctxt_pP, buffer, + sizeof(buffer), rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id), eutra_band, nr_band); - LOG_I(RRC, + LOG_A(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate NR UECapabilityEnquiry (bytes %d)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), size); @@ -2001,9 +2005,10 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( measurements_enabled = RC.rrc[ENB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)]->configuration.enable_x2 || RC.rrc[ENB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)]->configuration.enable_measurement_reports; // send LTE_RRCConnectionReconfiguration - memset(buffer, 0, RRC_BUF_SIZE); + memset(buffer, 0, sizeof(buffer)); size = do_RRCConnectionReconfiguration(ctxt_pP, buffer, + sizeof(buffer), next_xid, //Transaction_id, (LTE_SRB_ToAddModList_t *)*SRB_configList2, // SRB_configList (LTE_DRB_ToAddModList_t *)DRB_configList, @@ -2199,7 +2204,7 @@ rrc_eNB_generate_RRCConnectionRelease( uint8_t buffer[RRC_BUF_SIZE]; uint16_t size = 0; int release_num; - memset(buffer, 0, RRC_BUF_SIZE); + memset(buffer, 0, sizeof(buffer)); T(T_ENB_RRC_CONNECTION_RELEASE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); #if 0 @@ -2211,7 +2216,8 @@ rrc_eNB_generate_RRCConnectionRelease( } #endif - size = do_RRCConnectionRelease(ctxt_pP->module_id, buffer,rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id)); + size = do_RRCConnectionRelease(ctxt_pP->module_id, buffer, sizeof(buffer), + rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id)); ue_context_pP->ue_context.ue_reestablishment_timer = 0; ue_context_pP->ue_context.ue_release_timer = 0; ue_context_pP->ue_context.ue_rrc_inactivity_timer = 0; @@ -2487,9 +2493,10 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t *co LOG_W(RRC,"dedlicated NAS list is empty\n"); } - memset(buffer, 0, RRC_BUF_SIZE); + memset(buffer, 0, sizeof(buffer)); size = do_RRCConnectionReconfiguration(ctxt_pP, buffer, + sizeof(buffer), xid, (LTE_SRB_ToAddModList_t *)NULL, (LTE_DRB_ToAddModList_t *)*DRB_configList2, @@ -2734,9 +2741,9 @@ rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t *cons LOG_W(RRC,"dedlicated NAS list is empty\n"); } - memset(buffer, 0, RRC_BUF_SIZE); + memset(buffer, 0, sizeof(buffer)); size = do_RRCConnectionReconfiguration(ctxt_pP, - buffer, + buffer, sizeof(buffer), xid, (LTE_SRB_ToAddModList_t *)NULL, (LTE_DRB_ToAddModList_t *)DRB_configList2, @@ -2835,9 +2842,10 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_release( const protocol_ LOG_W(RRC,"dedlicated NAS list is empty\n"); } - memset(buffer, 0, RRC_BUF_SIZE); + memset(buffer, 0, sizeof(buffer)); size = do_RRCConnectionReconfiguration(ctxt_pP, buffer, + sizeof(buffer), xid, NULL, NULL, @@ -3465,6 +3473,7 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7->reportQuantityCellNR_r15->ss_rsrq = TRUE; ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7->reportQuantityCellNR_r15->ss_sinr = TRUE; ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_NR); + LOG_A(RRC, "Generating RRCCConnectionReconfigurationRequest (NRUE Measurement Report Request).\n"); } // LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->reportConfigToAddModList = ReportConfig_list; @@ -3545,9 +3554,10 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t measurements_enabled = RC.rrc[ENB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)]->configuration.enable_x2 || RC.rrc[ENB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)]->configuration.enable_measurement_reports; - memset(buffer, 0, RRC_BUF_SIZE); + memset(buffer, 0, sizeof(buffer)); size = do_RRCConnectionReconfiguration(ctxt_pP, buffer, + sizeof(buffer), xid, // Transaction_id, (LTE_SRB_ToAddModList_t *) *SRB_configList2, // SRB_configList (LTE_DRB_ToAddModList_t *) *DRB_configList, @@ -4257,9 +4267,10 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt measurements_enabled = RC.rrc[ENB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)]->configuration.enable_x2 || RC.rrc[ENB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)]->configuration.enable_measurement_reports; - memset(buffer, 0, RRC_BUF_SIZE); + memset(buffer, 0, sizeof(buffer)); size = do_RRCConnectionReconfiguration(ctxt_pP, buffer, + sizeof(buffer), xid, // Transaction_id, (LTE_SRB_ToAddModList_t *) *SRB_configList2, // SRB_configList (LTE_DRB_ToAddModList_t *) *DRB_configList, @@ -4357,6 +4368,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_SCell( size = do_RRCConnectionReconfiguration(ctxt_pP, buffer, + sizeof(buffer), rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id),//Transaction_id, (LTE_SRB_ToAddModList_t *)NULL, (LTE_DRB_ToAddModList_t *)NULL, @@ -4421,7 +4433,6 @@ static int encode_CG_ConfigInfo( struct NR_CG_ConfigInfo *cg_configinfo = NULL; struct NR_RadioBearerConfig *rb_config = NULL; asn_enc_rval_t enc_rval; - int RRC_OK = 1; char temp_buff[ASN_MAX_ENCODE_SIZE]; NR_UE_CapabilityRAT_ContainerList_t *ue_cap_rat_container_list = NULL; NR_UE_CapabilityRAT_Container_t *ue_cap_rat_container_MRDC = NULL; @@ -4441,7 +4452,6 @@ static int encode_CG_ConfigInfo( = calloc(1,sizeof(struct NR_CG_ConfigInfo_IEs)); AssertFatal(cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo != NULL, "failed to allocate memory for cg_configinfo_IEs"); - if(ue_context_pP->ue_context.UE_Capability_MRDC) { RAT_Container_count++; enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UE_MRDC_Capability,NULL, @@ -4611,6 +4621,7 @@ rrc_eNB_process_MeasurementReport( //= measResults2->measResultNeighCells->choice.measResultNeighCellListNR_r15.list.array[0]->pci_r15; = measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[0]->physCellId; + X2AP_ENDC_SGNB_ADDITION_REQ(msg).target_physCellId = 0; //For the moment we have a single E-RAB which will be the one to be added to the gNB //Not sure how to select bearers to be added if there are multiple. X2AP_ENDC_SGNB_ADDITION_REQ(msg).nb_e_rabs_tobeadded = 1; @@ -4624,7 +4635,7 @@ rrc_eNB_process_MeasurementReport( sizeof(transport_layer_addr_t)); } - LOG_I(RRC, + LOG_A(RRC, "[eNB %d] frame %d subframe %d: UE rnti %x switching to NSA mode\n", ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->subframe, ctxt_pP->rnti); itti_send_msg_to_task(TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), msg); @@ -4668,6 +4679,10 @@ rrc_eNB_process_MeasurementReport( if (ue_context_pP->ue_context.measResults->measResultNeighCells == NULL) { ue_context_pP->ue_context.measResults->measResultNeighCells = CALLOC(1, sizeof(*ue_context_pP->ue_context.measResults->measResultNeighCells)); } + if (!ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array) { + ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array = + calloc(neighboring_cells, sizeof(*ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array)); + } for (i=0; i < neighboring_cells; i++) { if (i>=ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.count) { @@ -4677,6 +4692,11 @@ rrc_eNB_process_MeasurementReport( ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->physCellId = measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->physCellId; + + if (!ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrpResult) + ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrpResult = calloc(1, sizeof(*ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrpResult)); + if (!ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrqResult) + ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrqResult = calloc(1, sizeof(*ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrqResult)); ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrpResult = measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrpResult; ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrqResult = @@ -5144,7 +5164,9 @@ check_handovers( // Configure target ue_context_p->ue_context.handover_info->state = HO_FORWARDING; msg = itti_alloc_new_message(TASK_RRC_ENB, 0, X2AP_HANDOVER_REQ_ACK); - rrc_eNB_generate_HO_RRCConnectionReconfiguration(ctxt_pP, ue_context_p, X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer, + rrc_eNB_generate_HO_RRCConnectionReconfiguration(ctxt_pP, ue_context_p, + X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer, + RRC_BUF_SIZE, // TODO: supposed to be size of the .rrc_buffer. Is this right? &X2AP_HANDOVER_REQ_ACK(msg).rrc_buffer_size); rrc_eNB_configure_rbs_handover(ue_context_p,ctxt_pP); X2AP_HANDOVER_REQ_ACK(msg).rnti = ue_context_p->ue_context.rnti; @@ -5306,6 +5328,7 @@ void rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, uint8_t *buffer, + size_t buffer_size, int *_size //const uint8_t ho_state ) @@ -6247,11 +6270,12 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct measurements_enabled = RC.rrc[ENB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)]->configuration.enable_x2 || RC.rrc[ENB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)]->configuration.enable_measurement_reports; - memset(buffer, 0, RRC_BUF_SIZE); + memset(buffer, 0, buffer_size); char rrc_buf[1000 /* arbitrary, should be big enough, has to be less than size of return buf by a few bits/bytes */]; int rrc_size; rrc_size = do_RRCConnectionReconfiguration(ctxt_pP, (unsigned char *)rrc_buf, + sizeof(rrc_buf), xid, //Transaction_id, NULL, // SRB_configList NULL, @@ -6287,7 +6311,7 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct char *ho_buf = (char *)buffer; int ho_size; ho_size = do_HandoverCommand( - ho_buf, 1024 /* TODO: this is the value found in struct x2ap_handover_req_ack_s for array rrc_buffer */, + ho_buf, buffer_size, rrc_buf, rrc_size); *_size = size = ho_size; @@ -7791,47 +7815,6 @@ is_ul_256QAM_supported( && *c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->rf_Parameters_v1430->supportedBandCombination_v1430->list.array[0]->bandParameterList_v1430->list.array[0]->ul_256QAM_r14==LTE_BandParameters_v1430__ul_256QAM_r14_supported; } -static int -is_en_dc_supported( - LTE_UE_EUTRA_Capability_t *c -) -//----------------------------------------------------------------------------- -{ - /* to be refined - check that the bands supported by the UE include - * the band of the gNB - */ - return c != NULL // R8 - && c->NCE != NULL // R92 - && c->NCE->NCE != NULL // R94 - && c->NCE->NCE->NCE != NULL // R102 - && c->NCE->NCE->NCE->NCE != NULL // R106 - && c->NCE->NCE->NCE->NCE->NCE != NULL // R109 - && c->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R113 - && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R117 - && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R118 - && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R11a - && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R125 - && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // R126 - && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // 127 - && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL // 128 - && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //131 - && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //132 - && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //133 - && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //134 - && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //135 - && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //136 - && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //143 - && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //144 - && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //145 - && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //146 - && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE != NULL //151 - && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->irat_ParametersNR_r15 != NULL - && c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->irat_ParametersNR_r15->en_DC_r15 != NULL - && *c->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->NCE->irat_ParametersNR_r15->en_DC_r15 == - LTE_IRAT_ParametersNR_r15__en_DC_r15_supported; -#undef NCE -} - int to_nr_rsrpq(long rsrpq_result,int nr_band) { switch(nr_band) { @@ -7902,7 +7885,6 @@ rrc_eNB_decode_dcch( Srb_id); } - //memset(ul_dcch_msg,0,sizeof(UL_DCCH_Message_t)); LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Decoding UL-DCCH Message\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); dec_rval = uper_decode( @@ -7994,7 +7976,7 @@ rrc_eNB_decode_dcch( /*FK: left the condition as is for the case MME is used (S1 mode) but setting dedicated_DRB = 1 otherwise (noS1 mode) so that no second RRCReconfiguration message activationg more DRB is sent as this causes problems with the nasmesh driver.*/ int flexran_agent_handover = 0; - if (EPC_MODE_ENABLED) { + if (EPC_MODE_ENABLED || get_softmodem_params()->emulate_l1) { if (ue_context_p->ue_context.StatusRrc == RRC_RECONFIGURED) { dedicated_DRB = 1; LOG_I(RRC, @@ -8067,6 +8049,7 @@ rrc_eNB_decode_dcch( rrc_eNB_send_E_RAB_Modification_Indication(ctxt_pP, ue_context_p); /* send reconfiguration complete to gNB */ rrc_eNB_process_reconfiguration_complete_endc(ctxt_pP, ue_context_p); + LOG_A(RRC, "Sent rrcReconfigurationComplete to gNB\n"); } } } @@ -8430,12 +8413,13 @@ rrc_eNB_decode_dcch( xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)ul_dcch_msg); } - LOG_I(RRC, "got UE capabilities for UE %x\n", ctxt_pP->rnti); + LOG_A(RRC, "got UE capabilities for UE %x\n", ctxt_pP->rnti); int eutra_index = -1; for (i = 0; i < ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.count; i++) { if (ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.array[i]->rat_Type == LTE_RAT_Type_nr) { + LOG_A(RRC, "got nrUE capabilities for UE %x\n", ctxt_pP->rnti); if(ue_context_p->ue_context.UE_Capability_nr) { ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability,ue_context_p->ue_context.UE_Capability_nr); ue_context_p->ue_context.UE_Capability_nr = 0; @@ -8541,7 +8525,13 @@ rrc_eNB_decode_dcch( if (dec_rval.code == RC_OK) { /* do NR only if at least one gNB connected */ if (RC.rrc[ctxt_pP->module_id]->num_gnb_cells != 0) + { + allocate_en_DC_r15(ue_context_p->ue_context.UE_Capability); + if (!is_en_dc_supported(ue_context_p->ue_context.UE_Capability)){ + LOG_E(RRC, "We did not properly allocate en_DC_r15 for UE_EUTRA_Capability\n"); + } ue_context_p->ue_context.does_nr = is_en_dc_supported(ue_context_p->ue_context.UE_Capability); + } else ue_context_p->ue_context.does_nr = 0; } @@ -10053,7 +10043,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink( { uint8_t buffer[RRC_BUF_SIZE]; uint16_t size = 0; - memset(buffer, 0, RRC_BUF_SIZE); + memset(buffer, 0, sizeof(buffer)); // allocate dedicated pools for UE -sl-CommConfig/sl-DiscConfig (sl-V2X-ConfigDedicated) //populate dedicated resources for SL communication (sl-CommConfig) @@ -10066,6 +10056,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink( sl_CommConfig[0] = rrc_eNB_get_sidelink_commTXPool(ctxt_pP, ue_context_pP, destinationInfoList); size = do_RRCConnectionReconfiguration(ctxt_pP, buffer, + sizeof(buffer), rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id), //Transaction_id (LTE_SRB_ToAddModList_t *)NULL, (LTE_DRB_ToAddModList_t *)NULL, @@ -10088,6 +10079,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink( sl_DiscConfig[0] = rrc_eNB_get_sidelink_discTXPool(ctxt_pP, ue_context_pP, n_discoveryMessages ); size = do_RRCConnectionReconfiguration(ctxt_pP, buffer, + sizeof(buffer), rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id), //Transaction_id (LTE_SRB_ToAddModList_t *)NULL, (LTE_DRB_ToAddModList_t *)NULL, diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index 4a472c8841..a2e65a1687 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -593,14 +593,20 @@ rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP( S1AP_INITIAL_CONTEXT_SETUP_RESP (msg_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id; for (e_rab = 0; e_rab < ue_context_pP->ue_context.nb_of_e_rabs; e_rab++) { - if (ue_context_pP->ue_context.e_rab[e_rab].status == E_RAB_STATUS_DONE) { + if (ue_context_pP->ue_context.e_rab[e_rab].status == E_RAB_STATUS_DONE || ue_context_pP->ue_context.e_rab[e_rab].status == E_RAB_STATUS_TOMODIFY) { e_rabs_done++; S1AP_INITIAL_CONTEXT_SETUP_RESP (msg_p).e_rabs[e_rab].e_rab_id = ue_context_pP->ue_context.e_rab[e_rab].param.e_rab_id; // TODO add other information from S1-U when it will be integrated S1AP_INITIAL_CONTEXT_SETUP_RESP (msg_p).e_rabs[e_rab].gtp_teid = ue_context_pP->ue_context.enb_gtp_teid[e_rab]; S1AP_INITIAL_CONTEXT_SETUP_RESP (msg_p).e_rabs[e_rab].eNB_addr = ue_context_pP->ue_context.enb_gtp_addrs[e_rab]; S1AP_INITIAL_CONTEXT_SETUP_RESP (msg_p).e_rabs[e_rab].eNB_addr.length = 4; - ue_context_pP->ue_context.e_rab[e_rab].status = E_RAB_STATUS_ESTABLISHED; + if (ue_context_pP->ue_context.e_rab[e_rab].status == E_RAB_STATUS_DONE) { + ue_context_pP->ue_context.e_rab[e_rab].status = E_RAB_STATUS_ESTABLISHED; + S1AP_INITIAL_CONTEXT_SETUP_RESP (msg_p).nb_of_e_rabs = e_rabs_done; + S1AP_INITIAL_CONTEXT_SETUP_RESP (msg_p).nb_of_e_rabs_failed = e_rabs_failed; + itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p); + } + } else { e_rabs_failed++; ue_context_pP->ue_context.e_rab[e_rab].status = E_RAB_STATUS_FAILED; @@ -619,9 +625,6 @@ rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP( ue_context_pP->ue_id_rnti, S1AP_INITIAL_CONTEXT_SETUP_RESP (msg_p).eNB_ue_s1ap_id, e_rabs_done, e_rabs_failed); - S1AP_INITIAL_CONTEXT_SETUP_RESP (msg_p).nb_of_e_rabs = e_rabs_done; - S1AP_INITIAL_CONTEXT_SETUP_RESP (msg_p).nb_of_e_rabs_failed = e_rabs_failed; - itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p); } //------------------------------------------------------------------------------ @@ -1981,7 +1984,7 @@ int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance message_p = itti_alloc_new_message (TASK_RRC_ENB, 0, RRC_PCCH_DATA_REQ); /* Create message for PDCP (DLInformationTransfer_t) */ length = do_Paging (instance, - buffer, + buffer, sizeof(buffer), S1AP_PAGING_IND(msg_p).ue_paging_identity, S1AP_PAGING_IND(msg_p).cn_domain); diff --git a/openair2/RRC/LTE/rrc_eNB_endc.c b/openair2/RRC/LTE/rrc_eNB_endc.c index 3d3d9787b5..a2792adba5 100644 --- a/openair2/RRC/LTE/rrc_eNB_endc.c +++ b/openair2/RRC/LTE/rrc_eNB_endc.c @@ -171,8 +171,10 @@ int rrc_eNB_generate_RRCConnectionReconfiguration_endc(protocol_ctxt_t *ctxt, OCTET_STRING_t dummy_scg_conf; unsigned char scg_conf_buf[4] = { 0, 0, 0, 0 }; - if (scg_group_config!=NULL) + if (scg_group_config!=NULL) { nr.choice.setup.nr_SecondaryCellGroupConfig_r15 = scg_group_config; //&scg_conf; + LOG_E(RRC, "setting scg_group_config\n"); + } else{ nr.choice.setup.nr_SecondaryCellGroupConfig_r15 = &dummy_scg_conf; dummy_scg_conf.buf = scg_conf_buf; @@ -197,8 +199,10 @@ int rrc_eNB_generate_RRCConnectionReconfiguration_endc(protocol_ctxt_t *ctxt, OCTET_STRING_t dummy_nr1_conf; unsigned char nr1_buf[4] = { 0, 0, 0, 0 }; - if(scg_RB_config!=NULL) + if(scg_RB_config!=NULL) { cr_1510.nr_RadioBearerConfig1_r15 = scg_RB_config; + LOG_E(RRC, "setting scg_RB_config\n"); + } else{ cr_1510.nr_RadioBearerConfig1_r15 = &dummy_nr1_conf; dummy_nr1_conf.buf = nr1_buf; @@ -230,7 +234,8 @@ int rrc_eNB_generate_RRCConnectionReconfiguration_endc(protocol_ctxt_t *ctxt, (void *)&dl_dcch_msg, buffer, buffer_size); - + AssertFatal (enc_rval.encoded > 0, "asn_DEF_LTE_DL_DCCH_Message message encoding failed (%s, %jd)!\n", + enc_rval.failed_type->name, enc_rval.encoded); { int len = (enc_rval.encoded + 7) / 8; int i; diff --git a/openair2/RRC/LTE/rrc_proto.h b/openair2/RRC/LTE/rrc_proto.h index c50ddf3189..f0456005f5 100644 --- a/openair2/RRC/LTE/rrc_proto.h +++ b/openair2/RRC/LTE/rrc_proto.h @@ -31,6 +31,8 @@ * @{ */ +#pragma once + #include "RRC/LTE/rrc_defs.h" #include "x2ap_messages_types.h" #include "flexran_agent_extern.h" @@ -103,6 +105,7 @@ rrc_ue_decode_dcch( const protocol_ctxt_t *const ctxt_pP, const rb_id_t Srb_id, const uint8_t *const Buffer, + const uint32_t Buffer_size, const uint8_t eNB_indexP ); @@ -310,6 +313,7 @@ void rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, uint8_t *buffer, + size_t buffer_size, int *_size //const uint8_t ho_state ); @@ -354,6 +358,12 @@ void *rrc_enb_task(void *args_p); \param void *args_p Pointer on arguments to start the task. */ void *rrc_ue_task(void *args_p); +/**\brief RRC NSA UE task. + \param void *args_p Pointer on arguments to start the task. */ +void *recv_msgs_from_nr_ue(void *args_p); + +void init_connections_with_nr_ue(void); + void rrc_eNB_process_x2_setup_request(int mod_id, x2ap_setup_req_t *m); void rrc_eNB_process_x2_setup_response(int mod_id, x2ap_setup_resp_t *m); diff --git a/openair2/RRC/LTE/rrc_types.h b/openair2/RRC/LTE/rrc_types.h index 9c1e37494f..6b339af563 100644 --- a/openair2/RRC/LTE/rrc_types.h +++ b/openair2/RRC/LTE/rrc_types.h @@ -61,4 +61,18 @@ typedef enum Rrc_Sub_State_e { RRC_SUB_STATE_CONNECTED_LAST = RRC_SUB_STATE_CONNECTED, } Rrc_Sub_State_t; +typedef enum Rrc_Msg_Type_e { + UE_CAPABILITY_DUMMY = 0xa0, + UE_CAPABILITY_ENQUIRY, + NRUE_CAPABILITY_ENQUIRY, + UE_CAPABILITY_INFO, + NRUE_CAPABILITY_INFO, + RRC_MEASUREMENT_PROCEDURE, + NR_UE_RRC_MEASUREMENT, + RRC_CONFIG_COMPLETE_REQ, + NR_RRC_CONFIG_COMPLETE_REQ, + OAI_TUN_IFACE_NSA +} Rrc_Msg_Type_t; + + #endif /* RRC_TYPES_H_ */ diff --git a/openair2/RRC/LTE/rrc_vars.h b/openair2/RRC/LTE/rrc_vars.h index b1a0121c00..dfb019193c 100644 --- a/openair2/RRC/LTE/rrc_vars.h +++ b/openair2/RRC/LTE/rrc_vars.h @@ -42,6 +42,8 @@ UE_RRC_INST *UE_rrc_inst = NULL; #include "LAYER2/MAC/mac_extern.h" #define MAX_U32 0xFFFFFFFF +extern uint16_t ue_id_g; + uint8_t DRB2LCHAN[8]; long logicalChannelGroup0 = 0; diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 8bd949aa67..84a0cf75d1 100755 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -1767,6 +1767,7 @@ uint8_t do_NR_SA_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, uint8_t do_NR_RRCRelease(uint8_t *buffer, + size_t buffer_size, uint8_t Transaction_id) { asn_enc_rval_t enc_rval; NR_DL_DCCH_Message_t dl_dcch_msg; @@ -1792,7 +1793,7 @@ uint8_t do_NR_RRCRelease(uint8_t *buffer, NULL, (void *)&dl_dcch_msg, buffer, - RRC_BUF_SIZE); + buffer_size); if(enc_rval.encoded == -1) { LOG_I(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); @@ -1805,6 +1806,7 @@ uint8_t do_NR_RRCRelease(uint8_t *buffer, int16_t do_RRCReconfiguration( const protocol_ctxt_t *const ctxt_pP, uint8_t *buffer, + size_t buffer_size, uint8_t Transaction_id, NR_SRB_ToAddModList_t *SRB_configList, NR_DRB_ToAddModList_t *DRB_configList, @@ -1900,7 +1902,7 @@ int16_t do_RRCReconfiguration( NULL, (void *)&dl_dcch_msg, buffer, - 1000); + buffer_size); if(enc_rval.encoded == -1) { LOG_I(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", @@ -1925,7 +1927,7 @@ int16_t do_RRCReconfiguration( } -uint8_t do_RRCSetupRequest(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv) { +uint8_t do_RRCSetupRequest(uint8_t Mod_id, uint8_t *buffer, size_t buffer_size, uint8_t *rv) { asn_enc_rval_t enc_rval; uint8_t buf[5],buf2=0; NR_UL_CCCH_Message_t ul_ccch_msg; @@ -1969,16 +1971,51 @@ uint8_t do_RRCSetupRequest(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv) { NULL, (void *)&ul_ccch_msg, buffer, - 100); + buffer_size); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); LOG_D(NR_RRC,"[UE] RRCSetupRequest Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8); return((enc_rval.encoded+7)/8); } + +//------------------------------------------------------------------------------ +uint8_t +do_NR_RRCReconfigurationComplete_for_nsa( + uint8_t *buffer, + size_t buffer_size, + NR_RRC_TransactionIdentifier_t Transaction_id +) +//------------------------------------------------------------------------------ +{ + NR_RRCReconfigurationComplete_t rrc_complete_msg; + memset(&rrc_complete_msg, 0, sizeof(rrc_complete_msg)); + rrc_complete_msg.rrc_TransactionIdentifier = Transaction_id; + rrc_complete_msg.criticalExtensions.choice.rrcReconfigurationComplete = + CALLOC(1, sizeof(*rrc_complete_msg.criticalExtensions.choice.rrcReconfigurationComplete)); + rrc_complete_msg.criticalExtensions.present = + NR_RRCReconfigurationComplete__criticalExtensions_PR_rrcReconfigurationComplete; + rrc_complete_msg.criticalExtensions.choice.rrcReconfigurationComplete->nonCriticalExtension = NULL; + rrc_complete_msg.criticalExtensions.choice.rrcReconfigurationComplete->lateNonCriticalExtension = NULL; + if (0) { + xer_fprint(stdout, &asn_DEF_NR_RRCReconfigurationComplete, (void *)&rrc_complete_msg); + } + + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_RRCReconfigurationComplete, + NULL, + (void *)&rrc_complete_msg, + buffer, + buffer_size); + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + LOG_A(NR_RRC, "rrcReconfigurationComplete Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8); + return((enc_rval.encoded+7)/8); +} + //------------------------------------------------------------------------------ uint8_t do_NR_RRCReconfigurationComplete( const protocol_ctxt_t *const ctxt_pP, uint8_t *buffer, + size_t buffer_size, const uint8_t Transaction_id ) //------------------------------------------------------------------------------ @@ -2006,14 +2043,15 @@ do_NR_RRCReconfigurationComplete( NULL, (void *)&ul_dcch_msg, buffer, - 100); + buffer_size); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); LOG_I(NR_RRC,"rrcReconfigurationComplete Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); return((enc_rval.encoded+7)/8); } -uint8_t do_RRCSetupComplete(uint8_t Mod_id, uint8_t *buffer, const uint8_t Transaction_id, uint8_t sel_plmn_id, const int dedicatedInfoNASLength, const char *dedicatedInfoNAS){ +uint8_t do_RRCSetupComplete(uint8_t Mod_id, uint8_t *buffer, size_t buffer_size, + const uint8_t Transaction_id, uint8_t sel_plmn_id, const int dedicatedInfoNASLength, const char *dedicatedInfoNAS){ asn_enc_rval_t enc_rval; NR_UL_DCCH_Message_t ul_dcch_msg; @@ -2056,7 +2094,7 @@ enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message, NULL, (void *)&ul_dcch_msg, buffer, - 100); + buffer_size); AssertFatal(enc_rval.encoded > 0,"ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name,enc_rval.encoded); LOG_D(NR_RRC,"RRCSetupComplete Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); @@ -2171,6 +2209,7 @@ const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *const ue_context_pP, int CC_id, uint8_t *const buffer, +size_t buffer_size, //const uint8_t transmission_mode, const uint8_t Transaction_id, NR_SRB_ToAddModList_t **SRB_configList @@ -2293,7 +2332,7 @@ NR_SRB_ToAddModList_t **SRB_configList } uint8_t -do_RRCReestablishmentComplete(uint8_t *buffer, int64_t rrc_TransactionIdentifier) { +do_RRCReestablishmentComplete(uint8_t *buffer, size_t buffer_size, int64_t rrc_TransactionIdentifier) { asn_enc_rval_t enc_rval; NR_UL_DCCH_Message_t ul_dcch_msg; NR_RRCReestablishmentComplete_t *rrcReestablishmentComplete; @@ -2319,7 +2358,7 @@ do_RRCReestablishmentComplete(uint8_t *buffer, int64_t rrc_TransactionIdentifier NULL, (void *)&ul_dcch_msg, buffer, - 100); + buffer_size); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); LOG_D(NR_RRC,"[UE] RRCReestablishmentComplete Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8); return((enc_rval.encoded+7)/8); diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.h b/openair2/RRC/NR/MESSAGES/asn1_msg.h index 53aaf118c6..6803cf21d7 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.h +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.h @@ -28,6 +28,8 @@ * \email: raymond.knopp@eurecom.fr and navid.nikaein@eurecom.fr, kroempa@gmail.com */ +#pragma once + #include #include #include /* for atoi(3) */ @@ -128,12 +130,13 @@ uint8_t do_NR_SA_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, uint8_t *const buffer, const uint8_t Transaction_id); -uint8_t do_NR_RRCRelease(uint8_t *buffer, +uint8_t do_NR_RRCRelease(uint8_t *buffer, size_t buffer_size, uint8_t Transaction_id); int16_t do_RRCReconfiguration( const protocol_ctxt_t *const ctxt_pP, uint8_t *buffer, + size_t buffer_size, uint8_t Transaction_id, NR_SRB_ToAddModList_t *SRB_configList, NR_DRB_ToAddModList_t *DRB_configList, @@ -144,19 +147,23 @@ int16_t do_RRCReconfiguration( struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList, NR_MAC_CellGroupConfig_t *mac_CellGroupConfig, NR_CellGroupConfig_t *cellGroupConfig); - -uint8_t do_RRCSetupComplete(uint8_t Mod_id, - uint8_t *buffer, - const uint8_t Transaction_id, - uint8_t sel_plmn_id, - const int dedicatedInfoNASLength, + +uint8_t do_RRCSetupComplete(uint8_t Mod_id, + uint8_t *buffer, + size_t buffer_size, + const uint8_t Transaction_id, + uint8_t sel_plmn_id, + const int dedicatedInfoNASLength, const char *dedicatedInfoNAS); -uint8_t do_RRCSetupRequest(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv); +uint8_t do_RRCSetupRequest(uint8_t Mod_id, uint8_t *buffer, size_t buffer_size, uint8_t *rv); + +uint8_t do_NR_RRCReconfigurationComplete_for_nsa(uint8_t *buffer, size_t buffer_size, NR_RRC_TransactionIdentifier_t Transaction_id); uint8_t do_NR_RRCReconfigurationComplete( const protocol_ctxt_t *const ctxt_pP, uint8_t *buffer, + size_t buffer_size, const uint8_t Transaction_id ); @@ -181,6 +188,7 @@ do_RRCReestablishment( rrc_gNB_ue_context_t *const ue_context_pP, int CC_id, uint8_t *const buffer, + size_t buffer_size, //const uint8_t transmission_mode, const uint8_t Transaction_id, NR_SRB_ToAddModList_t **SRB_configList @@ -188,6 +196,6 @@ do_RRCReestablishment( uint8_t do_RRCReestablishmentComplete( - uint8_t *buffer, + uint8_t *buffer, size_t buffer_size, int64_t rrc_TransactionIdentifier); diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 820c880bb1..e233e070fe 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -123,12 +123,12 @@ typedef enum UE_STATE_NR_e { #define RRM_CALLOC(t,n) (t *) malloc16( sizeof(t) * n) #define RRM_CALLOC2(t,s) (t *) malloc16( s ) -#define MAX_MEAS_OBJ 6 -#define MAX_MEAS_CONFIG 6 -#define MAX_MEAS_ID 6 +#define MAX_MEAS_OBJ 7 +#define MAX_MEAS_CONFIG 7 +#define MAX_MEAS_ID 7 #define PAYLOAD_SIZE_MAX 1024 -#define RRC_BUF_SIZE 8192 +#define RRC_BUF_SIZE 512 #define UNDEF_SECURITY_MODE 0xff #define NO_SECURITY_MODE 0x20 diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 335b4ca1cc..9ce3eefce8 100755 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -316,6 +316,8 @@ void rrc_gNB_process_AdditionRequestInformation(const module_id_t gnb_mod_idP, x AssertFatal(cg_configinfo->criticalExtensions.choice.c1->present == NR_CG_ConfigInfo__criticalExtensions__c1_PR_cg_ConfigInfo, "ueCapabilityInformation not present\n"); parse_CG_ConfigInfo(rrc,cg_configinfo,m); + LOG_A(NR_RRC, "Successfully parsed CG_ConfigInfo of size %zu bits. (%zu bytes)\n", + dec_rval.consumed, (dec_rval.consumed +7/8)); } @@ -790,8 +792,8 @@ rrc_gNB_generate_defaultRRCReconfiguration( dedicatedNAS_MessageList = NULL; } - memset(buffer, 0, RRC_BUF_SIZE); - size = do_RRCReconfiguration(ctxt_pP, buffer, + memset(buffer, 0, sizeof(buffer)); + size = do_RRCReconfiguration(ctxt_pP, buffer, sizeof(buffer), xid, NULL, //*SRB_configList2, NULL, //*DRB_configList, @@ -1058,10 +1060,10 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( dedicatedNAS_MessageList = NULL; } - memset(buffer, 0, RRC_BUF_SIZE); + memset(buffer, 0, sizeof(buffer)); cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); fill_mastercellGroupConfig(cellGroupConfig, ue_context_pP->ue_context.masterCellGroup); - size = do_RRCReconfiguration(ctxt_pP, buffer, + size = do_RRCReconfiguration(ctxt_pP, buffer, sizeof(buffer), xid, *SRB_configList2, *DRB_configList, @@ -1169,8 +1171,8 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release( LOG_W(NR_RRC,"dedlicated NAS list is empty\n"); } - memset(buffer, 0, RRC_BUF_SIZE); - size = do_RRCReconfiguration(ctxt_pP, buffer, xid, + memset(buffer, 0, sizeof(buffer)); + size = do_RRCReconfiguration(ctxt_pP, buffer, sizeof(buffer), xid, NULL, NULL, *DRB_Release_configList2, @@ -1480,6 +1482,7 @@ rrc_gNB_generate_RRCReestablishment( ue_context_pP, CC_id, (uint8_t *) ue_context->Srb0.Tx_buffer.Payload, + sizeof(ue_context->Srb0.Tx_buffer.Payload), //(uint8_t) carrier->p_gNB, // at this point we do not have the UE capability information, so it can only be TM1 or TM2 rrc_gNB_get_next_transaction_identifier(module_id), SRB_configList @@ -1735,9 +1738,9 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete( i, ue_context_pP->ue_context.pduSession[i].status, "PDU_SESSION_STATUS_DONE"); } - memset(buffer, 0, RRC_BUF_SIZE); + memset(buffer, 0, sizeof(buffer)); - size = do_RRCReconfiguration(ctxt_pP, buffer, + size = do_RRCReconfiguration(ctxt_pP, buffer, sizeof(buffer), xid, *SRB_configList2, DRB_configList, @@ -3713,7 +3716,7 @@ void *rrc_gnb_task(void *args_p) { break; case X2AP_ENDC_SGNB_RECONF_COMPLETE: - LOG_I(NR_RRC, "Handling of reconfiguration complete message at RRC gNB is pending \n"); + LOG_A(NR_RRC, "Handling of reconfiguration complete message at RRC gNB is pending \n"); break; case NGAP_INITIAL_CONTEXT_SETUP_REQ: @@ -3940,9 +3943,10 @@ rrc_gNB_generate_RRCRelease( uint8_t buffer[RRC_BUF_SIZE]; uint16_t size = 0; - memset(buffer, 0, RRC_BUF_SIZE); + memset(buffer, 0, sizeof(buffer)); - size = do_NR_RRCRelease(buffer,rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id)); + size = do_NR_RRCRelease(buffer, sizeof(buffer), + rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id)); ue_context_pP->ue_context.ue_reestablishment_timer = 0; ue_context_pP->ue_context.ue_release_timer = 0; ue_context_pP->ue_context.ul_failure_timer = 0; diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 00a2a56566..3acdc9d445 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -1055,7 +1055,7 @@ rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ( uint8_t nb_pdusessions_tosetup = NGAP_PDUSESSION_SETUP_REQ(msg_p).nb_pdusessions_tosetup; pdu_sessions_done = 0; - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0); + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, 0); for (int i = 0; i < NR_NB_RB_MAX - 3; i++) { if(ue_context_p->ue_context.pduSession[i].status >= PDU_SESSION_STATUS_DONE) continue; diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 3311779235..932127b3f9 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -123,6 +123,7 @@ void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, NR_UE_CapabilityRAT_ContainerL if ( LOG_DEBUGFLAG(DEBUG_ASN1) && ueCapabilityRAT_Container_MRDC != NULL ) { xer_fprint(stdout, &asn_DEF_NR_UE_MRDC_Capability, ue_context_p->ue_context.UE_Capability_MRDC); } + LOG_A(NR_RRC, "Successfully decoded UE NR capabilities (NR and MRDC)\n"); rrc_add_nsa_user(rrc,ue_context_p, m); } @@ -292,14 +293,18 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ create_tunnel_req.num_tunnels = m->nb_e_rabs_tobeadded; RB_INSERT(rrc_nr_ue_tree_s, &RC.nrrrc[rrc->module_id]->rrc_ue_head, ue_context_p); PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, ue_context_p->ue_id_rnti, 0, 0,rrc->module_id); - gtpv1u_create_s1u_tunnel( - ctxt.instance, - &create_tunnel_req, - &create_tunnel_resp); - rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( - &ctxt, - &create_tunnel_resp, - &inde_list[0]); + memset(&create_tunnel_resp, 0, sizeof(create_tunnel_resp)); + if (!IS_SOFTMODEM_NOS1) { + LOG_D(RRC, "Calling gtpv1u_create_s1u_tunnel()\n"); + gtpv1u_create_s1u_tunnel( + ctxt.instance, + &create_tunnel_req, + &create_tunnel_resp); + rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( + &ctxt, + &create_tunnel_resp, + &inde_list[0]); + } X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).nb_e_rabs_admitted_tobeadded = m->nb_e_rabs_tobeadded; X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).target_assoc_id = m->target_assoc_id; @@ -337,7 +342,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ NULL, (void *)CG_Config, X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer, - 1024); + sizeof(X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer)); X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer_size = (enc_rval.encoded+7)>>3; itti_send_msg_to_task(TASK_X2AP, ENB_MODULE_ID_TO_INSTANCE(0), msg); //Check right id instead of hardcoding } else if (get_softmodem_params()->do_ra || get_softmodem_params()->sa) { diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c index 5c9293dcf9..6f0c7fc27f 100644 --- a/openair2/RRC/NR_UE/L2_interface_ue.c +++ b/openair2/RRC/NR_UE/L2_interface_ue.c @@ -149,7 +149,7 @@ int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP, } uint8_t -rrc_data_req_ue( +rrc_data_req_nr_ue( const protocol_ctxt_t *const ctxt_pP, const rb_id_t rb_idP, const mui_t muiP, diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 6892599ec0..4a04192248 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -49,10 +49,12 @@ #include "rrc_defs.h" #include "rrc_proto.h" #include "rrc_vars.h" +#include "rrc_extern.h" #include "LAYER2/NR_MAC_UE/mac_proto.h" #include "intertask_interface.h" +#include "nr-uesoftmodem.h" #include "executables/softmodem-common.h" #include "plmn_data.h" #include "pdcp.h" @@ -105,7 +107,7 @@ nr_rrc_ue_process_ueCapabilityEnquiry( ); void -nr_sa_rrc_ue_process_radioBearerConfig( +nr_rrc_ue_process_RadioBearerConfig( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index, NR_RadioBearerConfig_t *const radioBearerConfig @@ -114,11 +116,10 @@ nr_sa_rrc_ue_process_radioBearerConfig( uint8_t do_NR_RRCReconfigurationComplete( const protocol_ctxt_t *const ctxt_pP, uint8_t *buffer, + size_t buffer_size, const uint8_t Transaction_id ); -void rrc_ue_generate_RRCReestablishmentRequest( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index ); - void nr_rrc_ue_generate_rrcReestablishmentComplete( const protocol_ctxt_t *const ctxt_pP, @@ -233,16 +234,6 @@ int8_t nr_rrc_ue_decode_secondary_cellgroup_config(const module_id_t module_id, return 0; } -int8_t nr_rrc_ue_process_RadioBearerConfig(NR_RadioBearerConfig_t *RadioBearerConfig){ - - if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *) RadioBearerConfig); - } - // Configure PDCP - - return 0; -} - // from LTE-RRC DL-DCCH RRCConnectionReconfiguration nr-secondary-cell-group-config (decoded) // RRCReconfiguration int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCReconfiguration_t *rrcReconfiguration){ @@ -253,12 +244,15 @@ int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCR if(NR_UE_rrc_inst[module_id].radio_bearer_config == NULL){ NR_UE_rrc_inst[module_id].radio_bearer_config = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->radioBearerConfig; }else{ - nr_rrc_ue_process_RadioBearerConfig(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->radioBearerConfig); + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + struct NR_RadioBearerConfig *RadioBearerConfig = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->radioBearerConfig; + xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *) RadioBearerConfig); + } } } if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup != NULL){ - if(get_softmodem_params()->sa) { + if(get_softmodem_params()->sa || get_softmodem_params()->nsa) { NR_CellGroupConfig_t *cellGroupConfig = NULL; uper_decode(NULL, @@ -336,6 +330,10 @@ int8_t nr_rrc_ue_process_scg_config(const module_id_t module_id, NR_CellGroupCon }else{ // maintain list if(cell_group_config->spCellConfig != NULL){ + if (get_softmodem_params()->nsa) { + nr_rrc_mac_config_req_ue(0, 0, 0, NULL, NULL, cell_group_config, NULL); + LOG_D(NR_RRC, "Filled scc now \n"); + } if(cell_group_config->spCellConfig->spCellConfigDedicated != NULL){ // process element of list to be add by RRC message if(cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList != NULL){ @@ -375,7 +373,7 @@ void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, msg_len); if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { - LOG_E(RRC,"NR_RRCReconfiguration decode error\n"); + LOG_E(NR_RRC, "NR_RRCReconfiguration decode error\n"); // free the memory SEQUENCE_free( &asn_DEF_NR_RRCReconfiguration, RRCReconfiguration, 1 ); return; @@ -394,12 +392,26 @@ void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, msg_len); if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { - LOG_E(RRC,"NR_RadioBearerConfig decode error\n"); + LOG_E(NR_RRC, "NR_RadioBearerConfig decode error\n"); // free the memory SEQUENCE_free( &asn_DEF_NR_RadioBearerConfig, RadioBearerConfig, 1 ); return; } - nr_rrc_ue_process_RadioBearerConfig(RadioBearerConfig); + if (get_softmodem_params()->nsa) { + protocol_ctxt_t ctxt; + NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_id, ENB_FLAG_YES, mac->crnti, 0, 0, 0); + xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)RadioBearerConfig); + LOG_D(NR_RRC, "Calling fill_default_rbconfig_ue at %d with: e_rab_id = %ld, drbID = %ld, cipher_algo = %ld, key = %ld \n", + __LINE__, RadioBearerConfig->drb_ToAddModList->list.array[0]->cnAssociation->choice.eps_BearerIdentity, + RadioBearerConfig->drb_ToAddModList->list.array[0]->drb_Identity, + RadioBearerConfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm, + *RadioBearerConfig->securityConfig->keyToUse); + nr_rrc_ue_process_RadioBearerConfig(&ctxt, 0, RadioBearerConfig); + } + else if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *) RadioBearerConfig); + } } break; @@ -516,6 +528,10 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* rrc_config_path){ fclose(fd); process_nsa_message(NR_UE_rrc_inst, nr_RadioBearerConfigX_r15, buffer,msg_len); } + else if (get_softmodem_params()->nsa) + { + LOG_D(NR_RRC, "In NSA mode \n"); + } } else{ NR_UE_rrc_inst = NULL; @@ -561,7 +577,8 @@ int8_t nr_rrc_ue_decode_NR_BCCH_BCH_Message( if (NR_UE_rrc_inst[module_id].mib != NULL) SEQUENCE_free( &asn_DEF_NR_BCCH_BCH_Message, (void *)bcch_message, 1 ); - else LOG_I(NR_RRC,"Configuring MAC for first MIB reception\n"); + else + LOG_A(NR_RRC, "Configuring MAC for first MIB reception\n"); asn_dec_rval_t dec_rval = uper_decode_complete(NULL, &asn_DEF_NR_BCCH_BCH_Message, @@ -589,13 +606,6 @@ int8_t nr_rrc_ue_decode_NR_BCCH_BCH_Message( return 0; } -const char siWindowLength[10][5] = {"5s", "10s", "20s", "40s", "80s", "160s", "320s", "640s", "1280s","ERR"};// {"1ms","2ms","5ms","10ms","15ms","20ms","40ms","80ms","ERR"}; -const short siWindowLength_int[9] = {5,10,20,40,80,160,320,640,1280};//{1,2,5,10,15,20,40,80}; - -const char SIBType[12][6] = {"SIB3","SIB4","SIB5","SIB6","SIB7","SIB8","SIB9","SIB10","SIB11","SIB12","SIB13","Spare"}; -const char SIBPeriod[8][6] = {"rf8","rf16","rf32","rf64","rf128","rf256","rf512","ERR"}; -int siPeriod_int[7] = {80,160,320,640,1280,2560,5120}; - const char *nr_SIBreserved( long value ) { if (value < 0 || value > 1) return "ERR"; @@ -1025,7 +1035,7 @@ int nr_decode_SI( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index // if (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIcnt == sib1->schedulingInfoList.list.count) // rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_SIB_COMPLETE ); - // LOG_I(RRC,"SIStatus %x, SIcnt %d/%d\n", + // LOG_I(NR_RRC, "SIStatus %x, SIcnt %d/%d\n", // NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus, // NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIcnt, // sib1->schedulingInfoList.list.count); @@ -1035,7 +1045,7 @@ int nr_decode_SI( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index return 0; } -int8_t check_requested_SI_List(module_id_t module_id, BIT_STRING_t requested_SI_List, NR_SIB1_t sib1) { +static int8_t check_requested_SI_List(module_id_t module_id, BIT_STRING_t requested_SI_List, NR_SIB1_t sib1) { if(sib1.si_SchedulingInfo) { @@ -1185,7 +1195,7 @@ int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(module_id_t module_id, if( g_log->log_component[NR_RRC].level >= OAILOG_DEBUG ) { xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void *) NR_UE_rrc_inst[module_id].sib1[gNB_index]); } - LOG_I(NR_RRC, "SIB1 decoded\n"); + LOG_A(NR_RRC, "SIB1 decoded\n"); /// dump_SIB1(); // FIXME: improve condition for the RA trigger @@ -1193,8 +1203,8 @@ int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(module_id_t module_id, check_requested_SI_List(module_id, NR_UE_rrc_inst[module_id].requested_SI_List, *sib1); if( nr_rrc_get_state(module_id) <= RRC_STATE_IDLE_NR ) { NR_UE_rrc_inst[module_id].ra_trigger = INITIAL_ACCESS_FROM_RRC_IDLE; - LOG_D(PHY,"Setting state to NR_RRC_SI_RECEIVED\n"); - nr_rrc_set_state (module_id, NR_RRC_SI_RECEIVED); + LOG_D(PHY,"Setting state to RRC_STATE_IDLE_NR\n"); + nr_rrc_set_state (module_id, RRC_STATE_IDLE_NR); } // take ServingCellConfigCommon and configure L1/L2 NR_UE_rrc_inst[module_id].servingCellConfigCommonSIB = sib1->servingCellConfigCommon; @@ -1375,7 +1385,8 @@ static void rrc_ue_generate_RRCSetupComplete( nas_msg = nr_nas_attach_req_imsi; nas_msg_length = sizeof(nr_nas_attach_req_imsi); } - size = do_RRCSetupComplete(ctxt_pP->module_id,buffer,Transaction_id,sel_plmn_id,nas_msg_length,nas_msg); + size = do_RRCSetupComplete(ctxt_pP->module_id, buffer, sizeof(buffer), + Transaction_id, sel_plmn_id, nas_msg_length, nas_msg); LOG_I(NR_RRC,"[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCSetupComplete (bytes%d, gNB %d)\n", ctxt_pP->module_id,ctxt_pP->frame, size, gNB_index); LOG_D(NR_RRC, @@ -1386,7 +1397,7 @@ static void rrc_ue_generate_RRCSetupComplete( //printf("\n"); // ctxt_pP_local.rnti = ctxt_pP->rnti; - rrc_data_req_ue(ctxt_pP, + rrc_data_req_nr_ue(ctxt_pP, DCCH, nr_rrc_mui++, SDU_CONFIRM_NO, @@ -1464,10 +1475,9 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB ctxt_pP, gNB_index, &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->masterCellGroup); - nr_sa_rrc_ue_process_radioBearerConfig( - ctxt_pP, - gNB_index, - &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->radioBearerConfig); + nr_rrc_ue_process_RadioBearerConfig(ctxt_pP, + gNB_index, + &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->radioBearerConfig); nr_rrc_set_state (ctxt_pP->module_id, RRC_STATE_CONNECTED); nr_rrc_set_sub_state (ctxt_pP->module_id, RRC_SUB_STATE_CONNECTED); NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].rnti = ctxt_pP->rnti; @@ -1737,7 +1747,7 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB GNB_RRC_DCCH_DATA_IND (message_p).size = (enc_rval.encoded + 7) / 8; itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p); #else - rrc_data_req_ue (ctxt_pP, + rrc_data_req_nr_ue (ctxt_pP, DCCH, nr_rrc_mui++, SDU_CONFIRM_NO, @@ -1775,6 +1785,7 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB do_RRCSetupRequest( module_id, (uint8_t *)NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.Payload, + sizeof(NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.Payload), rv); LOG_I(NR_RRC,"[UE %d] : Logical Channel UL-CCCH (SRB0), Generating RRCSetupRequest (bytes %d, gNB %d)\n", module_id, NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size, gNB_index); @@ -2015,7 +2026,7 @@ nr_rrc_ue_establish_srb2( //----------------------------------------------------------------------------- void - nr_sa_rrc_ue_process_radioBearerConfig( + nr_rrc_ue_process_RadioBearerConfig( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index, NR_RadioBearerConfig_t *const radioBearerConfig @@ -2206,7 +2217,7 @@ nr_rrc_ue_establish_srb2( } //----------------------------------------------------------------------------- - void + static void rrc_ue_process_rrcReconfiguration( const protocol_ctxt_t *const ctxt_pP, NR_RRCReconfiguration_t *rrcReconfiguration, @@ -2236,7 +2247,7 @@ nr_rrc_ue_establish_srb2( if (ie->radioBearerConfig != NULL) { LOG_I(NR_RRC, "radio Bearer Configuration is present\n"); - nr_sa_rrc_ue_process_radioBearerConfig(ctxt_pP, gNB_index, ie->radioBearerConfig); + nr_rrc_ue_process_RadioBearerConfig(ctxt_pP, gNB_index, ie->radioBearerConfig); } /* Check if there is dedicated NAS information to forward to NAS */ @@ -2264,7 +2275,7 @@ nr_rrc_ue_establish_srb2( //----------------------------------------------------------------------------- void nr_rrc_ue_generate_RRCReconfigurationComplete( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index, const uint8_t Transaction_id ) { uint8_t buffer[32], size; - size = do_NR_RRCReconfigurationComplete(ctxt_pP, buffer, Transaction_id); + size = do_NR_RRCReconfigurationComplete(ctxt_pP, buffer, sizeof(buffer), Transaction_id); LOG_I(NR_RRC,PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel UL-DCCH (SRB1), Generating RRCReconfigurationComplete (bytes %d, gNB_index %d)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), size, gNB_index); LOG_D(RLC, @@ -2289,7 +2300,7 @@ nr_rrc_ue_establish_srb2( itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p); #else - rrc_data_req_ue ( + rrc_data_req_nr_ue ( ctxt_pP, DCCH, nr_rrc_mui++, @@ -2308,6 +2319,7 @@ nr_rrc_ue_establish_srb2( const protocol_ctxt_t *const ctxt_pP, const srb_id_t Srb_id, const uint8_t *const Buffer, + size_t Buffer_size, const uint8_t gNB_indexP ) //----------------------------------------------------------------------------- @@ -2328,7 +2340,7 @@ nr_rrc_ue_establish_srb2( &asn_DEF_NR_DL_DCCH_Message, (void **)&dl_dcch_msg, Buffer, - RRC_BUF_SIZE, + Buffer_size, 0, 0); @@ -2510,6 +2522,7 @@ nr_rrc_ue_establish_srb2( &ctxt, NR_RRC_DCCH_DATA_IND (msg_p).dcch_index, NR_RRC_DCCH_DATA_IND (msg_p).sdu_p, + NR_RRC_DCCH_DATA_IND (msg_p).sdu_size, NR_RRC_DCCH_DATA_IND (msg_p).gNB_index); break; @@ -2561,14 +2574,14 @@ nr_rrc_ue_establish_srb2( #else // check if SRB2 is created, if yes request data_req on DCCH1 (SRB2) if(NR_UE_rrc_inst[ue_mod_id].SRB2_config[0] == NULL) { - rrc_data_req_ue (&ctxt, + rrc_data_req_nr_ue (&ctxt, DCCH, nr_rrc_mui++, SDU_CONFIRM_NO, length, buffer, PDCP_TRANSMISSION_MODE_CONTROL); } else { - rrc_data_req_ue (&ctxt, + rrc_data_req_nr_ue (&ctxt, DCCH1, nr_rrc_mui++, SDU_CONFIRM_NO, @@ -2669,6 +2682,11 @@ nr_rrc_ue_process_ueCapabilityEnquiry( OCTET_STRING_fromBuf(&ue_CapabilityRAT_Container.ue_CapabilityRAT_Container, (const char *)NR_UE_rrc_inst[ctxt_pP->module_id].UECapability, NR_UE_rrc_inst[ctxt_pP->module_id].UECapability_size); + + if (get_softmodem_params()->nsa == 1) { + OCTET_STRING_t * requestedFreqBandsNR = UECapabilityEnquiry->criticalExtensions.choice.ueCapabilityEnquiry->ue_CapabilityEnquiryExt; + nsa_sendmsg_to_lte_ue(requestedFreqBandsNR->buf, requestedFreqBandsNR->size, UE_CAPABILITY_INFO); + } // ue_CapabilityRAT_Container.ueCapabilityRAT_Container.buf = UE_rrc_inst[ue_mod_idP].UECapability; // ue_CapabilityRAT_Container.ueCapabilityRAT_Container.size = UE_rrc_inst[ue_mod_idP].UECapability_size; AssertFatal(UECapabilityEnquiry->criticalExtensions.present == NR_UECapabilityEnquiry__criticalExtensions_PR_ueCapabilityEnquiry, @@ -2694,7 +2712,7 @@ nr_rrc_ue_process_ueCapabilityEnquiry( xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg); } - LOG_I(RRC,"UECapabilityInformation Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); + LOG_I(NR_RRC, "UECapabilityInformation Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); #ifdef ITTI_SIM MessageDef *message_p; uint8_t *message_buffer; @@ -2708,7 +2726,7 @@ nr_rrc_ue_process_ueCapabilityEnquiry( GNB_RRC_DCCH_DATA_IND (message_p).size = (enc_rval.encoded + 7) / 8; itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p); #else - rrc_data_req_ue ( + rrc_data_req_nr_ue ( ctxt_pP, DCCH, nr_rrc_mui++, @@ -2721,36 +2739,6 @@ nr_rrc_ue_process_ueCapabilityEnquiry( } } -//----------------------------------------------------------------------------- -void rrc_ue_generate_RRCReestablishmentRequest( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index ) -{ - NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size = - do_RRCReestablishmentRequest( - ctxt_pP->module_id, - (uint8_t *)NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload, 1); - LOG_I(NR_RRC,"[UE %d] : Frame %d, Logical Channel UL-CCCH (SRB0), Generating RRCReestablishmentRequest (bytes %d, gNB %d)\n", - ctxt_pP->module_id, ctxt_pP->frame, NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size, gNB_index); - - for (int i=0; imodule_id].Srb0[gNB_index].Tx_buffer.payload_size; i++) { - LOG_T(NR_RRC,"%x.",NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload[i]); - } - - LOG_T(NR_RRC,"\n"); - -#ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM, - NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size); - memcpy (message_buffer, (uint8_t*)NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload, - NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size); - message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_CCCH_DATA_IND); - UE_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer; - UE_RRC_CCCH_DATA_IND (message_p).size = NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size; - itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p); -#endif -} - void nr_rrc_ue_generate_rrcReestablishmentComplete( const protocol_ctxt_t *const ctxt_pP, @@ -2761,7 +2749,8 @@ nr_rrc_ue_generate_rrcReestablishmentComplete( { uint32_t length; uint8_t buffer[100]; - length = do_RRCReestablishmentComplete(buffer, rrcReestablishment->rrc_TransactionIdentifier); + length = do_RRCReestablishmentComplete(buffer, sizeof(buffer), + rrcReestablishment->rrc_TransactionIdentifier); LOG_I(NR_RRC,"[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCReestablishmentComplete (bytes%d, gNB %d)\n", ctxt_pP->module_id,ctxt_pP->frame, length, gNB_index); #ifdef ITTI_SIM @@ -2778,3 +2767,224 @@ nr_rrc_ue_generate_rrcReestablishmentComplete( #endif } + +void *recv_msgs_from_lte_ue(void *args_p) +{ + itti_mark_task_ready (TASK_RRC_NSA_NRUE); + int from_lte_ue_fd = get_from_lte_ue_fd(); + for (;;) + { + nsa_msg_t msg; + int recvLen = recvfrom(from_lte_ue_fd, &msg, sizeof(msg), + MSG_WAITALL | MSG_TRUNC, NULL, NULL); + if (recvLen == -1) + { + LOG_E(NR_RRC, "%s: recvfrom: %s\n", __func__, strerror(errno)); + continue; + } + if (recvLen > sizeof(msg)) + { + LOG_E(NR_RRC, "%s: Received truncated message %d\n", __func__, recvLen); + continue; + } + process_lte_nsa_msg(&msg, recvLen); + } + return NULL; +} + +void start_oai_nrue_threads() +{ + init_queue(&nr_rach_ind_queue); + init_queue(&nr_rx_ind_queue); + init_queue(&nr_crc_ind_queue); + init_queue(&nr_uci_ind_queue); + init_queue(&nr_sfn_slot_queue); + init_queue(&nr_chan_param_queue); + init_queue(&nr_dl_tti_req_queue); + init_queue(&nr_tx_req_queue); + init_queue(&nr_ul_dci_req_queue); + init_queue(&nr_ul_tti_req_queue); + init_queue(&nr_wait_ul_tti_req_queue); + + if (sem_init(&sfn_slot_semaphore, 0, 0) != 0) + { + LOG_E(MAC, "sem_init() error\n"); + abort(); + } + + init_nrUE_standalone_thread(ue_id_g); + +} + +static void nsa_rrc_ue_process_ueCapabilityEnquiry(void) +{ + NR_UE_NR_Capability_t *UE_Capability_nr = CALLOC(1, sizeof(NR_UE_NR_Capability_t)); + NR_BandNR_t *nr_bandnr = CALLOC(1, sizeof(NR_BandNR_t)); + nr_bandnr->bandNR = 78; + ASN_SEQUENCE_ADD(&UE_Capability_nr->rf_Parameters.supportedBandListNR.list, nr_bandnr); + OAI_NR_UECapability_t *UECap = CALLOC(1, sizeof(OAI_NR_UECapability_t)); + UECap->UE_NR_Capability = UE_Capability_nr; + + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UE_NR_Capability, + NULL, + (void *)UE_Capability_nr, + &UECap->sdu[0], + MAX_UE_NR_CAPABILITY_SIZE); + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + UECap->sdu_size = (enc_rval.encoded + 7) / 8; + LOG_A(NR_RRC, "[NR_RRC] NRUE Capability encoded, %d bytes (%zd bits)\n", + UECap->sdu_size, enc_rval.encoded + 7); + + NR_UE_rrc_inst[0].UECap = UECap; + NR_UE_rrc_inst[0].UECapability = UECap->sdu; + NR_UE_rrc_inst[0].UECapability_size = UECap->sdu_size; + + NR_UE_CapabilityRAT_Container_t ue_CapabilityRAT_Container; + memset(&ue_CapabilityRAT_Container, 0, sizeof(NR_UE_CapabilityRAT_Container_t)); + ue_CapabilityRAT_Container.rat_Type = NR_RAT_Type_nr; + OCTET_STRING_fromBuf(&ue_CapabilityRAT_Container.ue_CapabilityRAT_Container, + (const char *)NR_UE_rrc_inst[0].UECapability, + NR_UE_rrc_inst[0].UECapability_size); + + nsa_sendmsg_to_lte_ue(ue_CapabilityRAT_Container.ue_CapabilityRAT_Container.buf, + ue_CapabilityRAT_Container.ue_CapabilityRAT_Container.size, + NRUE_CAPABILITY_INFO); +} + +void process_lte_nsa_msg(nsa_msg_t *msg, int msg_len) +{ + if (msg_len < sizeof(msg->msg_type)) + { + LOG_E(RRC, "Msg_len = %d\n", msg_len); + return; + } + LOG_D(NR_RRC, "Processing an NSA message\n"); + Rrc_Msg_Type_t msg_type = msg->msg_type; + uint8_t *const msg_buffer = msg->msg_buffer; + msg_len -= sizeof(msg->msg_type); + switch (msg_type) + { + case UE_CAPABILITY_ENQUIRY: + { + LOG_D(NR_RRC, "We are processing a %d message \n", msg_type); + NR_FreqBandList_t *nr_freq_band_list = NULL; + asn_dec_rval_t dec_rval = uper_decode_complete(NULL, + &asn_DEF_NR_FreqBandList, + (void **)&nr_freq_band_list, + msg_buffer, + msg_len); + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) + { + SEQUENCE_free(&asn_DEF_NR_FreqBandList, nr_freq_band_list, ASFM_FREE_EVERYTHING); + LOG_E(RRC, "Failed to decode UECapabilityInfo (%zu bits)\n", dec_rval.consumed); + break; + } + for (int i = 0; i < nr_freq_band_list->list.count; i++) + { + LOG_D(NR_RRC, "Received NR band information: %ld.\n", + nr_freq_band_list->list.array[i]->choice.bandInformationNR->bandNR); + } + MessageDef *dummy_msg = itti_alloc_new_message(TASK_RRC_NSA_UE, 0, UE_CAPABILITY_DUMMY); + LOG_D(NR_RRC, "We are calling nsa_sendmsg_to_lte_ue to send a UE_CAPABILITY_DUMMY\n"); + nsa_sendmsg_to_lte_ue(dummy_msg, sizeof(dummy_msg), UE_CAPABILITY_DUMMY); + LOG_A(NR_RRC, "Sent initial NRUE Capability response to LTE UE\n"); + break; + } + + case NRUE_CAPABILITY_ENQUIRY: + { + LOG_I(NR_RRC, "We are processing a %d message \n", msg_type); + NR_FreqBandList_t *nr_freq_band_list = NULL; + asn_dec_rval_t dec_rval = uper_decode_complete(NULL, + &asn_DEF_NR_FreqBandList, + (void **)&nr_freq_band_list, + msg_buffer, + msg_len); + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) + { + SEQUENCE_free(&asn_DEF_NR_FreqBandList, nr_freq_band_list, ASFM_FREE_EVERYTHING); + LOG_E(NR_RRC, "Failed to decode UECapabilityInfo (%zu bits)\n", dec_rval.consumed); + break; + } + LOG_I(NR_RRC, "Calling nsa_rrc_ue_process_ueCapabilityEnquiry\n"); + nsa_rrc_ue_process_ueCapabilityEnquiry(); + break; + } + + case RRC_MEASUREMENT_PROCEDURE: + { + LOG_I(NR_RRC, "We are processing a %d message \n", msg_type); + + LTE_MeasObjectToAddMod_t *nr_meas_obj = NULL; + asn_dec_rval_t dec_rval = uper_decode_complete(NULL, + &asn_DEF_LTE_MeasObjectToAddMod, + (void **)&nr_meas_obj, + msg_buffer, + msg_len); + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) + { + SEQUENCE_free(&asn_DEF_LTE_MeasObjectToAddMod, nr_meas_obj, ASFM_FREE_EVERYTHING); + LOG_E(RRC, "Failed to decode measurement object (%zu bits) %d\n", dec_rval.consumed, dec_rval.code); + break; + } + LOG_D(NR_RRC, "NR carrierFreq_r15 (ssb): %ld and sub carrier spacing:%ld\n", + nr_meas_obj->measObject.choice.measObjectNR_r15.carrierFreq_r15, + nr_meas_obj->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.subcarrierSpacingSSB_r15); + start_oai_nrue_threads(); + break; + } + case RRC_CONFIG_COMPLETE_REQ: + { + struct msg { + uint32_t RadioBearer_size; + uint32_t SecondaryCellGroup_size; + uint8_t trans_id; + uint8_t padding[3]; + uint8_t buffer[]; + } hdr; + AssertFatal(msg_len >= sizeof(hdr), "Bad received msg\n"); + memcpy(&hdr, msg_buffer, sizeof(hdr)); + LOG_I(NR_RRC, "We got an RRC_CONFIG_COMPLETE_REQ\n"); + uint32_t nr_RadioBearer_size = hdr.RadioBearer_size; + uint32_t nr_SecondaryCellGroup_size = hdr.SecondaryCellGroup_size; + AssertFatal(sizeof(hdr) + nr_RadioBearer_size + nr_SecondaryCellGroup_size <= msg_len, + "nr_RadioBearerConfig1_r15 size %d nr_SecondaryCellGroupConfig_r15 size %d sizeof(hdr) %zu, msg_len = %d\n", + nr_RadioBearer_size, + nr_SecondaryCellGroup_size, + sizeof(hdr), msg_len); + NR_RRC_TransactionIdentifier_t t_id = hdr.trans_id; + LOG_I(NR_RRC, "nr_RadioBearerConfig1_r15 size %d nr_SecondaryCellGroupConfig_r15 size %d t_id %ld\n", + nr_RadioBearer_size, + nr_SecondaryCellGroup_size, + t_id); + + uint8_t *nr_RadioBearer_buffer = msg_buffer + offsetof(struct msg, buffer); + uint8_t *nr_SecondaryCellGroup_buffer = nr_RadioBearer_buffer + nr_RadioBearer_size; + process_nsa_message(NR_UE_rrc_inst, nr_SecondaryCellGroupConfig_r15, nr_SecondaryCellGroup_buffer, + nr_SecondaryCellGroup_size); + process_nsa_message(NR_UE_rrc_inst, nr_RadioBearerConfigX_r15, nr_RadioBearer_buffer, nr_RadioBearer_size); + LOG_I(NR_RRC, "Calling do_NR_RRCReconfigurationComplete. t_id %ld \n", t_id); + uint8_t buffer[RRC_BUF_SIZE]; + size_t size = do_NR_RRCReconfigurationComplete_for_nsa(buffer, sizeof(buffer), t_id); + nsa_sendmsg_to_lte_ue(buffer, size, NR_RRC_CONFIG_COMPLETE_REQ); + break; + } + + case OAI_TUN_IFACE_NSA: + { + LOG_I(NR_RRC, "We got an OAI_TUN_IFACE_NSA!!\n"); + char cmd_line[RRC_BUF_SIZE]; + memcpy(cmd_line, msg_buffer, sizeof(cmd_line)); + LOG_D(NR_RRC, "Command line: %s\n", cmd_line); + if (background_system(cmd_line) != 0) + { + LOG_E(NR_RRC, "ESM-PROC - failed command '%s'", cmd_line); + } + break; + } + + default: + LOG_E(NR_RRC, "No NSA Message Found\n"); + } +} diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index b79cbb4bae..0da6748b32 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -59,9 +59,9 @@ #define NB_CNX_UE 2//MAX_MANAGED_RG_PER_MOBILE #define NB_SIG_CNX_UE 2 //MAX_MANAGED_RG_PER_MOBILE -#define MAX_MEAS_OBJ 6 -#define MAX_MEAS_CONFIG 6 -#define MAX_MEAS_ID 6 +#define MAX_MEAS_OBJ 7 +#define MAX_MEAS_CONFIG 7 +#define MAX_MEAS_ID 7 typedef uint32_t channel_t; diff --git a/openair2/RRC/NR_UE/rrc_nsa.c b/openair2/RRC/NR_UE/rrc_nsa.c new file mode 100644 index 0000000000..9e62243c65 --- /dev/null +++ b/openair2/RRC/NR_UE/rrc_nsa.c @@ -0,0 +1,85 @@ +#include +#include +#include +#include "common/utils/LOG/log.h" +#include "openair2/RRC/NR_UE/rrc_proto.h" + +static const char nsa_ipaddr[] = "127.0.0.1"; +static int from_lte_ue_fd = -1; +static int to_lte_ue_fd = -1; +uint16_t ue_id_g; + +int get_from_lte_ue_fd() +{ + return from_lte_ue_fd; +} + +void nsa_sendmsg_to_lte_ue(const void *message, size_t msg_len, MessagesIds msg_type) +{ + LOG_I(NR_RRC, "Entered %s \n", __FUNCTION__); + nsa_msg_t n_msg; + if (msg_len > sizeof(n_msg.msg_buffer)) + { + LOG_E(NR_RRC, "%s: message too big: %zu\n", __func__, msg_len); + abort(); + } + n_msg.msg_type = msg_type; + memcpy(n_msg.msg_buffer, message, msg_len); + size_t to_send = sizeof(n_msg.msg_type) + msg_len; + + struct sockaddr_in sa = + { + .sin_family = AF_INET, + .sin_port = htons(6007 + ue_id_g * 2), + }; + int sent = sendto(from_lte_ue_fd, &n_msg, to_send, 0, + (struct sockaddr *)&sa, sizeof(sa)); + if (sent == -1) + { + LOG_E(NR_RRC, "%s: sendto: %s\n", __func__, strerror(errno)); + return; + } + if (sent != to_send) + { + LOG_E(NR_RRC, "%s: Short send %d != %zu\n", __func__, sent, to_send); + return; + } + LOG_D(NR_RRC, "Sent a %d message to the LTE UE (%d bytes) \n", msg_type, sent); +} + +void init_connections_with_lte_ue(void) +{ + struct sockaddr_in sa = + { + .sin_family = AF_INET, + .sin_port = htons(6008 + ue_id_g * 2), + }; + AssertFatal(from_lte_ue_fd == -1, "from_lte_ue_fd %d was assigned already", from_lte_ue_fd); + from_lte_ue_fd = socket(AF_INET, SOCK_DGRAM, 0); + if (from_lte_ue_fd == -1) + { + LOG_E(NR_RRC, "%s: Error opening socket %d (%d:%s)\n", __FUNCTION__, from_lte_ue_fd, errno, strerror(errno)); + abort(); + } + + if (inet_aton(nsa_ipaddr, &sa.sin_addr) == 0) + { + LOG_E(NR_RRC, "Bad nsa_ipaddr '%s'\n", nsa_ipaddr); + abort(); + } + + if (bind(from_lte_ue_fd, (struct sockaddr *) &sa, sizeof(sa)) == -1) + { + LOG_E(NR_RRC,"%s: Failed to bind the socket\n", __FUNCTION__); + abort(); + } + + AssertFatal(to_lte_ue_fd == -1, "to_lte_ue_fd was assigned already"); + to_lte_ue_fd = socket(AF_INET, SOCK_DGRAM, 0); + if (to_lte_ue_fd == -1) + { + LOG_E(NR_RRC, "%s: Error opening socket %d (%d:%s)\n", __FUNCTION__, to_lte_ue_fd, errno, strerror(errno)); + abort(); + } + LOG_I(NR_RRC, "Started LTE-NR link in the nr-UE\n"); +} diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index 534da0112b..c9b3bf86a1 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -39,6 +39,19 @@ #include "NR_MeasConfig.h" #include "NR_CellGroupConfig.h" #include "NR_RadioBearerConfig.h" +#include "openair2/PHY_INTERFACE/queue_t.h" + +extern queue_t nr_rach_ind_queue; +extern queue_t nr_rx_ind_queue; +extern queue_t nr_crc_ind_queue; +extern queue_t nr_uci_ind_queue; +extern queue_t nr_sfn_slot_queue; +extern queue_t nr_chan_param_queue; +extern queue_t nr_dl_tti_req_queue; +extern queue_t nr_tx_req_queue; +extern queue_t nr_ul_dci_req_queue; +extern queue_t nr_ul_tti_req_queue; +extern queue_t nr_wait_ul_tti_req_queue; // // main_rrc.c // @@ -133,15 +146,40 @@ int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP, const rb_id_t Srb_id, uint8_t *buffer_pP); +uint8_t +rrc_data_req_nr_ue( + const protocol_ctxt_t *const ctxt_pP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_sizeP, + uint8_t *const buffer_pP, + const pdcp_transmission_mode_t modeP +); + /**\brief RRC UE task. \param void *args_p Pointer on arguments to start the task. */ void *rrc_nrue_task(void *args_p); +/**\brief RRC NSA UE task. + \param void *args_p Pointer on arguments to start the task. */ +void *recv_msgs_from_lte_ue(void *args_p); + +void init_connections_with_lte_ue(void); + +void nsa_sendmsg_to_lte_ue(const void *message, size_t msg_len, MessagesIds msg_type); + +void start_oai_nrue_threads(void); + /**\brief RRC UE generate RRCSetupRequest message. \param module_id module id \param gNB_index gNB index */ void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index); +void process_lte_nsa_msg(nsa_msg_t *msg, int msg_len); + +int get_from_lte_ue_fd(); + /** @}*/ #endif diff --git a/openair2/RRC/NR_UE/rrc_vars.h b/openair2/RRC/NR_UE/rrc_vars.h index 30c74debdd..ecb9335131 100644 --- a/openair2/RRC/NR_UE/rrc_vars.h +++ b/openair2/RRC/NR_UE/rrc_vars.h @@ -37,5 +37,6 @@ #include "rrc_defs.h" extern NR_UE_RRC_INST_t *NR_UE_rrc_inst; +extern uint16_t ue_id_g; #endif diff --git a/openair2/SIMULATION/NR_RRC/itti_sim.c b/openair2/SIMULATION/NR_RRC/itti_sim.c index 3b0d6e721b..e3792dca77 100644 --- a/openair2/SIMULATION/NR_RRC/itti_sim.c +++ b/openair2/SIMULATION/NR_RRC/itti_sim.c @@ -394,7 +394,7 @@ statis void init_pdcp(void) { pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT ; } - pdcp_module_init(pdcp_initmask); + pdcp_module_init(pdcp_initmask, 0); pdcp_set_rlc_data_req_func(rlc_data_req); pdcp_set_pdcp_data_ind_func(pdcp_data_ind); @@ -406,7 +406,7 @@ int create_tasks_nrue(uint32_t ue_nb) { itti_wait_ready(1); if (ue_nb > 0) { - printf("create TASK_RRC_NRUE\n"); + LOG_D(NR_RRC, "create TASK_RRC_NRUE\n"); if (itti_create_task (TASK_RRC_NRUE, rrc_nrue_task, NULL) < 0) { LOG_E(NR_RRC, "Create task for RRC UE failed\n"); return -1; diff --git a/openair2/UTIL/ASYNC_IF/socket_link.c b/openair2/UTIL/ASYNC_IF/socket_link.c index 51c5511675..eac0b91069 100644 --- a/openair2/UTIL/ASYNC_IF/socket_link.c +++ b/openair2/UTIL/ASYNC_IF/socket_link.c @@ -409,10 +409,14 @@ static int socket_udp_receive(int socket_fd, void *buf, int size) socklen_t slen = sizeof(client); int l; - l = recvfrom(socket_fd, buf, size, 0, (struct sockaddr *) &client, &slen); + l = recvfrom(socket_fd, buf, size, MSG_TRUNC, (struct sockaddr *) &client, &slen); //getsockname(socket_fd, (struct sockaddr *)&client, &slen); if (l == -1) goto error; if (l == 0) goto socket_closed; + if (l > size) { + LOG_E(MAC, "%s(%d). Message truncated. %d\n", __FUNCTION__, __LINE__, l); + return -1; + } return l; diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c index 7c3a89e7f4..9724e0cc38 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.c +++ b/openair2/X2AP/x2ap_eNB_generate_messages.c @@ -1734,7 +1734,9 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( X2AP_ERROR("Failed to encode ENDC X2 SgNB_addition request message\n"); return -1; } + # if 0 // TODO: Sanitizer complains we are trying to access this after free. free(ie->value.choice.MeNBtoSgNBContainer.buf); + #endif MSC_LOG_TX_MESSAGE (MSC_X2AP_SRC_ENB, MSC_X2AP_TARGET_ENB, NULL, 0, "0 X2Setup/initiatingMessage assoc_id %u", x2ap_eNB_data_p->assoc_id); x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 0); diff --git a/openair3/GTPV1-U/gtpv1u_eNB.c b/openair3/GTPV1-U/gtpv1u_eNB.c index 9cf429426c..6f5ef004b5 100644 --- a/openair3/GTPV1-U/gtpv1u_eNB.c +++ b/openair3/GTPV1-U/gtpv1u_eNB.c @@ -222,7 +222,7 @@ NwGtpv1uRcT gtpv1u_eNB_process_stack_req( * - END-MARKER */ case NW_GTPV1U_ULP_API_RECV_TPDU: { - uint8_t buffer[4096]; + uint8_t buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE]; uint32_t buffer_len; struct rrc_eNB_ue_context_s *ue_context_p; uint16_t msgType = NW_GTP_GPDU; @@ -908,7 +908,8 @@ gtpv1u_create_s1u_tunnel( do { s1u_teid = gtpv1u_new_teid(); - LOG_D(GTPU, "gtpv1u_create_s1u_tunnel() 0x%x %u(dec)\n", s1u_teid, s1u_teid); + LOG_I(GTPU, "gtpv1u_data_g %p\n", RC.gtpv1u_data_g); + LOG_I(GTPU, "gtpv1u_create_s1u_tunnel() 0x%x %u(dec)\n", s1u_teid, s1u_teid); stack_req.apiInfo.createTunnelEndPointInfo.teid = s1u_teid; stack_req.apiInfo.createTunnelEndPointInfo.hUlpSession = 0; stack_req.apiInfo.createTunnelEndPointInfo.hStackSession = 0; diff --git a/openair3/NAS/TOOLS/display.c b/openair3/NAS/TOOLS/display.c index 363fae76b8..0828eeb673 100644 --- a/openair3/NAS/TOOLS/display.c +++ b/openair3/NAS/TOOLS/display.c @@ -262,10 +262,10 @@ void display_usim_data(const char *filename) { kasme[USIM_K_ASME_SIZE] = '\0'; memcpy(kasme, data.securityctx.Kasme.value, USIM_K_ASME_SIZE); printf("\tKasme\t: \"%s\"\n", kasme); - printf("\tulNAScount\t: 0x%.8x\n", + /*printf("\tulNAScount\t: 0x%.8x\n", *(uint32_t*) data.securityctx.ulNAScount.value); printf("\tdlNAScount\t: 0x%.8x\n", - *(uint32_t*) data.securityctx.dlNAScount.value); + *(uint32_t*) data.securityctx.dlNAScount.value);*/ printf("\talgorithmID\t: 0x%.2x\n\n", data.securityctx.algorithmID.value[0]); diff --git a/openair3/NAS/UE/API/USIM/usim_api.c b/openair3/NAS/UE/API/USIM/usim_api.c index b882689f9b..7facdaba79 100644 --- a/openair3/NAS/UE/API/USIM/usim_api.c +++ b/openair3/NAS/UE/API/USIM/usim_api.c @@ -249,7 +249,9 @@ int usim_api_authenticate_test(usim_data_t *usim_data, LOG_TRACE(INFO, "USIM-API - Comparing the XMAC with the MAC included in AUTN Succeeded"); /* Verify that the received sequence number SQN is in the correct range */ - rc = _usim_api_check_sqn(*(uint32_t*)(sqn), sqn[USIM_API_SQN_SIZE - 1]); + uint32_t v; + memcpy(&v, sqn, sizeof(v)); + rc = _usim_api_check_sqn(v, sqn[USIM_API_SQN_SIZE - 1]); } @@ -392,7 +394,9 @@ int usim_api_authenticate(usim_data_t *usim_data, const OctetString* rand_pP, co LOG_TRACE(INFO, "USIM-API - Comparing the XMAC with the MAC included in AUTN Succeeded"); /* Verify that the received sequence number SQN is in the correct range */ - rc = _usim_api_check_sqn(*(uint32_t*)(sqn), sqn[USIM_API_SQN_SIZE - 1]); + uint32_t v; + memcpy(&v, sqn, sizeof(v)); + rc = _usim_api_check_sqn(v, sqn[USIM_API_SQN_SIZE - 1]); } diff --git a/openair3/NAS/UE/ESM/PdnConnectivity.c b/openair3/NAS/UE/ESM/PdnConnectivity.c index 3b5bad7529..d17b5fde3c 100644 --- a/openair3/NAS/UE/ESM/PdnConnectivity.c +++ b/openair3/NAS/UE/ESM/PdnConnectivity.c @@ -356,7 +356,7 @@ int esm_proc_pdn_connectivity_accept(nas_user_t *user, int pti, esm_proc_pdn_typ int pid = RETURNerror; char apn_first_char[4]; - LOG_VAR(char, str[128]); + char str[128] __attribute__((unused)); if (isprint(apn->value[0])) { apn_first_char[0] = '\0'; diff --git a/openair3/NAS/UE/ESM/esm_ebr_context.c b/openair3/NAS/UE/ESM/esm_ebr_context.c index 0c79fa3e3a..b801ca2ad5 100644 --- a/openair3/NAS/UE/ESM/esm_ebr_context.c +++ b/openair3/NAS/UE/ESM/esm_ebr_context.c @@ -51,6 +51,7 @@ Description Defines functions used to handle EPS bearer contexts. #include "assertions.h" #include "pdcp.h" #include "nfapi/oai_integration/vendor_ext.h" +#include "executables/softmodem-common.h" #include #include @@ -262,8 +263,7 @@ int esm_ebr_context_create( netmask = 32; strcpy(broadcast, ipv4_addr); } - - res = sprintf(command_line, + LOG_D(NAS, "setting commandline string: " "ip address add %s/%d broadcast %s dev %s%d && " "ip link set %s%d up && " "ip rule add from %s/32 table %d && " @@ -276,26 +276,67 @@ int esm_ebr_context_create( ipv4_addr, ueid + 10000, UE_NAS_USE_TUN ? "oaitun_ue" : "oip", ueid + 1, ueid + 10000); + if (!get_softmodem_params()->nsa) + { + res = sprintf(command_line, + "ip address add %s/%d broadcast %s dev %s%d && " + "ip link set %s%d up && " + "ip rule add from %s/32 table %d && " + "ip rule add to %s/32 table %d && " + "ip route add default dev %s%d table %d", + ipv4_addr, netmask, broadcast, + UE_NAS_USE_TUN ? "oaitun_ue" : "oip", ueid + 1, + UE_NAS_USE_TUN ? "oaitun_ue" : "oip", ueid + 1, + ipv4_addr, ueid + 10000, + ipv4_addr, ueid + 10000, + UE_NAS_USE_TUN ? "oaitun_ue" : "oip", + ueid + 1, ueid + 10000); - if ( res<0 ) { - LOG_TRACE(WARNING, "ESM-PROC - Failed to system command string"); - } + if ( res<0 ) { + LOG_TRACE(WARNING, "ESM-PROC - Failed to system command string"); + } - LOG_TRACE(INFO, "ESM-PROC - executing %s ", + /* Calling system() here disrupts UE's realtime processing in some cases. + * This may be because of the call to fork(), which, for some + * unidentified reason, interacts badly with other (realtime) threads. + * background_system() is a replacement mechanism relying on a + * background process that does the system() and reports result to + * the parent process (lte-softmodem, oaisim, ...). The background + * process is created very early in the life of the parent process. + * The processes interact through standard pipes. See + * common/utils/system.c for details. + */ + + LOG_TRACE(INFO, "ESM-PROC - executing %s ", command_line); + if (background_system(command_line) != 0) + { + LOG_TRACE(ERROR, "ESM-PROC - failed command '%s'", command_line); + } + } + else if (get_softmodem_params()->nsa) { + res = sprintf(command_line, + "ip address add %s/%d broadcast %s dev %s%d && " + "ip link set %s%d up && " + "ip rule add from %s/32 table %d && " + "ip rule add to %s/32 table %d && " + "ip route add default dev %s%d table %d", + ipv4_addr, netmask, broadcast, + UE_NAS_USE_TUN ? "oaitun_nru" : "oip", ueid + 1, + UE_NAS_USE_TUN ? "oaitun_nru" : "oip", ueid + 1, + ipv4_addr, ueid + 10000, + ipv4_addr, ueid + 10000, + UE_NAS_USE_TUN ? "oaitun_nru" : "oip", + ueid + 1, ueid + 10000); - /* Calling system() here disrupts UE's realtime processing in some cases. - * This may be because of the call to fork(), which, for some - * unidentified reason, interacts badly with other (realtime) threads. - * background_system() is a replacement mechanism relying on a - * background process that does the system() and reports result to - * the parent process (lte-softmodem, oaisim, ...). The background - * process is created very early in the life of the parent process. - * The processes interact through standard pipes. See - * common/utils/system.c for details. - */ - if (background_system(command_line) != 0) - LOG_TRACE(ERROR, "ESM-PROC - failed command '%s'", command_line); + if ( res<0 ) { + LOG_TRACE(WARNING, "ESM-PROC - Failed to system command string"); + } + LOG_D(NAS, "Sending NAS_OAI_TUN_NSA msg to LTE UE via itti\n"); + MessageDef *msg_p = itti_alloc_new_message(TASK_NAS_UE, 0, NAS_OAI_TUN_NSA); + memcpy(NAS_OAI_TUN_NSA(msg_p).buffer, command_line, sizeof(NAS_OAI_TUN_NSA(msg_p).buffer)); + itti_send_msg_to_task(TASK_RRC_UE, 0, msg_p); + } break; diff --git a/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c index be887623bb..88938c3c37 100644 --- a/openair3/NAS/UE/nas_ue_task.c +++ b/openair3/NAS/UE/nas_ue_task.c @@ -24,7 +24,7 @@ # include "intertask_interface.h" # include "nas_ue_task.h" # include "common/utils/LOG/log.h" - +# include "vendor_ext.h" # include "user_defs.h" # include "user_api.h" # include "nas_parser.h" @@ -42,6 +42,8 @@ extern unsigned char NB_eNB_INST; extern uint16_t NB_UE_INST; +uint16_t ue_idx_standalone = 0xFFFF; + char *make_port_str_from_ueid(const char *base_port_str, int ueid); static int nas_ue_process_events(nas_user_container_t *users, struct epoll_event *events, int nb_events) @@ -96,41 +98,89 @@ void *nas_ue_task(void *args_p) itti_mark_task_ready (TASK_NAS_UE); MSC_START_USE(); + LOG_I(NAS, "ue_idx_standalone val:: %u\n", ue_idx_standalone); /* Initialize UE NAS (EURECOM-NAS) */ - for (int i=0; i < users->count; i++) + // Intead of for loop for standalone mode + if (ue_idx_standalone == 0xFFFF) { - nas_user_t *user = &users->item[i]; - user->ueid=i; + for (int i = 0; i < users->count; i++) + { + nas_user_t *user = &users->item[i]; + user->ueid = i; - /* Get USIM data application filename */ - user->usim_data_store = memory_get_path_from_ueid(USIM_API_NVRAM_DIRNAME, USIM_API_NVRAM_FILENAME, user->ueid); - if ( user->usim_data_store == NULL ) { - LOG_E(NAS, "[UE %d] - Failed to get USIM data application filename", user->ueid); - exit(EXIT_FAILURE); + /* Get USIM data application filename */ + user->usim_data_store = memory_get_path_from_ueid(USIM_API_NVRAM_DIRNAME, USIM_API_NVRAM_FILENAME, user->ueid); + if (user->usim_data_store == NULL) + { + LOG_E(NAS, "[UE %d] - Failed to get USIM data application filename", user->ueid); + exit(EXIT_FAILURE); + } + + /* Get UE's data pathname */ + user->user_nvdata_store = memory_get_path_from_ueid(USER_NVRAM_DIRNAME, USER_NVRAM_FILENAME, user->ueid); + if (user->user_nvdata_store == NULL) + { + LOG_E(NAS, "[UE %d] - Failed to get USIM nvdata filename", user->ueid); + exit(EXIT_FAILURE); + } + + /* Get EMM data pathname */ + user->emm_nvdata_store = memory_get_path_from_ueid(EMM_NVRAM_DIRNAME, EMM_NVRAM_FILENAME, user->ueid); + if (user->emm_nvdata_store == NULL) + { + LOG_E(NAS, "[UE %d] - Failed to get EMM nvdata filename", user->ueid); + exit(EXIT_FAILURE); + } + + /* Initialize user interface (to exchange AT commands with user process) */ + nas_user_api_id_initialize(user); + /* allocate needed structures */ + user->user_at_commands = calloc_or_fail(sizeof(user_at_commands_t)); + user->at_response = calloc_or_fail(sizeof(at_response_t)); + user->lowerlayer_data = calloc_or_fail(sizeof(lowerlayer_data_t)); + /* Initialize NAS user */ + nas_user_initialize(user, &user_api_emm_callback, &user_api_esm_callback, FIRMWARE_VERSION); } + } + else + { + // use new parameter passed into lte-uesoftmodem which instead of looping + // calls functions on specific UE index. - /* Get UE's data pathname */ - user->user_nvdata_store = memory_get_path_from_ueid(USER_NVRAM_DIRNAME, USER_NVRAM_FILENAME, user->ueid); - if ( user->user_nvdata_store == NULL ) { - LOG_E(NAS, "[UE %d] - Failed to get USIM nvdata filename", user->ueid); - exit(EXIT_FAILURE); - } + nas_user_t *user = &users->item[0]; + user->ueid = ue_idx_standalone; + LOG_I(NAS, "[UE %d] Configuring\n", user->ueid); - /* Get EMM data pathname */ - user->emm_nvdata_store = memory_get_path_from_ueid(EMM_NVRAM_DIRNAME, EMM_NVRAM_FILENAME, user->ueid); - if ( user->emm_nvdata_store == NULL ) { - LOG_E(NAS, "[UE %d] - Failed to get EMM nvdata filename", user->ueid); - exit(EXIT_FAILURE); - } - - /* Initialize user interface (to exchange AT commands with user process) */ - nas_user_api_id_initialize(user); - /* allocate needed structures */ - user->user_at_commands = calloc_or_fail(sizeof(user_at_commands_t)); - user->at_response = calloc_or_fail(sizeof(at_response_t)); - user->lowerlayer_data = calloc_or_fail(sizeof(lowerlayer_data_t)); - /* Initialize NAS user */ - nas_user_initialize (user, &user_api_emm_callback, &user_api_esm_callback, FIRMWARE_VERSION); + /* Get USIM data application filename */ // + user->usim_data_store = memory_get_path_from_ueid(USIM_API_NVRAM_DIRNAME, USIM_API_NVRAM_FILENAME, user->ueid); + if (user->usim_data_store == NULL) + { + LOG_E(NAS, "[UE %d] - Failed to get USIM data application filename", user->ueid); + exit(EXIT_FAILURE); + } + /* Get UE's data pathname */ + user->user_nvdata_store = memory_get_path_from_ueid(USER_NVRAM_DIRNAME, USER_NVRAM_FILENAME, user->ueid); + if (user->user_nvdata_store == NULL) + { + LOG_E(NAS, "[UE %d] - Failed to get USIM nvdata filename", user->ueid); + exit(EXIT_FAILURE); + } + /* Get EMM data pathname */ + user->emm_nvdata_store = memory_get_path_from_ueid(EMM_NVRAM_DIRNAME, EMM_NVRAM_FILENAME, user->ueid); + if (user->emm_nvdata_store == NULL) + { + LOG_E(NAS, "[UE %d] - Failed to get EMM nvdata filename", user->ueid); + exit(EXIT_FAILURE); + } + /* Initialize user interface (to exchange AT commands with user process) */ + nas_user_api_id_initialize(user); + /* allocate needed structures */ + user->user_at_commands = calloc_or_fail(sizeof(user_at_commands_t)); + user->at_response = calloc_or_fail(sizeof(at_response_t)); + user->lowerlayer_data = calloc_or_fail(sizeof(lowerlayer_data_t)); + /* Initialize NAS user */ + nas_user_initialize(user, &user_api_emm_callback, &user_api_esm_callback, FIRMWARE_VERSION); + user->ueid = 0; } /* Set UE activation state */ diff --git a/openair3/UDP/udp_eNB_task.c b/openair3/UDP/udp_eNB_task.c index 05729ba6b1..8b9fc77bb1 100644 --- a/openair3/UDP/udp_eNB_task.c +++ b/openair3/UDP/udp_eNB_task.c @@ -235,7 +235,7 @@ udp_eNB_send_to( void udp_eNB_receiver(struct udp_socket_desc_s *udp_sock_pP) { - uint8_t l_buffer[2048]; + uint8_t l_buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE]; int n; socklen_t from_len; struct sockaddr_in addr; @@ -246,10 +246,13 @@ void udp_eNB_receiver(struct udp_socket_desc_s *udp_sock_pP) if (1) { from_len = (socklen_t)sizeof(struct sockaddr_in); - if ((n = recvfrom(udp_sock_pP->sd, l_buffer, sizeof(l_buffer), 0, + if ((n = recvfrom(udp_sock_pP->sd, l_buffer, sizeof(l_buffer), MSG_TRUNC, (struct sockaddr *)&addr, &from_len)) < 0) { LOG_E(UDP_, "Recvfrom failed %s\n", strerror(errno)); return; + } else if (n > sizeof(l_buffer)) { + LOG_E(UDP_, "%s(%d). Message truncated. %d\n", __FUNCTION__, __LINE__, n); + return; } else if (n == 0) { LOG_W(UDP_, "Recvfrom returned 0\n"); return; diff --git a/targets/COMMON/create_tasks.c b/targets/COMMON/create_tasks.c index 8b9631dca3..4463228dc7 100644 --- a/targets/COMMON/create_tasks.c +++ b/targets/COMMON/create_tasks.c @@ -59,7 +59,7 @@ int create_tasks(uint32_t enb_nb) { rc = itti_create_task (TASK_RRC_ENB, rrc_enb_task, NULL); AssertFatal(rc >= 0, "Create task for RRC eNB failed\n"); - if (EPC_MODE_ENABLED && ! ( split73==SPLIT73_DU ) ) { + if (get_softmodem_params()->emulate_l1 || (EPC_MODE_ENABLED && split73 != SPLIT73_DU)) { rc = itti_create_task(TASK_SCTP, sctp_eNB_task, NULL); AssertFatal(rc >= 0, "Create task for SCTP failed\n"); } @@ -73,12 +73,13 @@ int create_tasks(uint32_t enb_nb) { } rc = itti_create_task(TASK_GTPV1_U, gtpv1u_eNB_task, NULL); AssertFatal(rc >= 0, "Create task for GTPV1U failed\n"); - if (is_x2ap_enabled()) { + } + + if (is_x2ap_enabled()) { rc = itti_create_task(TASK_X2AP, x2ap_task, NULL); AssertFatal(rc >= 0, "Create task for X2AP failed\n"); - } else { + } else { LOG_I(X2AP, "X2AP is disabled.\n"); - } } if (NODE_IS_CU(type)) { diff --git a/targets/COMMON/create_tasks_mbms.c b/targets/COMMON/create_tasks_mbms.c index 8b1736853f..1cd3bb2f3a 100644 --- a/targets/COMMON/create_tasks_mbms.c +++ b/targets/COMMON/create_tasks_mbms.c @@ -51,6 +51,7 @@ int create_tasks_mbms(uint32_t enb_nb) { // LOG_D(ENB_APP, "%s(enb_nb:%d\n", __FUNCTION__, enb_nb); // ngran_node_t type = RC.rrc[0]->node_type; + AssertFatal(!get_softmodem_params()->nsa, "In NSA mode\n"); int rc; if (enb_nb == 0) return 0; diff --git a/targets/COMMON/create_tasks_ue.c b/targets/COMMON/create_tasks_ue.c index 3b9b7cf7bb..9341107af9 100644 --- a/targets/COMMON/create_tasks_ue.c +++ b/targets/COMMON/create_tasks_ue.c @@ -22,6 +22,7 @@ # include "intertask_interface.h" # include "create_tasks.h" # include "common/utils/LOG/log.h" +# include "executables/softmodem-common.h" #include "sctp_eNB_task.h" #include "s1ap_eNB.h" @@ -63,6 +64,15 @@ int create_tasks_ue(uint32_t ue_nb) { LOG_E(RRC, "Create task for RRC UE failed\n"); return -1; } + + if (get_softmodem_params()->nsa) { + init_connections_with_nr_ue(); + LOG_I(RRC, "Started LTE-NR link in the LTE UE\n"); + if (itti_create_task (TASK_RRC_NSA_UE, recv_msgs_from_nr_ue, NULL) < 0) { + LOG_E(RRC, "Create task for RRC NSA UE failed\n"); + return -1; + } + } } itti_wait_ready(0); diff --git a/targets/COMMON/openairinterface5g_limits.h b/targets/COMMON/openairinterface5g_limits.h index 9260fe2701..d68292bd39 100644 --- a/targets/COMMON/openairinterface5g_limits.h +++ b/targets/COMMON/openairinterface5g_limits.h @@ -28,7 +28,7 @@ # ifndef PHYSIM # ifndef UE_EXPANSION -# define NUMBER_OF_UE_MAX 4 +# define NUMBER_OF_UE_MAX 40 # define NUMBER_OF_NR_UE_MAX 4 # define NUMBER_OF_CONNECTED_eNB_MAX 1 # define NUMBER_OF_CONNECTED_gNB_MAX 1 diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 632a47707b..f20f8267ed 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -398,8 +398,20 @@ static void *L1_thread( void *param ) { // set default return value eNB_thread_rxtx_status = 0; sprintf(thread_name,"RXn_TXnp4_%d\n",&eNB->proc.L1_proc == proc ? 0 : 1); +#if 1 + { + struct sched_param sparam = + { + .sched_priority = 79, + }; + if (pthread_setschedparam(pthread_self(), SCHED_RR, &sparam) != 0) + { + LOG_E(PHY,"pthread_setschedparam: %s\n", strerror(errno)); + } + } +#else thread_top_init(thread_name,1,470000,500000,500000); - pthread_setname_np( pthread_self(),"rxtx processing"); +#endif LOG_I(PHY,"thread rxtx created id=%ld\n", syscall(__NR_gettid)); while (!oai_exit) { @@ -943,7 +955,16 @@ void init_eNB_proc(int inst) { //pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, &proc_rxtx[0] ); //pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, eNB_thread_rxtx, &proc_rxtx[1] ); pthread_create( &L1_proc->pthread, attr0, L1_thread, L1_proc ); + if (pthread_setname_np(L1_proc->pthread, "oai:enb-L1-rx") != 0) + { + LOG_E(PHY, "pthread_setname_np: %s\n", strerror(errno)); + } + pthread_create( &L1_proc_tx->pthread, attr1, L1_thread, L1_proc_tx); + if (pthread_setname_np(L1_proc_tx->pthread, "oai:enb-L1-tx") != 0) + { + LOG_E(PHY, "pthread_setname_np: %s\n", strerror(errno)); + } } if (NFAPI_MODE!=NFAPI_MODE_VNF) { diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 10ba121c44..20644388c8 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -1490,6 +1490,7 @@ static void *ru_stats_thread(void *param) { static void *ru_thread_tx( void *param ) { RU_t *ru = (RU_t *)param; RU_proc_t *proc = &ru->proc; + __attribute__((unused)) LTE_DL_FRAME_PARMS *fp = ru->frame_parms; PHY_VARS_eNB *eNB; L1_proc_t *eNB_proc; @@ -1917,7 +1918,8 @@ static void *ru_thread( void *param ) { // This thread run the initial synchronization like a UE void *ru_thread_synch(void *arg) { RU_t *ru = (RU_t *)arg; - LTE_DL_FRAME_PARMS *fp; + __attribute__((unused)) + LTE_DL_FRAME_PARMS *fp = ru->frame_parms; int64_t peak_val, avg; static int ru_thread_synch_status = 0; int cnt=0; diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index f229ecf086..8cc693623b 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -94,6 +94,9 @@ unsigned short config_frames[4] = {2,9,11,13}; #include "NB_IoT_interface.h" #include +#if USING_GPROF +# include "sys/gmon.h" +#endif pthread_cond_t nfapi_sync_cond; pthread_mutex_t nfapi_sync_mutex; @@ -489,7 +492,7 @@ static void init_pdcp(void) { pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_W_MBMS_BIT; - pdcp_module_init(pdcp_initmask); + pdcp_module_init(pdcp_initmask, 0); if (NODE_IS_CU(RC.rrc[0]->node_type)) { pdcp_set_rlc_data_req_func(cu_send_to_du); @@ -515,6 +518,13 @@ static void wait_nfapi_init(char *thread_name) { int main ( int argc, char **argv ) { + set_priority(79); + if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) + { + fprintf(stderr, "mlockall: %s\n", strerror(errno)); + return EXIT_FAILURE; + } + int i; int CC_id = 0; int ru_id; @@ -741,10 +751,19 @@ int main ( int argc, char **argv ) if(IS_SOFTMODEM_DOSCOPE) load_softscope("enb",NULL); itti_wait_tasks_end(); + +#if USING_GPROF + // Save the gprof data now (rather than via atexit) in case we crash while shutting down + fprintf(stderr, "Recording gprof data...\n"); + _mcleanup(); + fprintf(stderr, "Recording gprof data...done\n"); +#endif // USING_GPROF + oai_exit=1; LOG_I(ENB_APP,"oai_exit=%d\n",oai_exit); // stop threads + #if 0 //Disable clean up because this tends to crash (and unnecessary) if (RC.nb_inst == 0 || !NODE_IS_CU(node_type)) { if(IS_SOFTMODEM_DOSCOPE) end_forms(); @@ -786,7 +805,9 @@ int main ( int argc, char **argv ) } } } + #endif + pdcp_module_cleanup(); terminate_opt(); logClean(); printf("Bye.\n"); diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index a1b261f263..4154d6c8db 100644 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -114,7 +114,9 @@ {"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:(char **)&usrp_args, defstrval:"type=b200",TYPE_STRING, 0}, \ {"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \ {"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \ - {"A", CONFIG_HLP_TADV, 0, iptr:&(timingadv), defintval:0, TYPE_INT, 0} \ + {"A", CONFIG_HLP_TADV, 0, iptr:&(timingadv), defintval:0, TYPE_INT, 0}, \ + {"ue-idx-standalone", NULL, 0, u16ptr:&ue_idx_standalone, defuintval:0xFFFF, TYPE_UINT16, 0}, \ + {"node-number", NULL, 0, u16ptr:&node_number, defuintval:2, TYPE_UINT16, 0}, \ } /*-----------------------------------------------------------------------------------------------------------------------------*/ @@ -138,6 +140,9 @@ extern pthread_cond_t sync_cond; extern pthread_mutex_t sync_mutex; extern int sync_var; +extern uint16_t ue_id_g; +extern uint16_t node_number; + extern uint64_t downlink_frequency[MAX_NUM_CCs][4]; extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; @@ -208,7 +213,10 @@ extern int stop_L1L2(module_id_t enb_id); extern int restart_L1L2(module_id_t enb_id); extern void init_UE_stub_single_thread(int nb_inst, int eMBMS_active, int uecap_xer_in, char *emul_iface); +extern void init_UE_standalone_thread(int ue_idx); extern PHY_VARS_UE *init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms, uint8_t UE_id, uint8_t abstraction_flag); +extern void init_bler_table(void); + #endif diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 1fae6c1e66..70e4677943 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -81,18 +81,10 @@ void init_UE_threads(int); void init_UE_threads_stub(int); void init_UE_single_thread_stub(int); void *UE_thread(void *arg); -void init_UE(int nb_inst,int eMBMS_active, int uecap_xer_in, int timing_correction, int phy_test, int UE_scan, int UE_scan_carrier, runmode_t mode,int rxgain,int txpowermax,LTE_DL_FRAME_PARMS *fp); -void init_UE_stub(int nb_inst,int,int,char *); -void init_UE_stub_single_thread(int nb_inst,int,int,char *); int init_timer_thread(void); -extern void oai_subframe_ind(uint16_t sfn, uint16_t sf); extern void multicast_link_start(void (*rx_handlerP) (unsigned int, char *), - unsigned char _multicast_group, char *multicast_ifname); -extern int oai_nfapi_crc_indication(nfapi_crc_indication_t *crc_ind); -extern int oai_nfapi_cqi_indication(nfapi_cqi_indication_t *cqi_ind); -extern int oai_nfapi_harq_indication(nfapi_harq_indication_t *harq_ind); -extern int oai_nfapi_sr_indication(nfapi_sr_indication_t *ind); -extern int oai_nfapi_rx_ind(nfapi_rx_indication_t *ind); + unsigned char _multicast_group, + char *multicast_ifname); extern int multicast_link_write_sock(int groupP, char *dataP, uint32_t sizeP); @@ -194,7 +186,7 @@ PHY_VARS_UE *init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms, ue->mac_enabled = 1; // In phy_stub_UE (MAC-to-MAC) mode these init functions don't need to get called. Is this correct? - if (NFAPI_MODE!=NFAPI_UE_STUB_PNF) { + if (NFAPI_MODE!=NFAPI_UE_STUB_PNF && NFAPI_MODE!=NFAPI_MODE_STANDALONE_PNF) { // initialize all signal buffers init_lte_ue_signal(ue,1,abstraction_flag); // intialize transport @@ -413,15 +405,31 @@ void init_UE_stub_single_thread(int nb_inst, // PHY_vars_UE_g[inst][0] = init_ue_vars(NULL,inst,0); } - init_timer_thread(); + if(NFAPI_MODE != NFAPI_MODE_STANDALONE_PNF) { + init_timer_thread(); + } + init_UE_single_thread_stub(nb_inst); printf("UE threads created \n"); - LOG_I(PHY,"Starting multicast link on %s\n",emul_iface); - if(NFAPI_MODE!=NFAPI_UE_STUB_PNF) + if(NFAPI_MODE!=NFAPI_UE_STUB_PNF && NFAPI_MODE!=NFAPI_MODE_STANDALONE_PNF) { + LOG_I(PHY,"Starting multicast link on %s\n",emul_iface); multicast_link_start(ue_stub_rx_handler,0,emul_iface); + } } +void init_UE_standalone_thread(int ue_idx) +{ + int standalone_tx_port = 3211 + ue_idx * 2; + int standalone_rx_port = 3212 + ue_idx * 2; + ue_init_standalone_socket(standalone_tx_port, standalone_rx_port); + + pthread_t thread; + if (pthread_create(&thread, NULL, ue_standalone_pnf_task, NULL) != 0) { + LOG_E(MAC, "pthread_create failed for calling ue_standalone_pnf_task"); + } + pthread_setname_np(thread, "oai:ue-stand"); +} void init_UE_stub(int nb_inst, int eMBMS_active, @@ -449,7 +457,7 @@ void init_UE_stub(int nb_inst, printf("UE threads created \n"); LOG_I(PHY,"Starting multicast link on %s\n",emul_iface); - if(NFAPI_MODE!=NFAPI_UE_STUB_PNF) + if(NFAPI_MODE!=NFAPI_UE_STUB_PNF && NFAPI_MODE!=NFAPI_MODE_STANDALONE_PNF) multicast_link_start(ue_stub_rx_handler,0,emul_iface); } @@ -956,6 +964,396 @@ void ue_stub_rx_handler(unsigned int num_bytes, } } +uint64_t clock_usec(void) +{ + struct timespec t; + if (clock_gettime(CLOCK_MONOTONIC, &t) == -1) + { + abort(); + } + return (uint64_t)t.tv_sec * 1000000 + (t.tv_nsec / 1000); +} +/*! + * \brief This is the UE thread for RX subframe n and TX subframe n+4. + * This thread performs the phy_procedures_UE_RX() on every received slot. + * then, if TX is enabled it performs TX for n+4. + * \param arg is a pointer to a \ref PHY_VARS_UE structure. + * \returns a pointer to an int. The storage is not on the heap and must not be freed. + */ + +static void *UE_phy_stub_standalone_pnf_task(void *arg) +{ +#if 1 + { + struct sched_param sparam = + { + .sched_priority = 79, + }; + if (pthread_setschedparam(pthread_self(), SCHED_RR, &sparam) != 0) + { + LOG_E(PHY,"pthread_setschedparam: %s\n", strerror(errno)); + } + } +#else + thread_top_init("UE_phy_stub_thread_rxn_txnp4", 1, 870000L, 1000000L, 1000000L); +#endif + + // for multipule UE's L2-emulator + //module_id_t Mod_id = 0; + //int init_ra_UE = -1; // This counter is used to initiate the RA of each UE in different SFrames + struct rx_tx_thread_data *rtd = arg; + + if (rtd == NULL) { + LOG_E(MAC, "[SCHED][UE] rx_tx_thread_data *rtd: NULL pointer\n"); + exit_fun("nothing to add"); + } + + UE_rxtx_proc_t *proc = rtd->proc; + // settings for nfapi-L2-emulator mode + module_id_t ue_thread_id = rtd->ue_thread_id; + uint16_t ue_index = 0; + uint16_t ue_num = NB_UE_INST / NB_THREAD_INST + ((NB_UE_INST % NB_THREAD_INST > ue_thread_id) ? 1 : 0); + module_id_t ue_Mod_id; + PHY_VARS_UE *UE = NULL; + int ret; + proc = &PHY_vars_UE_g[0][0]->proc.proc_rxtx[0]; + + UE = rtd->UE; + + UL_INFO = (UL_IND_t *)calloc(1, sizeof(UL_IND_t)); + UL_INFO->rx_ind.rx_indication_body.rx_pdu_list = calloc(NFAPI_RX_IND_MAX_PDU, sizeof(nfapi_rx_indication_pdu_t)); + UL_INFO->rx_ind.rx_indication_body.number_of_pdus = 0; + UL_INFO->crc_ind.crc_indication_body.crc_pdu_list = calloc(NFAPI_CRC_IND_MAX_PDU, sizeof(nfapi_crc_indication_pdu_t)); + UL_INFO->crc_ind.crc_indication_body.number_of_crcs = 0; + UL_INFO->harq_ind.harq_indication_body.harq_pdu_list = calloc(NFAPI_HARQ_IND_MAX_PDU, sizeof(nfapi_harq_indication_pdu_t)); + UL_INFO->harq_ind.harq_indication_body.number_of_harqs = 0; + UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = calloc(NFAPI_SR_IND_MAX_PDU, sizeof(nfapi_sr_indication_pdu_t)); + UL_INFO->sr_ind.sr_indication_body.number_of_srs = 0; + UL_INFO->cqi_ind.cqi_indication_body.cqi_pdu_list = calloc(NFAPI_CQI_IND_MAX_PDU, sizeof(nfapi_cqi_indication_pdu_t)); + UL_INFO->cqi_ind.cqi_indication_body.cqi_raw_pdu_list = calloc(NFAPI_CQI_IND_MAX_PDU, sizeof(nfapi_cqi_indication_raw_pdu_t)); + UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis = 0; + + proc->subframe_rx = proc->sub_frame_start; + proc->subframe_tx = -1; + proc->frame_rx = -1; + proc->frame_tx = -1; + // Initializations for nfapi-L2-emulator mode + sync_var = 0; + + //PANOS: CAREFUL HERE! + wait_sync("UE_phy_stub_standalone_pnf_task"); + + int last_sfn_sf = -1; + + LOG_I(MAC, "Clearing Queues\n"); + reset_queue(&dl_config_req_tx_req_queue); + reset_queue(&ul_config_req_queue); + reset_queue(&hi_dci0_req_queue); + + while (!oai_exit) { + bool sent_any = false; + if (sem_wait(&sfn_semaphore) != 0) { + LOG_E(MAC, "sem_wait() error\n"); + abort(); + } + + int sfn_sf = current_sfn_sf; + if (sfn_sf == last_sfn_sf) + { + LOG_W(MAC, "repeated sfn_sf = %d.%d\n", + sfn_sf >> 4, sfn_sf & 15); + continue; + } + last_sfn_sf = sfn_sf; + + nfapi_dl_config_req_tx_req_t *dl_config_req_tx_req = get_queue(&dl_config_req_tx_req_queue); + nfapi_ul_config_request_t *ul_config_req = get_queue(&ul_config_req_queue); + nfapi_hi_dci0_request_t *hi_dci0_req = get_queue(&hi_dci0_req_queue); + + LOG_I(MAC, "received from proxy frame %d subframe %d\n", + NFAPI_SFNSF2SFN(sfn_sf), NFAPI_SFNSF2SF(sfn_sf)); + + if (ul_config_req != NULL) { + uint8_t ul_num_pdus = ul_config_req->ul_config_request_body.number_of_pdus; + if (ul_num_pdus > 0) { + char *ul_str = nfapi_ul_config_req_to_string(ul_config_req); + LOG_I(MAC, "ul_config_req: %s\n", ul_str); + free(ul_str); + } + } + if (hi_dci0_req != NULL) { + LOG_D(MAC, "hi_dci0_req pdus: %u Frame: %d Subframe: %d\n", + hi_dci0_req->hi_dci0_request_body.number_of_dci, + NFAPI_SFNSF2SFN(hi_dci0_req->sfn_sf), NFAPI_SFNSF2SF(hi_dci0_req->sfn_sf)); + } + + if (dl_config_req_tx_req != NULL) { + + nfapi_tx_req_pdu_list_t *tx_req_pdu_list = dl_config_req_tx_req->tx_req_pdu_list; + nfapi_dl_config_request_t *dl_config_req = dl_config_req_tx_req->dl_config_req; + + uint16_t dl_num_pdus = dl_config_req->dl_config_request_body.number_pdu; + LOG_I(MAC, "(OAI UE) Received dl_config_req from proxy at Frame: %d, Subframe: %d," + " with number of PDUs: %u\n", + NFAPI_SFNSF2SFN(dl_config_req->sfn_sf), NFAPI_SFNSF2SF(dl_config_req->sfn_sf), + dl_num_pdus); + if (dl_num_pdus > 0) { + char *dl_str = nfapi_dl_config_req_to_string(dl_config_req); + LOG_I(MAC, "dl_config_req: %s\n", dl_str); + free(dl_str); + } + LOG_D(MAC, "tx_req pdus: %d\n", tx_req_pdu_list->num_pdus); + + // Handling dl_config_req and tx_req: + nfapi_dl_config_request_body_t *dl_config_req_body = &dl_config_req->dl_config_request_body; + for (int i = 0; i < dl_config_req_body->number_pdu; ++i) { + nfapi_dl_config_request_pdu_t *pdu = &dl_config_req_body->dl_config_pdu_list[i]; + if (pdu->pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) { + i += 1; + AssertFatal(i < dl_config_req->dl_config_request_body.number_pdu, + "Need PDU following DCI at index %d, but not found\n", + i); + nfapi_dl_config_request_pdu_t *dlsch = &dl_config_req_body->dl_config_pdu_list[i]; + if (dlsch->pdu_type != NFAPI_DL_CONFIG_DLSCH_PDU_TYPE) { + LOG_E(MAC, "expected DLSCH PDU at index %d\n", i); + continue; + } + dl_config_req_UE_MAC_dci(NFAPI_SFNSF2SFN(dl_config_req->sfn_sf), + NFAPI_SFNSF2SF(dl_config_req->sfn_sf), + pdu, + dlsch, + ue_num, + tx_req_pdu_list); + } else if (pdu->pdu_type == NFAPI_DL_CONFIG_BCH_PDU_TYPE) { + dl_config_req_UE_MAC_bch(NFAPI_SFNSF2SFN(dl_config_req->sfn_sf), + NFAPI_SFNSF2SF(dl_config_req->sfn_sf), + pdu, + ue_num); + } else if (pdu->pdu_type == NFAPI_DL_CONFIG_MCH_PDU_TYPE) { + dl_config_req_UE_MAC_mch(NFAPI_SFNSF2SFN(dl_config_req->sfn_sf), + NFAPI_SFNSF2SF(dl_config_req->sfn_sf), + pdu, + ue_num, + tx_req_pdu_list); + } + } + } + if (hi_dci0_req) { + nfapi_hi_dci0_request_body_t *hi_dci0_body = &hi_dci0_req->hi_dci0_request_body; + for (int i = 0; i < hi_dci0_body->number_of_dci + hi_dci0_body->number_of_hi; i++) { + nfapi_hi_dci0_request_pdu_t *pdu = &hi_dci0_body->hi_dci0_pdu_list[i]; + hi_dci0_req_UE_MAC(NFAPI_SFNSF2SFN(hi_dci0_req->sfn_sf), + NFAPI_SFNSF2SF(hi_dci0_req->sfn_sf), + pdu, + ue_num); // This function doesnt do anything? - Andrew + } + } + + for (ue_index = 0; ue_index < ue_num; ue_index++) { + ue_Mod_id = ue_thread_id + NB_THREAD_INST * ue_index; // Always 0 in standalone pnf mode + UE = PHY_vars_UE_g[ue_Mod_id][0]; + +#if UE_TIMING_TRACE + start_meas(&UE->generic_stat); +#endif + int rx_frame = NFAPI_SFNSF2SF(sfn_sf) < 4 ? (NFAPI_SFNSF2SFN(sfn_sf) + 1023) % 1024 : NFAPI_SFNSF2SFN(sfn_sf); // subtracting 4 from subframe_tx + int rx_subframe = NFAPI_SFNSF2SF(sfn_sf) < 4 ? NFAPI_SFNSF2SF(sfn_sf) + 6 : NFAPI_SFNSF2SF(sfn_sf) - 4; + LOG_D(MAC, "rx_frame %d rx_subframe %d\n", rx_frame, rx_subframe); + if (UE->mac_enabled == 1) { + ret = ue_scheduler(ue_Mod_id, + rx_frame, + rx_subframe, + NFAPI_SFNSF2SFN(sfn_sf), + NFAPI_SFNSF2SF(sfn_sf), + subframe_select(&UE->frame_parms, NFAPI_SFNSF2SF(sfn_sf)), + 0, + 0 /*FIXME CC_id*/); + + if (ret != CONNECTION_OK) { + LOG_E(PHY, "[UE %" PRIu8 "] Frame %" PRIu32 ", subframe %u %s\n", + UE->Mod_id, rx_frame, NFAPI_SFNSF2SF(sfn_sf), get_connectionloss_errstr(ret)); + } + } + +#if UE_TIMING_TRACE + stop_meas(&UE->generic_stat); +#endif + + // Prepare the future Tx data + if ((subframe_select(&UE->frame_parms, NFAPI_SFNSF2SF(sfn_sf)) == SF_UL) || + (UE->frame_parms.frame_type == FDD)) + { + if (UE->mode != loop_through_memory) + { + // We make the start of RA between consecutive UEs differ by 20 frames + //if ((UE_mac_inst[Mod_id].UE_mode[0] == PRACH && Mod_id == 0) || (UE_mac_inst[Mod_id].UE_mode[0] == PRACH && Mod_id>0 && rx_frame >= UE_mac_inst[Mod_id-1].ra_frame + 20) ) { + if (UE_mac_inst[ue_Mod_id].UE_mode[0] == RA_RESPONSE && + is_prach_subframe(&UE->frame_parms, NFAPI_SFNSF2SFN(sfn_sf), NFAPI_SFNSF2SF(sfn_sf))) + { + UE_mac_inst[ue_Mod_id].UE_mode[0] = PRACH; + } + LOG_D(MAC, "UE_mode: %d\n", UE_mac_inst[ue_Mod_id].UE_mode[0]); + if (UE_mac_inst[ue_Mod_id].UE_mode[0] == PRACH) + { //&& ue_Mod_id == next_Mod_id) { + next_ra_frame++; + if (next_ra_frame > 500) + { + // check if we have PRACH opportunity + if (is_prach_subframe(&UE->frame_parms, NFAPI_SFNSF2SFN(sfn_sf), NFAPI_SFNSF2SF(sfn_sf)) && UE_mac_inst[ue_Mod_id].SI_Decoded == 1) + { + // The one working strangely... + //if (is_prach_subframe(&UE->frame_parms,NFAPI_SFNSF2SFN(sfn_sf), NFAPI_SFNSF2SF(sfn_sf) && Mod_id == (module_id_t) init_ra_UE) ) { + PRACH_RESOURCES_t *prach_resources = ue_get_rach(ue_Mod_id, 0, NFAPI_SFNSF2SFN(sfn_sf), 0, NFAPI_SFNSF2SF(sfn_sf)); + if (prach_resources != NULL) + { + LOG_I(MAC, "preamble_received_tar_power: %d\n", + prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER); + UE_mac_inst[ue_Mod_id].ra_frame = NFAPI_SFNSF2SFN(sfn_sf); + LOG_D(MAC, "UE_phy_stub_thread_rxn_txnp4 before RACH, Mod_id: %d frame %d subframe %d\n", ue_Mod_id, NFAPI_SFNSF2SFN(sfn_sf), NFAPI_SFNSF2SF(sfn_sf)); + fill_rach_indication_UE_MAC(ue_Mod_id, NFAPI_SFNSF2SFN(sfn_sf), NFAPI_SFNSF2SF(sfn_sf), UL_INFO, prach_resources->ra_PreambleIndex, prach_resources->ra_RNTI); + sent_any = true; + Msg1_transmitted(ue_Mod_id, 0, NFAPI_SFNSF2SFN(sfn_sf), 0); + UE_mac_inst[ue_Mod_id].UE_mode[0] = RA_RESPONSE; + next_Mod_id = ue_Mod_id + 1; + //next_ra_frame = (rx_frame + 20)%1000; + next_ra_frame = 0; + } + //ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode); + } + } + } // mode is PRACH + + // Substitute call to phy_procedures Tx with call to phy_stub functions in order to trigger + // UE Tx procedures directly at the MAC layer, based on the received ul_config requests from the vnf (eNB). + // Generate UL_indications which correspond to UL traffic. + if (ul_config_req != NULL) + { //&& UE_mac_inst[Mod_id].ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL){ + ul_config_req_UE_MAC(ul_config_req, NFAPI_SFNSF2SFN(sfn_sf), NFAPI_SFNSF2SF(sfn_sf), ue_Mod_id); + } + } + + phy_procedures_UE_SL_RX(UE, proc); + } + else + { + LOG_I(MAC, "Skipping subframe select statement proxy SFN.SF: %d.%d\n", + NFAPI_SFNSF2SFN(sfn_sf), NFAPI_SFNSF2SF(sfn_sf)); + if (ul_config_req != NULL) + { + LOG_I(MAC, "Skipping subframe select statement ul_config_req SFN.SF: %d.%d\n", + NFAPI_SFNSF2SFN(ul_config_req->sfn_sf), NFAPI_SFNSF2SF(ul_config_req->sfn_sf)); + } + } + } //for (Mod_id=0; Mod_idcrc_ind.crc_indication_body.number_of_crcs > 0) { + //LOG_D(PHY,"UL_info->crc_ind.crc_indication_body.number_of_crcs:%d CRC_IND:SFN/SF:%d\n", UL_info->crc_ind.crc_indication_body.number_of_crcs, NFAPI_SFNSF2DEC(UL_info->crc_ind.sfn_sf)); + //LOG_I(MAC, "ul_config_req_UE_MAC 2.2, SFN/SF of PNF counter:%d.%d, number_of_crcs: %d \n", timer_frame, timer_subframe, UL_INFO->crc_ind.crc_indication_body.number_of_crcs); + send_standalone_msg(UL_INFO, UL_INFO->crc_ind.header.message_id); + sent_any = true; + //LOG_I(MAC, "ul_config_req_UE_MAC 2.21 \n"); + UL_INFO->crc_ind.crc_indication_body.number_of_crcs = 0; + } + + if (UL_INFO->rx_ind.rx_indication_body.number_of_pdus > 0) { + + //LOG_D(PHY,"UL_info->rx_ind.number_of_pdus:%d RX_IND:SFN/SF:%d\n", UL_info->rx_ind.rx_indication_body.number_of_pdus, NFAPI_SFNSF2DEC(UL_info->rx_ind.sfn_sf)); + //LOG_I(MAC, "ul_config_req_UE_MAC 2.3, SFN/SF of PNF counter:%d.%d, number_of_pdus: %d \n", timer_frame, timer_subframe, UL_INFO->rx_ind.rx_indication_body.number_of_pdus); + send_standalone_msg(UL_INFO, UL_INFO->rx_ind.header.message_id); + sent_any = true; + + //LOG_I(MAC, "ul_config_req_UE_MAC 2.31 \n"); + UL_INFO->rx_ind.rx_indication_body.number_of_pdus = 0; + } + + if (UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis > 0) { + send_standalone_msg(UL_INFO, UL_INFO->cqi_ind.header.message_id); + sent_any = true; + UL_INFO->cqi_ind.cqi_indication_body.number_of_cqis = 0; + } + + if (UL_INFO->harq_ind.harq_indication_body.number_of_harqs > 0) { + //LOG_D(MAC, "ul_config_req_UE_MAC 2.4, SFN/SF of PNF counter:%d.%d, number_of_harqs: %d \n", timer_frame, timer_subframe, UL_INFO->harq_ind.harq_indication_body.number_of_harqs); + send_standalone_msg(UL_INFO, UL_INFO->harq_ind.header.message_id); + sent_any = true; + //LOG_I(MAC, "ul_config_req_UE_MAC 2.41 \n"); + UL_INFO->harq_ind.harq_indication_body.number_of_harqs = 0; + } + + if (UL_INFO->sr_ind.sr_indication_body.number_of_srs > 0) { + //LOG_I(MAC, "ul_config_req_UE_MAC 2.5, SFN/SF of PNF counter:%d.%d, number_of_srs: %d \n", timer_frame, timer_subframe, UL_INFO->sr_ind.sr_indication_body.number_of_srs); + send_standalone_msg(UL_INFO, UL_INFO->sr_ind.header.message_id); + sent_any = true; + //LOG_I(MAC, "ul_config_req_UE_MAC 2.51 \n"); + UL_INFO->sr_ind.sr_indication_body.number_of_srs = 0; + } + + // De-allocate memory of nfapi requests copies before next subframe round + if (dl_config_req_tx_req != NULL) { + if (dl_config_req_tx_req->dl_config_req->vendor_extension != NULL) { + free(dl_config_req_tx_req->dl_config_req->vendor_extension); + dl_config_req_tx_req->dl_config_req->vendor_extension = NULL; + } + + if (dl_config_req_tx_req->dl_config_req->dl_config_request_body.dl_config_pdu_list != NULL) { + free(dl_config_req_tx_req->dl_config_req->dl_config_request_body.dl_config_pdu_list); + dl_config_req_tx_req->dl_config_req->dl_config_request_body.dl_config_pdu_list = NULL; + } + nfapi_free_tx_req_pdu_list(dl_config_req_tx_req->tx_req_pdu_list); + dl_config_req_tx_req->tx_req_pdu_list = NULL; + + free(dl_config_req_tx_req->dl_config_req); + dl_config_req_tx_req->dl_config_req = NULL; + + free(dl_config_req_tx_req); + dl_config_req_tx_req = NULL; + } + + if (ul_config_req != NULL) { + if (ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL) { + free(ul_config_req->ul_config_request_body.ul_config_pdu_list); + ul_config_req->ul_config_request_body.ul_config_pdu_list = NULL; + } + + free(ul_config_req); + ul_config_req = NULL; + } + + if (hi_dci0_req != NULL) { + if (hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list != NULL) { + free(hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list); + hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list = NULL; + } + + free(hi_dci0_req); + hi_dci0_req = NULL; + } + if (!sent_any) + { + send_standalone_dummy(); + } + } + + // Free UL_INFO messages + free(UL_INFO->cqi_ind.cqi_indication_body.cqi_raw_pdu_list); + UL_INFO->cqi_ind.cqi_indication_body.cqi_raw_pdu_list = NULL; + free(UL_INFO->cqi_ind.cqi_indication_body.cqi_pdu_list); + UL_INFO->cqi_ind.cqi_indication_body.cqi_pdu_list = NULL; + free(UL_INFO->sr_ind.sr_indication_body.sr_pdu_list); + UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = NULL; + free(UL_INFO->harq_ind.harq_indication_body.harq_pdu_list); + UL_INFO->harq_ind.harq_indication_body.harq_pdu_list = NULL; + free(UL_INFO->crc_ind.crc_indication_body.crc_pdu_list); + UL_INFO->crc_ind.crc_indication_body.crc_pdu_list = NULL; + free(UL_INFO->rx_ind.rx_indication_body.rx_pdu_list); + UL_INFO->rx_ind.rx_indication_body.rx_pdu_list = NULL; + free(UL_INFO); + UL_INFO = NULL; + + // thread finished + free(arg); + return NULL; +} /*! * \brief This is the UE thread for RX subframe n and TX subframe n+4. @@ -967,6 +1365,7 @@ void ue_stub_rx_handler(unsigned int num_bytes, static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) { +#if 0 // TODO: doesn't currently compile, obviated by multi-ue proxy thread_top_init("UE_phy_stub_thread_rxn_txnp4",1,870000L,1000000L,1000000L); // for multipule UE's L2-emulator //module_id_t Mod_id = 0; @@ -1012,7 +1411,7 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) dl_config_req = NULL; ul_config_req = NULL; hi_dci0_req = NULL; - tx_request_pdu_list = NULL; + tx_req_pdu_list = NULL; // waiting for all UE's threads set phy_stub_ticking->num_single_thread[ue_thread_id] = -1. do { @@ -1108,7 +1507,7 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) } } - if (dl_config_req && tx_request_pdu_list) { + if (dl_config_req && tx_req_pdu_list) { nfapi_dl_config_request_body_t* dl_config_req_body = &dl_config_req->dl_config_request_body; for (int i = 0; i < dl_config_req_body->number_pdu; ++i) { nfapi_dl_config_request_pdu_t* pdu = &dl_config_req_body->dl_config_pdu_list[i]; @@ -1322,16 +1721,16 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) dl_config_req = NULL; } - if(tx_request_pdu_list!=NULL) { + if(tx_req_pdu_list!=NULL) { for (int i = 0; i < tx_req_num_elems; i++) { - for (int j = 0; j < tx_request_pdu_list[i].num_segments; j++) { - free(tx_request_pdu_list[i].segments[j].segment_data); - tx_request_pdu_list[i].segments[j].segment_data = NULL; + for (int j = 0; j < tx_req_pdu_list[i].num_segments; j++) { + free(tx_req_pdu_list[i].segments[j].segment_data); + tx_req_pdu_list[i].segments[j].segment_data = NULL; } } tx_req_num_elems = 0; - free(tx_request_pdu_list); - tx_request_pdu_list = NULL; + free(tx_req_pdu_list); + tx_req_pdu_list = NULL; } if(ul_config_req!=NULL) { @@ -1371,10 +1770,11 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) UL_INFO->rx_ind.rx_indication_body.rx_pdu_list = NULL; free(UL_INFO); UL_INFO = NULL; +#endif // disabled UE_phy_stub_single_thread_rxn_txnp4 // thread finished free(arg); - return &UE_thread_rxtx_retval; + return NULL; } @@ -1388,6 +1788,7 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) static void *UE_phy_stub_thread_rxn_txnp4(void *arg) { + #if 0 thread_top_init("UE_phy_stub_thread_rxn_txnp4",1,870000L,1000000L,1000000L); module_id_t Mod_id = 0; static __thread int UE_thread_rxtx_retval; @@ -1536,10 +1937,10 @@ static void *UE_phy_stub_thread_rxn_txnp4(void *arg) phy_procedures_UE_SL_RX(UE,proc); } - + #endif // disabled // thread finished free(arg); - return &UE_thread_rxtx_retval; + return NULL; //return &UE_thread_rxtx_retval; } @@ -1607,6 +2008,8 @@ void *UE_thread(void *arg) oai_exit=1; } + log_scheduler(__func__); + while (!oai_exit) { if (IS_SOFTMODEM_BASICSIM) while (!(UE->proc.instance_cnt_synch < 0)) { @@ -1973,7 +2376,7 @@ void init_UE_single_thread_stub(int nb_inst) AssertFatal(PHY_vars_UE_g[i]!=NULL,"PHY_vars_UE_g[inst] is NULL\n"); AssertFatal(PHY_vars_UE_g[i][0]!=NULL,"PHY_vars_UE_g[inst][0] is NULL\n"); - if(NFAPI_MODE==NFAPI_UE_STUB_PNF) { + if(NFAPI_MODE==NFAPI_UE_STUB_PNF || NFAPI_MODE==NFAPI_MODE_STANDALONE_PNF) { #ifdef NAS_UE MessageDef *message_p; message_p = itti_alloc_new_message(TASK_NAS_UE, 0, INITIALIZE_MESSAGE); @@ -1993,6 +2396,13 @@ void init_UE_single_thread_stub(int nb_inst) //int nb_threads=RX_NB_TH; int nb_threads=1; + void* (*task_func)(void*); + if (NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF) { + task_func = UE_phy_stub_standalone_pnf_task; + } else { + task_func = UE_phy_stub_single_thread_rxn_txnp4; + } + for(uint16_t ue_thread_id = 0; ue_thread_id < NB_THREAD_INST; ue_thread_id++) { UE = PHY_vars_UE_g[ue_thread_id][0]; @@ -2009,7 +2419,8 @@ void init_UE_single_thread_stub(int nb_inst) UE->proc.proc_rxtx[i].sub_frame_start=i; UE->proc.proc_rxtx[i].sub_frame_step=nb_threads; printf("Init_UE_threads rtd %d proc %d nb_threads %d i %d\n",rtd->proc->sub_frame_start, UE->proc.proc_rxtx[i].sub_frame_start,nb_threads, i); - pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx, NULL, UE_phy_stub_single_thread_rxn_txnp4, rtd); + pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx, NULL, task_func, rtd); + pthread_setname_np(UE->proc.proc_rxtx[i].pthread_rxtx, "oai:ue-phy"); } } @@ -2239,7 +2650,7 @@ static void *timer_thread( void *param ) pdu.header.packet_type = TTI_SYNC; pdu.header.absSF = (timer_frame*10)+timer_subframe; - if (NFAPI_MODE != NFAPI_UE_STUB_PNF) { + if (NFAPI_MODE != NFAPI_UE_STUB_PNF && NFAPI_MODE != NFAPI_MODE_STANDALONE_PNF) { multicast_link_write_sock(0, (char *)&pdu, sizeof(UE_tport_header_t)); diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c index 6d9aa612a2..dcbecc85ac 100644 --- a/targets/RT/USER/lte-uesoftmodem.c +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -66,6 +66,7 @@ #include "LAYER2/MAC/mac_proto.h" #include "RRC/LTE/rrc_vars.h" #include "PHY_INTERFACE/phy_interface_vars.h" +#include "PHY_INTERFACE/phy_stub_UE.h" #include "PHY/TOOLS/phy_scope_interface.h" #include "common/utils/LOG/log.h" #include "nfapi/oai_integration/vendor_ext.h" @@ -78,12 +79,10 @@ #include "create_tasks.h" #include "system.h" - #include "lte-softmodem.h" - +#include "executables/softmodem-common.h" /* temporary compilation wokaround (UE/eNB split */ -uint16_t sf_ahead; pthread_cond_t nfapi_sync_cond; @@ -91,7 +90,7 @@ pthread_mutex_t nfapi_sync_mutex; int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex -uint16_t sf_ahead=2; +uint16_t sf_ahead=4; int tddflag; char *emul_iface; @@ -188,6 +187,7 @@ int oaisim_flag=0; */ uint8_t abstraction_flag=0; +bler_struct bler_data[NUM_MCS]; // needed for pdcp.c RAN_CONTEXT_t RC; instance_t CUuniqInstance=0; @@ -276,7 +276,7 @@ void exit_function(const char *file, const char *function, const int line, const } extern int16_t dlsch_demod_shift; - +uint16_t node_number; static void get_options(void) { int CC_id=0; int tddflag=0; @@ -520,7 +520,7 @@ int restart_L1L2(module_id_t enb_id) { return 0; } -static void init_pdcp(void) { +static void init_pdcp(int ue_id) { uint32_t pdcp_initmask = (!IS_SOFTMODEM_NOS1) ? LINK_ENB_PDCP_TO_GTPV1U_BIT : (LINK_ENB_PDCP_TO_GTPV1U_BIT | PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT); if (IS_SOFTMODEM_BASICSIM || IS_SOFTMODEM_RFSIM || (nfapi_getmode()==NFAPI_UE_STUB_PNF)) { @@ -530,9 +530,9 @@ static void init_pdcp(void) { if (IS_SOFTMODEM_NOKRNMOD) pdcp_initmask = pdcp_initmask | UE_NAS_USE_TUN_BIT; - pdcp_module_init(pdcp_initmask); - pdcp_set_rlc_data_req_func(rlc_data_req); - pdcp_set_pdcp_data_ind_func(pdcp_data_ind); + pdcp_module_init(pdcp_initmask, ue_id); + pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req); + pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind); } // Stupid function addition because UE itti messages queues definition is common with eNB @@ -542,6 +542,13 @@ AssertFatal(false,""); } int main( int argc, char **argv ) { + set_priority(79); + if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) + { + fprintf(stderr, "mlockall: %s\n", strerror(errno)); + return EXIT_FAILURE; + } + int CC_id; uint8_t abstraction_flag=0; // Default value for the number of UEs. It will hold, @@ -566,6 +573,11 @@ int main( int argc, char **argv ) { get_options (); + if (NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF) { + sf_ahead = 1; + } + printf("sf_ahead = %d\n", sf_ahead); + EPC_MODE_ENABLED = !IS_SOFTMODEM_NOS1; printf("Running with %d UE instances\n",NB_UE_INST); @@ -600,7 +612,16 @@ int main( int argc, char **argv ) { MSC_INIT(MSC_E_UTRAN, ADDED_QUEUES_MAX+TASK_MAX); init_opt(); - init_pdcp(); + ue_id_g = (node_number == 0) ? 0 : node_number-2; //ue_id_g = 0, 1, ..., + if(node_number == 0) + { + init_pdcp(0); + } + else + { + init_pdcp(node_number-1); + } + //TTN for D2D printf ("RRC control socket\n"); rrc_control_socket_init(); @@ -623,7 +644,7 @@ int main( int argc, char **argv ) { NB_INST=1; - if(NFAPI_MODE==NFAPI_UE_STUB_PNF) { + if(NFAPI_MODE==NFAPI_UE_STUB_PNF || NFAPI_MODE==NFAPI_MODE_STANDALONE_PNF) { PHY_vars_UE_g = malloc(sizeof(PHY_VARS_UE **)*NB_UE_INST); for (int i=0; i2 */ cpu_set_t cpuset; @@ -656,7 +677,7 @@ int main( int argc, char **argv ) { if (get_nprocs() > 2) { for (j = 2; j < get_nprocs(); j++) CPU_SET(j, &cpuset); - + s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); if (s != 0) { @@ -693,7 +714,7 @@ int main( int argc, char **argv ) { exit(-1); // need a softer mode } - if (NFAPI_MODE==NFAPI_UE_STUB_PNF) { // UE-STUB-PNF + if (NFAPI_MODE==NFAPI_UE_STUB_PNF || NFAPI_MODE==NFAPI_MODE_STANDALONE_PNF) { // UE-STUB-PNF UE_config_stub_pnf(); } @@ -708,6 +729,21 @@ int main( int argc, char **argv ) { //Panos: Temporarily we will be using single set of threads for multiple UEs. //init_UE_stub(1,eMBMS_active,uecap_xer_in,emul_iface); init_UE_stub_single_thread(NB_UE_INST,eMBMS_active,uecap_xer_in,emul_iface); + } else if (NFAPI_MODE==NFAPI_MODE_STANDALONE_PNF) { + init_queue(&dl_config_req_tx_req_queue); + init_queue(&hi_dci0_req_queue); + init_queue(&ul_config_req_queue); + + init_bler_table(); + + config_sync_var=0; + if (sem_init(&sfn_semaphore, 0, 0) != 0) + { + LOG_E(MAC, "sem_init() error\n"); + abort(); + } + init_UE_stub_single_thread(NB_UE_INST,eMBMS_active,uecap_xer_in,emul_iface); + init_UE_standalone_thread(ue_id_g); } else { init_UE(NB_UE_INST,eMBMS_active,uecap_xer_in,0,get_softmodem_params()->phy_test,UE_scan,UE_scan_carrier,mode,(int)rx_gain[0][0],tx_max_power[0], frame_parms[0]); @@ -780,8 +816,73 @@ int main( int argc, char **argv ) { if (PHY_vars_UE_g[0][0]->rfdevice.trx_end_func) PHY_vars_UE_g[0][0]->rfdevice.trx_end_func(&PHY_vars_UE_g[0][0]->rfdevice); + pdcp_module_cleanup(); terminate_opt(); logClean(); printf("Bye.\n"); return 0; } + + +// Read in each MCS file and build BLER-SINR-TB table +void init_bler_table(void) +{ + size_t bufSize = 1024; + char * line = NULL; + char * token; + char * temp = NULL; + const char *openair_dir = getenv("OPENAIR_DIR"); + if (!openair_dir) + { + LOG_E(MAC, "No $OPENAIR_DIR\n"); + abort(); + } + + // Maybe not needed... and may not work. + memset(bler_data, 0, sizeof(bler_data)); + + for (unsigned int i = 0; i < NUM_MCS; i++) + { + char fName[1024]; + snprintf(fName, sizeof(fName), "%s/openair1/SIMULATION/LTE_PHY/BLER_SIMULATIONS/AWGN/AWGN_results/bler_tx1_chan18_nrx1_mcs%d.csv", openair_dir, i); + FILE *pFile = fopen(fName, "r"); + if (!pFile) + { + LOG_E(MAC, "Bler File ERROR! - fopen(), file: %s\n", fName); + abort(); + } + int nlines = 0; + while (getline(&line, &bufSize, pFile) > 0) + { + if (!strncmp(line,"SNR",3)) + { + continue; + } + + if (nlines > NUM_SINR) + { + LOG_E(MAC, "BLER FILE ERROR - num lines greater than expected - file: %s\n", fName); + abort(); + } + + token = strtok_r(line, ";", &temp); + int ncols = 0; + while (token != NULL) + { + if (ncols > NUM_BLER_COL) + { + LOG_E(MAC, "BLER FILE ERROR - num of cols greater than expected\n"); + abort(); + } + + bler_data[i].bler_table[nlines][ncols] = strtof(token, NULL); + ncols++; + + token = strtok_r(NULL, ";", &temp); + } + nlines++; + } + bler_data[i].length = nlines; + fclose(pFile); + } +}