diff --git a/.vscode/launch.json b/.vscode/launch.json
index 6757ed47f6..4b563febde 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -25,4 +25,4 @@
]
}
]
-}
\ No newline at end of file
+}
diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab
index ff661543c0..de49275b7e 100644
--- a/ci-scripts/Jenkinsfile-gitlab
+++ b/ci-scripts/Jenkinsfile-gitlab
@@ -196,16 +196,6 @@ pipeline {
}
}
- stage ("Start VM -- enb-usrp") {
- steps {
- lock (vmResource) {
- timeout (time: 5, unit: 'MINUTES') {
- sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant enb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon"
- }
- }
- }
- }
-
stage ("Start VM -- phy-sim") {
steps {
lock (vmResource) {
@@ -251,7 +241,7 @@ pipeline {
stage ("Analysis with cppcheck") {
steps {
gitlabCommitStatus(name: "Analysis with cppcheck") {
- timeout (time: 20, unit: 'MINUTES') {
+ timeout (time: 30, unit: 'MINUTES') {
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant cppcheck --job-name ${JOB_NAME} --build-id ${BUILD_ID}"
}
}
@@ -260,7 +250,7 @@ pipeline {
stage ("Build basic simulator") {
steps {
gitlabCommitStatus(name: "Build basic-sim") {
- timeout (time: 20, unit: 'MINUTES') {
+ timeout (time: 30, unit: 'MINUTES') {
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
}
}
@@ -269,7 +259,7 @@ pipeline {
stage ("Build 5G gNB-USRP") {
steps {
gitlabCommitStatus(name: "Build gNB-USRP") {
- timeout (time: 20, unit: 'MINUTES') {
+ timeout (time: 30, unit: 'MINUTES') {
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant gnb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
}
}
@@ -278,25 +268,16 @@ pipeline {
stage ("Build 5G NR-UE-USRP") {
steps {
gitlabCommitStatus(name: "Build nr-UE-USRP") {
- timeout (time: 20, unit: 'MINUTES') {
+ timeout (time: 30, unit: 'MINUTES') {
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant nr-ue-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
}
}
}
}
- stage ("Build eNB-USRP") {
- steps {
- gitlabCommitStatus(name: "Build eNB-USRP") {
- timeout (time: 20, unit: 'MINUTES') {
- sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant enb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID}"
- }
- }
- }
- }
stage ("Build physical simulators") {
steps {
gitlabCommitStatus(name: "Build phy-sim") {
- timeout (time: 20, unit: 'MINUTES') {
+ timeout (time: 30, unit: 'MINUTES') {
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
}
}
@@ -305,7 +286,7 @@ pipeline {
stage ("Build eNB-ethernet") {
steps {
gitlabCommitStatus(name: "Build eNB-ethernet") {
- timeout (time: 20, unit: 'MINUTES') {
+ timeout (time: 30, unit: 'MINUTES') {
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
}
}
@@ -316,7 +297,7 @@ pipeline {
// This is typically the last one to finish.
lock (vmResource) {
gitlabCommitStatus(name: "Build UE-ethernet") {
- timeout (time: 20, unit: 'MINUTES') {
+ timeout (time: 30, unit: 'MINUTES') {
sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive"
}
}
diff --git a/ci-scripts/buildOnVM.sh b/ci-scripts/buildOnVM.sh
index 861cab0782..2b1a5e0c71 100755
--- a/ci-scripts/buildOnVM.sh
+++ b/ci-scripts/buildOnVM.sh
@@ -62,6 +62,12 @@ function build_on_vm {
echo "ARCHIVES_LOC = $ARCHIVES_LOC"
echo "BUILD_OPTIONS = $BUILD_OPTIONS"
+ if [[ "$VM_NAME" == *"-enb-usrp"* ]]
+ then
+ echo "This VM type is no longer supported in the pipeline framework"
+ return
+ fi
+
IS_VM_ALIVE=`uvt-kvm list | grep -c $VM_NAME`
if [ $IS_VM_ALIVE -eq 0 ]
@@ -158,6 +164,9 @@ function build_on_vm {
echo "cd tmp" >> $VM_CMDS
echo "echo \"unzip -qq -DD ../localZip.zip\"" >> $VM_CMDS
echo "unzip -qq -DD ../localZip.zip" >> $VM_CMDS
+ # Trying to make some room on filesystem before building
+ echo "rm ../localZip.zip" >> $VM_CMDS
+ echo "export CI_ENV=True" >> $VM_CMDS
if [[ "$VM_NAME" == *"-cppcheck"* ]]
then
echo "mkdir cmake_targets/log" >> $VM_CMDS
@@ -208,7 +217,15 @@ function build_on_vm {
echo "echo \"./build_oai -I $BUILD_OPTIONS \"" >> $VM_CMDS
echo "./build_oai -I $BUILD_OPTIONS > log/install-build.txt 2>&1" >> $VM_CMDS
else
- echo "echo \"./build_oai -I $BUILD_OPTIONS\" > ./my-vm-build.sh" >> $VM_CMDS
+ if [[ "$VM_NAME" == *"-enb-ethernet"* ]]
+ then
+ echo "echo \"sleep 170 && ./build_oai -I $BUILD_OPTIONS\" > ./my-vm-build.sh" >> $VM_CMDS
+ elif [[ "$VM_NAME" == *"-ue-ethernet"* ]]
+ then
+ echo "echo \"sleep 60 && ./build_oai -I $BUILD_OPTIONS\" > ./my-vm-build.sh" >> $VM_CMDS
+ else
+ echo "echo \"./build_oai -I $BUILD_OPTIONS\" > ./my-vm-build.sh" >> $VM_CMDS
+ fi
echo "chmod 775 ./my-vm-build.sh " >> $VM_CMDS
echo "echo \"sudo -E daemon --inherit --unsafe --name=build_daemon --chdir=/home/ubuntu/tmp/cmake_targets -o /home/ubuntu/tmp/cmake_targets/log/install-build.txt ./my-vm-build.sh\"" >> $VM_CMDS
echo "sudo -E daemon --inherit --unsafe --name=build_daemon --chdir=/home/ubuntu/tmp/cmake_targets -o /home/ubuntu/tmp/cmake_targets/log/install-build.txt ./my-vm-build.sh" >> $VM_CMDS
diff --git a/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf
new file mode 100644
index 0000000000..32de0aa4f5
--- /dev/null
+++ b/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf
@@ -0,0 +1,292 @@
+Active_gNBs = ( "gNB-Eurecom-5GNRBox");
+# Asn1_verbosity, choice in: none, info, annoying
+Asn1_verbosity = "none";
+
+gNBs =
+(
+ {
+ ////////// Identification parameters:
+ gNB_ID = 0xe00;
+
+ cell_type = "CELL_MACRO_GNB";
+
+ gNB_name = "gNB-Eurecom-5GNRBox";
+
+ // Tracking area code, 0x0000 and 0xfffe are reserved values
+ tracking_area_code = 1;
+
+ plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;});
+
+ tr_s_preference = "local_mac"
+
+ ////////// Physical parameters:
+
+ ssb_SubcarrierOffset = 0;
+ pdsch_AntennaPorts = 1;
+
+ servingCellConfigCommon = (
+ {
+ #spCellConfigCommon
+
+ physCellId = 0;
+
+# downlinkConfigCommon
+ #frequencyInfoDL
+ # this is 2150 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
+ absoluteFrequencySSB = 433096;
+ dl_frequencyBand = 66;
+ # this is 2150 MHz
+ dl_absoluteFrequencyPointA = 430000;
+ #scs-SpecificCarrierList
+ dl_offstToCarrier = 0;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+ dl_subcarrierSpacing = 1;
+ dl_carrierBandwidth = 106;
+ #initialDownlinkBWP
+ #genericParameters
+ # this is RBstart=0,L=50 (275*(L-1))+RBstart
+ initialDLBWPlocationAndBandwidth = 13475;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+ initialDLBWPsubcarrierSpacing = 1;
+ #pdcch-ConfigCommon
+ initialDLBWPcontrolResourceSetZero = 12;
+ initialDLBWPsearchSpaceZero = 0;
+ #pdsch-ConfigCommon
+ #pdschTimeDomainAllocationList (up to 16 entries)
+ initialDLBWPk0_0 = 0;
+ #initialULBWPmappingType
+ #0=typeA,1=typeB
+ initialDLBWPmappingType_0 = 0;
+ #this is SS=1,L=13
+ initialDLBWPstartSymbolAndLength_0 = 40;
+
+ initialDLBWPk0_1 = 0;
+ initialDLBWPmappingType_1 = 0;
+ #this is SS=2,L=12
+ initialDLBWPstartSymbolAndLength_1 = 53;
+
+ initialDLBWPk0_2 = 0;
+ initialDLBWPmappingType_2 = 0;
+ #this is SS=1,L=12
+ initialDLBWPstartSymbolAndLength_2 = 54;
+
+ initialDLBWPk0_3 = 0;
+ initialDLBWPmappingType_3 = 0;
+ #this is SS=1,L=4
+ initialDLBWPstartSymbolAndLength_3 = 57;
+ #uplinkConfigCommon
+ #frequencyInfoUL
+ ul_frequencyBand = 66;
+ ul_absoluteFrequencyPointA = 350000;
+ #scs-SpecificCarrierList
+ ul_offstToCarrier = 0;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+ ul_subcarrierSpacing = 1;
+ ul_carrierBandwidth = 106;
+ pMax = 20;
+ #initialUplinkBWP
+ #genericParameters
+ initialULBWPlocationAndBandwidth = 13475;
+# subcarrierSpacing
+# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
+ initialULBWPsubcarrierSpacing = 1;
+ #rach-ConfigCommon
+ #rach-ConfigGeneric
+ prach_ConfigurationIndex = 98;
+#prach_msg1_FDM
+#0 = one, 1=two, 2=four, 3=eight
+ prach_msg1_FDM = 0;
+ prach_msg1_FrequencyStart = 0;
+ zeroCorrelationZoneConfig = 13;
+ preambleReceivedTargetPower = -118;
+#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
+ preambleTransMax = 6;
+#powerRampingStep
+# 0=dB0,1=dB2,2=dB4,3=dB6
+ powerRampingStep = 1;
+#ra_ReponseWindow
+#1,2,4,8,10,20,40,80
+ ra_ResponseWindow = 4;
+#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
+#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;
+ }
+
+ );
+
+
+ # ------- 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.12.26";
+ ipv6 = "192:168:30::17";
+ active = "yes";
+ preference = "ipv4";
+ }
+ );
+
+ NETWORK_INTERFACES :
+ {
+
+ GNB_INTERFACE_NAME_FOR_S1_MME = "eth0";
+ GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24";
+ GNB_INTERFACE_NAME_FOR_S1U = "eth0";
+ GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24";
+ GNB_PORT_FOR_S1U = 2152; # Spec 2152
+ };
+ }
+);
+
+MACRLCs = (
+ {
+ num_cc = 1;
+ tr_s_preference = "local_L1";
+ tr_n_preference = "local_RRC";
+ }
+);
+
+L1s = (
+ {
+ num_cc = 1;
+ tr_n_preference = "local_mac";
+ pusch_proc_threads = 8;
+ }
+);
+
+RUs = (
+ {
+ local_rf = "yes"
+ nb_tx = 1;
+ nb_rx = 1;
+ att_tx = 0;
+ att_rx = 0;
+ bands = [7];
+ max_pdschReferenceSignalPower = -27;
+ max_rxgain = 75;
+ eNB_instances = [0];
+ ##beamforming 1x2 matrix: 1 layer x 2 antennas
+ bf_weights = [0x00007fff, 0x0000];
+ ##beamforming 1x4 matrix: 1 layer x 4 antennas
+ #bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
+ ## beamforming 2x2 matrix:
+ # bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
+ ## beamforming 4x4 matrix:
+ #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
+
+ sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2";
+ clock_src = "external";
+ # if_freq = 3700000000L;
+ # if_offset = 1000000;
+ }
+);
+
+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/gnb.band78.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf
index 46da933158..b89aa97976 100644
--- a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf
+++ b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf
@@ -228,19 +228,20 @@ MACRLCs = (
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
- }
+ }
);
L1s = (
- {
+ {
num_cc = 1;
tr_n_preference = "local_mac";
- }
+ pusch_proc_threads = 8;
+ }
);
RUs = (
{
- local_rf = "yes"
+ local_rf = "yes"
nb_tx = 1
nb_rx = 1
att_tx = 0
@@ -249,14 +250,15 @@ RUs = (
max_pdschReferenceSignalPower = -27;
max_rxgain = 75;
eNB_instances = [0];
- ##beamforming 1x2 matrix: 1 layer x 2 antennas
- #bf_weights = [0x00007fff, 0x00007fff];
- ##beamforming 1x4 matrix: 1 layer x 4 antennas
+ ## beamforming 1x2 matrix: 1 layer x 2 antennas
+ bf_weights = [0x00007fff, 0x0000];
+ ## beamforming 1x4 matrix: 1 layer x 4 antennas
#bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
## beamforming 2x2 matrix:
#bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
## beamforming 4x4 matrix:
#bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
+
sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2";
clock_src = "external";
}
diff --git a/ci-scripts/createVM.sh b/ci-scripts/createVM.sh
index 237a1a5d5e..b67668f0bc 100755
--- a/ci-scripts/createVM.sh
+++ b/ci-scripts/createVM.sh
@@ -87,6 +87,12 @@ function create_vm {
echo "VM_CPU = $VM_CPU"
echo "VM_DISK = $VM_DISK GBytes"
+ if [[ "$VM_NAME" == *"-enb-usrp"* ]]
+ then
+ echo "This VM type is no longer supported in the pipeline framework"
+ return
+ fi
+
echo "############################################################"
echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base"
echo "############################################################"
diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool
index 9b9fe462f1..d8f088b707 100755
--- a/ci-scripts/oai-ci-vm-tool
+++ b/ci-scripts/oai-ci-vm-tool
@@ -172,6 +172,7 @@ function setvar_usage {
function variant__v1__enb_usrp {
NB_PATTERN_FILES=9
BUILD_OPTIONS="--eNB -w USRP --mu"
+ VM_MEMORY=3072
}
function variant__v2__basic_sim {
@@ -213,15 +214,15 @@ function variant__v6__nr_ue_usrp {
function variant__v7__enb_ethernet {
VM_MEMORY=4096
ARCHIVES_LOC=enb_eth
- NB_PATTERN_FILES=8
- BUILD_OPTIONS="--eNB"
+ NB_PATTERN_FILES=9
+ BUILD_OPTIONS="--eNB -w USRP"
}
function variant__v8__ue_ethernet {
VM_MEMORY=4096
ARCHIVES_LOC=ue_eth
- NB_PATTERN_FILES=12
- BUILD_OPTIONS="--UE"
+ NB_PATTERN_FILES=13
+ BUILD_OPTIONS="--UE -w USRP"
}
function variant__v10__flexran_rtc {
diff --git a/ci-scripts/reportBuildLocally.sh b/ci-scripts/reportBuildLocally.sh
index 44d200c3b6..19a486303f 100755
--- a/ci-scripts/reportBuildLocally.sh
+++ b/ci-scripts/reportBuildLocally.sh
@@ -580,16 +580,42 @@ function report_build {
sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Expression depends on order of evaluation of side effects" unknownEvaluationOrder
sca_summary_table_footer ./archives/cppcheck/cppcheck.xml
- summary_table_header "OAI Build: 4G LTE eNB -- USRP option" ./archives/enb_usrp
- summary_table_row "LTE SoftModem - Release 15" ./archives/enb_usrp/lte-softmodem.Rel15.txt "Built target lte-softmodem" ./enb_usrp_row1.html
- summary_table_row "Coding - Release 15" ./archives/enb_usrp/coding.Rel15.txt "Built target coding" ./enb_usrp_row2.html
- summary_table_row "OAI USRP device if - Release 15" ./archives/enb_usrp/oai_usrpdevif.Rel15.txt "Built target oai_usrpdevif" ./enb_usrp_row3.html
- summary_table_row "OAI ETHERNET transport - Release 15" ./archives/enb_usrp/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./enb_usrp_row4.html
- summary_table_row "Parameters Lib Config - Release 15" ./archives/enb_usrp/params_libconfig.Rel15.txt "Built target params_libconfig" ./enb_usrp_row5.html
- summary_table_row "NASMESH - Release 15" ./archives/enb_usrp/nasmesh.Rel15.txt "Built target nasmesh" ./enb_usrp_row6.html
- summary_table_row "RB Tool - Release 15" ./archives/enb_usrp/rb_tool.Rel15.txt "Built target rb_tool" ./enb_usrp_row7.html
- summary_table_row "RF Simulator - Release 15" ./archives/enb_usrp/rfsimulator.Rel15.txt "Built target rfsimulator" ./enb_usrp_row8.html
- summary_table_row "TCP Bridge - Release 15" ./archives/enb_usrp/tcp_bridge_oai.Rel15.txt "Built target tcp_bridge_oai" ./enb_usrp_row9.html
+# summary_table_header "OAI Build: 4G LTE eNB -- USRP option" ./archives/enb_usrp
+# summary_table_row "LTE SoftModem - Release 15" ./archives/enb_usrp/lte-softmodem.Rel15.txt "Built target lte-softmodem" ./enb_usrp_row1.html
+# summary_table_row "Coding - Release 15" ./archives/enb_usrp/coding.Rel15.txt "Built target coding" ./enb_usrp_row2.html
+# summary_table_row "OAI USRP device if - Release 15" ./archives/enb_usrp/oai_usrpdevif.Rel15.txt "Built target oai_usrpdevif" ./enb_usrp_row3.html
+# summary_table_row "OAI ETHERNET transport - Release 15" ./archives/enb_usrp/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./enb_usrp_row4.html
+# summary_table_row "Parameters Lib Config - Release 15" ./archives/enb_usrp/params_libconfig.Rel15.txt "Built target params_libconfig" ./enb_usrp_row5.html
+# summary_table_row "NASMESH - Release 15" ./archives/enb_usrp/nasmesh.Rel15.txt "Built target nasmesh" ./enb_usrp_row6.html
+# summary_table_row "RB Tool - Release 15" ./archives/enb_usrp/rb_tool.Rel15.txt "Built target rb_tool" ./enb_usrp_row7.html
+# summary_table_row "RF Simulator - Release 15" ./archives/enb_usrp/rfsimulator.Rel15.txt "Built target rfsimulator" ./enb_usrp_row8.html
+# summary_table_row "TCP Bridge - Release 15" ./archives/enb_usrp/tcp_bridge_oai.Rel15.txt "Built target tcp_bridge_oai" ./enb_usrp_row9.html
+# summary_table_footer
+#
+ summary_table_header "OAI Build: 4G LTE eNB -- USRP option" ./archives/enb_eth
+ summary_table_row "LTE SoftModem - Release 15" ./archives/enb_eth/lte-softmodem.Rel15.txt "Built target lte-softmodem" ./enb_eth_row1.html
+ summary_table_row "Coding - Release 15" ./archives/enb_eth/coding.Rel15.txt "Built target coding" ./enb_eth_row2.html
+ summary_table_row "OAI ETHERNET transport - Release 15" ./archives/enb_eth/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./enb_eth_row3.html
+ summary_table_row "Parameters Lib Config - Release 15" ./archives/enb_eth/params_libconfig.Rel15.txt "Built target params_libconfig" ./enb_eth_row4.html
+ summary_table_row "RF Simulator - Release 15" ./archives/enb_eth/rfsimulator.Rel15.txt "Built target rfsimulator" ./enb_eth_row5.html
+ summary_table_row "TCP OAI Bridge - Release 15" ./archives/enb_eth/tcp_bridge_oai.Rel15.txt "Built target tcp_bridge_oai" ./enb_eth_row6.html
+ summary_table_row "OAI USRP device if - Release 15" ./archives/enb_eth/oai_usrpdevif.Rel15.txt "Built target oai_usrpdevif" ./enb_eth_row7.html
+ summary_table_row "NASMESH - Release 15" ./archives/enb_eth/nasmesh.Rel15.txt "Built target nasmesh" ./enb_eth_row8.html
+ summary_table_row "RB Tool - Release 15" ./archives/enb_eth/rb_tool.Rel15.txt "Built target rb_tool" ./enb_eth_row9.html
+ summary_table_footer
+
+ summary_table_header "OAI Build: 4G LTE UE -- USRP option" ./archives/ue_eth
+ summary_table_row "LTE UE SoftModem - Release 15" ./archives/ue_eth/lte-uesoftmodem.Rel15.txt "Built target lte-uesoftmodem" ./ue_eth_row1.html
+ summary_table_row "Coding - Release 15" ./archives/ue_eth/coding.Rel15.txt "Built target coding" ./ue_eth_row2.html
+ summary_table_row "OAI ETHERNET transport - Release 15" ./archives/ue_eth/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./ue_eth_row3.html
+ summary_table_row "Parameters Lib Config - Release 15" ./archives/ue_eth/params_libconfig.Rel15.txt "Built target params_libconfig" ./ue_eth_row4.html
+ summary_table_row "RF Simulator - Release 15" ./archives/ue_eth/rfsimulator.Rel15.txt "Built target rfsimulator" ./ue_eth_row5.html
+ summary_table_row "TCP OAI Bridge - Release 15" ./archives/ue_eth/tcp_bridge_oai.Rel15.txt "Built target tcp_bridge_oai" ./ue_eth_row6.html
+ summary_table_row "Conf 2 UE Data - Release 15" ./archives/ue_eth/conf2uedata.Rel15.txt "Built target conf2uedata" ./ue_eth_row7.html
+ summary_table_row "NVRAM - Release 15" ./archives/ue_eth/nvram.Rel15.txt "Built target nvram" ./ue_eth_row8.html
+ summary_table_row "UE IP - Release 15" ./archives/ue_eth/ue_ip.Rel15.txt "Built target ue_ip" ./ue_eth_row9.html
+ summary_table_row "USIM - Release 15" ./archives/ue_eth/usim.Rel15.txt "Built target usim" ./ue_eth_row9a.html
+ summary_table_row "OAI USRP device if - Release 15" ./archives/ue_eth/oai_usrpdevif.Rel15.txt "Built target oai_usrpdevif" ./ue_eth_row9b.html
summary_table_footer
summary_table_header "OAI Build: 4G LTE basic simulator option" ./archives/basic_sim
@@ -676,28 +702,6 @@ function report_build {
summary_table_footer
fi
- summary_table_header "OAI Build: 4G LTE eNB -- ETHERNET transport option" ./archives/enb_eth
- summary_table_row "LTE SoftModem - Release 15" ./archives/enb_eth/lte-softmodem.Rel15.txt "Built target lte-softmodem" ./enb_eth_row1.html
- summary_table_row "Coding - Release 15" ./archives/enb_eth/coding.Rel15.txt "Built target coding" ./enb_eth_row2.html
- summary_table_row "OAI ETHERNET transport - Release 15" ./archives/enb_eth/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./enb_eth_row3.html
- summary_table_row "Parameters Lib Config - Release 15" ./archives/enb_eth/params_libconfig.Rel15.txt "Built target params_libconfig" ./enb_eth_row4.html
- summary_table_row "RF Simulator - Release 15" ./archives/enb_eth/rfsimulator.Rel15.txt "Built target rfsimulator" ./enb_eth_row5.html
- summary_table_row "TCP OAI Bridge - Release 15" ./archives/enb_eth/tcp_bridge_oai.Rel15.txt "Built target tcp_bridge_oai" ./enb_eth_row6.html
- summary_table_footer
-
- summary_table_header "OAI Build: 4G LTE UE -- ETHERNET transport option" ./archives/ue_eth
- summary_table_row "LTE UE SoftModem - Release 15" ./archives/ue_eth/lte-uesoftmodem.Rel15.txt "Built target lte-uesoftmodem" ./ue_eth_row1.html
- summary_table_row "Coding - Release 15" ./archives/ue_eth/coding.Rel15.txt "Built target coding" ./ue_eth_row2.html
- summary_table_row "OAI ETHERNET transport - Release 15" ./archives/ue_eth/oai_eth_transpro.Rel15.txt "Built target oai_eth_transpro" ./ue_eth_row3.html
- summary_table_row "Parameters Lib Config - Release 15" ./archives/ue_eth/params_libconfig.Rel15.txt "Built target params_libconfig" ./ue_eth_row4.html
- summary_table_row "RF Simulator - Release 15" ./archives/ue_eth/rfsimulator.Rel15.txt "Built target rfsimulator" ./ue_eth_row5.html
- summary_table_row "TCP OAI Bridge - Release 15" ./archives/ue_eth/tcp_bridge_oai.Rel15.txt "Built target tcp_bridge_oai" ./ue_eth_row6.html
- summary_table_row "Conf 2 UE Data - Release 15" ./archives/ue_eth/conf2uedata.Rel15.txt "Built target conf2uedata" ./ue_eth_row7.html
- summary_table_row "NVRAM - Release 15" ./archives/ue_eth/nvram.Rel15.txt "Built target nvram" ./ue_eth_row8.html
- summary_table_row "UE IP - Release 15" ./archives/ue_eth/ue_ip.Rel15.txt "Built target ue_ip" ./ue_eth_row9.html
- summary_table_row "USIM - Release 15" ./archives/ue_eth/usim.Rel15.txt "Built target usim" ./ue_eth_row9a.html
- summary_table_footer
-
if [ -e ./archives/red_hat ]
then
echo "
Red Hat Enterprise Linux Server release 7.6) -- Summary
" >> ./build_results.html
@@ -714,9 +718,23 @@ function report_build {
echo " " >> ./build_results.html
echo " " >> ./build_results.html
- if [ -f ./enb_usrp_row1.html ] || [ -f ./enb_usrp_row2.html ] || [ -f ./enb_usrp_row3.html ] || [ -f ./enb_usrp_row4.html ]
+# if [ -f ./enb_usrp_row1.html ] || [ -f ./enb_usrp_row2.html ] || [ -f ./enb_usrp_row3.html ] || [ -f ./enb_usrp_row4.html ]
+# then
+# for DETAILS_TABLE in `ls ./enb_usrp_row*.html`
+# do
+# cat $DETAILS_TABLE >> ./build_results.html
+# done
+# fi
+ if [ -f ./enb_eth_row1.html ] || [ -f ./enb_eth_row2.html ] || [ -f ./enb_eth_row3.html ] || [ -f ./enb_eth_row4.html ] || [ -f ./enb_eth_row5.html ] || [ -f ./enb_eth_row6.html ] || [ -f ./enb_eth_row7.html ] || [ -f ./enb_eth_row8.html ] || [ -f ./enb_eth_row9.html ]
then
- for DETAILS_TABLE in `ls ./enb_usrp_row*.html`
+ for DETAILS_TABLE in `ls ./enb_eth_row*.html`
+ do
+ cat $DETAILS_TABLE >> ./build_results.html
+ done
+ fi
+ if [ -f ./ue_eth_row1.html ] || [ -f ./ue_eth_row2.html ] || [ -f ./ue_eth_row3.html ] || [ -f ./ue_eth_row4.html ] || [ -f ./ue_eth_row5.html ] || [ -f ./ue_eth_row6.html ] || [ -f ./ue_eth_row7.html ] || [ -f ./ue_eth_row8.html ] || [ -f ./ue_eth_row9.html ] || [ -f ./ue_eth_row9a.html ] || [ -f ./ue_eth_row9b.html ]
+ then
+ for DETAILS_TABLE in `ls ./ue_eth_row*.html`
do
cat $DETAILS_TABLE >> ./build_results.html
done
@@ -749,20 +767,6 @@ function report_build {
cat $DETAILS_TABLE >> ./build_results.html
done
fi
- if [ -f ./enb_eth_row1.html ] || [ -f ./enb_eth_row2.html ] || [ -f ./enb_eth_row3.html ] || [ -f ./enb_eth_row4.html ] || [ -f ./enb_eth_row5.html ] || [ -f ./enb_eth_row6.html ]
- then
- for DETAILS_TABLE in `ls ./enb_eth_row*.html`
- do
- cat $DETAILS_TABLE >> ./build_results.html
- done
- fi
- if [ -f ./ue_eth_row1.html ] || [ -f ./ue_eth_row2.html ] || [ -f ./ue_eth_row3.html ] || [ -f ./ue_eth_row4.html ] || [ -f ./ue_eth_row5.html ] || [ -f ./ue_eth_row6.html ]
- then
- for DETAILS_TABLE in `ls ./ue_eth_row*.html`
- do
- cat $DETAILS_TABLE >> ./build_results.html
- done
- fi
if [ -f ./enb_usrp_rh_row1.html ] || [ -f ./enb_usrp_rh_row2.html ] || [ -f ./enb_usrp_rh_row3.html ] || [ -f ./enb_usrp_rh_row4.html ]
then
for DETAILS_TABLE in `ls ./enb_usrp_rh_row*.html`
diff --git a/ci-scripts/reportTestLocally.sh b/ci-scripts/reportTestLocally.sh
index 8562f4b2de..415ded57a4 100755
--- a/ci-scripts/reportTestLocally.sh
+++ b/ci-scripts/reportTestLocally.sh
@@ -749,7 +749,7 @@ function report_test {
echo " " >> ./test_simulator_results.html
EPC_CONFIGS=("noS1")
- TRANS_MODES=("tdd")
+ TRANS_MODES=("fdd" "tdd")
BW_CASES=(106)
for CN_CONFIG in ${EPC_CONFIGS[@]}
do
diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh
index 70eabb7b69..f818685049 100755
--- a/ci-scripts/runTestOnVM.sh
+++ b/ci-scripts/runTestOnVM.sh
@@ -379,7 +379,7 @@ function check_iperf {
local LOC_IS_DL=`echo $LOC_BASE_LOG | grep -c _dl`
local LOC_IS_BASIC_SIM=`echo $LOC_BASE_LOG | grep -c basic_sim`
local LOC_IS_RF_SIM=`echo $LOC_BASE_LOG | grep -c rf_sim`
- local LOC_IS_NR=`echo $LOC_BASE_LOG | grep -c tdd_106prb`
+ local LOC_IS_NR=`echo $LOC_BASE_LOG | grep -c _106prb`
if [ -f ${LOC_BASE_LOG}_client.txt ]
then
local FILE_COMPLETE=`egrep -c "Server Report" ${LOC_BASE_LOG}_client.txt`
@@ -2189,39 +2189,50 @@ function run_test_on_vm {
if [[ "$RUN_OPTIONS" == "complex" ]] && [[ $VM_NAME =~ .*-rf-sim.* ]]
then
- CN_CONFIG="noS1"
- CONF_FILE=gnb.band78.tm1.106PRB.usrpn300.conf
- S1_NOS1_CFG=0
- PRB=106
- FREQUENCY=3510
-
if [ ! -d $ARCHIVES_LOC ]
then
mkdir --parents $ARCHIVES_LOC
fi
- local try_cnt=0
- NR_STATUS=0
+ CN_CONFIG="noS1"
+ S1_NOS1_CFG=0
######### start of RA TEST loop
- while [ $try_cnt -lt 5 ] #5 because it hardly succeed within CI
+ # for the moment only TDD
+ TRANS_MODES=("tdd")
+ for TMODE in ${TRANS_MODES[@]}
do
+ if [[ $TMODE =~ .*fdd.* ]]
+ then
+ CONF_FILE=gnb.band66.tm1.106PRB.usrpn300.conf
+ PRB=106
+ FREQUENCY=37000
+ else
+ CONF_FILE=gnb.band78.tm1.106PRB.usrpn300.conf
+ PRB=106
+ FREQUENCY=3510
+ fi
+ local try_cnt=0
+ NR_STATUS=0
+ while [ $try_cnt -lt 5 ] #5 because it hardly succeed within CI
+
+ do
SYNC_STATUS=0
RA_STATUS=0
- rm -f $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}*ra_test.log
+ rm -f $ARCHIVES_LOC/${TMODE}_${PRB}prb_${CN_CONFIG}*ra_test.log
echo "############################################################"
- echo "${CN_CONFIG} : Starting the gNB"
+ echo "${CN_CONFIG} : Starting the gNB in ${TMODE} mode (RA TEST)"
echo "############################################################"
- CURRENT_GNB_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_gnb_ra_test.log
+ CURRENT_GNB_LOG_FILE=${TMODE}_${PRB}prb_${CN_CONFIG}_gnb_ra_test.log
#last argument = 1 is to enable --do-ra for RA test
start_rf_sim_gnb $GNB_VM_CMDS "$GNB_VM_IP_ADDR" $CURRENT_GNB_LOG_FILE $PRB $CONF_FILE $S1_NOS1_CFG 1
echo "############################################################"
- echo "${CN_CONFIG} : Starting the NR-UE"
+ echo "${CN_CONFIG} : Starting the NR-UE in ${TMODE} mode (RA TEST)"
echo "############################################################"
- CURRENT_NR_UE_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_ue_ra_test.log
+ CURRENT_NR_UE_LOG_FILE=${TMODE}_${PRB}prb_${CN_CONFIG}_ue_ra_test.log
#last argument = 1 is to enable --do-ra for RA test
start_rf_sim_nr_ue $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $GNB_VM_IP_ADDR $CURRENT_NR_UE_LOG_FILE $PRB $FREQUENCY $S1_NOS1_CFG 1
if [ $NR_UE_SYNC -eq 0 ]
@@ -2260,35 +2271,47 @@ function run_test_on_vm {
else
try_cnt=$((try_cnt+10))
fi
+ done
done
########### end RA test
sleep 30
-
######### start of PHY TEST loop
- try_cnt=0
- while [ $try_cnt -lt 4 ]
+ SYNC_STATUS=0
+ PING_STATUS=0
+ IPERF_STATUS=0
+ TRANS_MODES=("fdd tdd")
+ for TMODE in ${TRANS_MODES[@]}
do
+ if [[ $TMODE =~ .*fdd.* ]]
+ then
+ CONF_FILE=gnb.band66.tm1.106PRB.usrpn300.conf
+ PRB=106
+ FREQUENCY=37000
+ else
+ CONF_FILE=gnb.band78.tm1.106PRB.usrpn300.conf
+ PRB=106
+ FREQUENCY=3510
+ fi
-
- SYNC_STATUS=0
- PING_STATUS=0
- IPERF_STATUS=0
- rm -f $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}_gnb.log $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}_ue.log
- rm -f $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}_ping_gnb_from_nrue.log $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}_ping_from_gnb_nrue.log
- rm -f $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}_iperf_dl*txt $ARCHIVES_LOC/tdd_${PRB}prb_${CN_CONFIG}_iperf_ul*txt
+ try_cnt=0
+ while [ $try_cnt -lt 4 ]
+ do
+ rm -f $ARCHIVES_LOC/${TMODE}_${PRB}prb_${CN_CONFIG}_gnb.log $ARCHIVES_LOC/${TMODE}_${PRB}prb_${CN_CONFIG}_ue.log
+ rm -f $ARCHIVES_LOC/${TMODE}_${PRB}prb_${CN_CONFIG}_ping_gnb_from_nrue.log $ARCHIVES_LOC/${TMODE}_${PRB}prb_${CN_CONFIG}_ping_from_gnb_nrue.log
+ rm -f $ARCHIVES_LOC/${TMODE}_${PRB}prb_${CN_CONFIG}_iperf_dl*txt $ARCHIVES_LOC/${TMODE}_${PRB}prb_${CN_CONFIG}_iperf_ul*txt
echo "############################################################"
- echo "${CN_CONFIG} : Starting the gNB"
+ echo "${CN_CONFIG} : Starting the gNB in ${TMODE} mode (PHY TEST)"
echo "############################################################"
- CURRENT_GNB_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_gnb.log
+ CURRENT_GNB_LOG_FILE=${TMODE}_${PRB}prb_${CN_CONFIG}_gnb.log
start_rf_sim_gnb $GNB_VM_CMDS "$GNB_VM_IP_ADDR" $CURRENT_GNB_LOG_FILE $PRB $CONF_FILE $S1_NOS1_CFG 0
echo "############################################################"
- echo "${CN_CONFIG} : Starting the NR-UE"
+ echo "${CN_CONFIG} : Starting the NR-UE in ${TMODE} mode (PHY TEST)"
echo "############################################################"
- CURRENT_NR_UE_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_ue.log
+ CURRENT_NR_UE_LOG_FILE=${TMODE}_${PRB}prb_${CN_CONFIG}_ue.log
start_rf_sim_nr_ue $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $GNB_VM_IP_ADDR $CURRENT_NR_UE_LOG_FILE $PRB $FREQUENCY $S1_NOS1_CFG 0
if [ $NR_UE_SYNC -eq 0 ]
then
@@ -2306,7 +2329,7 @@ function run_test_on_vm {
echo "${CN_CONFIG} : Pinging the gNB from NR-UE"
echo "############################################################"
get_enb_noS1_ip_addr $GNB_VM_CMDS $GNB_VM_IP_ADDR
- PING_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_ping_gnb_from_nrue.log
+ PING_LOG_FILE=${TMODE}_${PRB}prb_${CN_CONFIG}_ping_gnb_from_nrue.log
ping_epc_ip_addr $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $ENB_IP_ADDR $PING_LOG_FILE 1 0
scp -o StrictHostKeyChecking=no ubuntu@$NR_UE_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC
check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20
@@ -2315,7 +2338,7 @@ function run_test_on_vm {
echo "${CN_CONFIG} : Pinging the NR-UE from gNB"
echo "############################################################"
get_ue_ip_addr $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 1
- PING_LOG_FILE=tdd_${PRB}prb_${CN_CONFIG}_ping_from_gnb_nrue.log
+ PING_LOG_FILE=${TMODE}_${PRB}prb_${CN_CONFIG}_ping_from_gnb_nrue.log
ping_enb_ip_addr $GNB_VM_CMDS $GNB_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE 0
scp -o StrictHostKeyChecking=no ubuntu@$GNB_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC
check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20
@@ -2324,7 +2347,7 @@ function run_test_on_vm {
echo "${CN_CONFIG} : iperf DL -- NR-UE is server and gNB is client"
echo "############################################################"
THROUGHPUT="30K"
- CURR_IPERF_LOG_BASE=tdd_${PRB}prb_${CN_CONFIG}_iperf_dl
+ CURR_IPERF_LOG_BASE=${TMODE}_${PRB}prb_${CN_CONFIG}_iperf_dl
get_enb_noS1_ip_addr $GNB_VM_CMDS $GNB_VM_IP_ADDR
get_ue_ip_addr $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 1
generic_iperf $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $UE_IP_ADDR $GNB_VM_CMDS $GNB_VM_IP_ADDR $ENB_IP_ADDR $THROUGHPUT $CURR_IPERF_LOG_BASE 1 0
@@ -2346,7 +2369,7 @@ function run_test_on_vm {
echo "${CN_CONFIG} : iperf UL -- gNB is server and NR-UE is client"
echo "############################################################"
THROUGHPUT="30K"
- CURR_IPERF_LOG_BASE=tdd_${PRB}prb_${CN_CONFIG}_iperf_ul
+ CURR_IPERF_LOG_BASE=${TMODE}_${PRB}prb_${CN_CONFIG}_iperf_ul
get_enb_noS1_ip_addr $GNB_VM_CMDS $GNB_VM_IP_ADDR
get_ue_ip_addr $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR 1
generic_iperf $GNB_VM_CMDS $GNB_VM_IP_ADDR $ENB_IP_ADDR $NR_UE_VM_CMDS $NR_UE_VM_IP_ADDR $UE_IP_ADDR $THROUGHPUT $CURR_IPERF_LOG_BASE 1 0
@@ -2368,6 +2391,7 @@ function run_test_on_vm {
else
try_cnt=$((try_cnt+10))
fi
+ done
done
######### end of loop
full_l2_sim_destroy
diff --git a/ci-scripts/waitBuildOnVM.sh b/ci-scripts/waitBuildOnVM.sh
index f066dacd81..ff2129a187 100755
--- a/ci-scripts/waitBuildOnVM.sh
+++ b/ci-scripts/waitBuildOnVM.sh
@@ -47,6 +47,12 @@ function wait_on_vm_build {
echo "ARCHIVES_LOC = $ARCHIVES_LOC"
echo "BUILD_OPTIONS = $BUILD_OPTIONS"
+ if [[ "$VM_NAME" == *"-enb-usrp"* ]]
+ then
+ echo "This VM type is no longer supported in the pipeline framework"
+ return
+ fi
+
IS_VM_ALIVE=`uvt-kvm list | grep -c $VM_NAME`
if [ $IS_VM_ALIVE -eq 0 ]
@@ -84,6 +90,12 @@ function wait_on_vm_build {
}
function check_on_vm_build {
+ if [[ "$VM_NAME" == *"-enb-usrp"* ]]
+ then
+ echo "This VM type is no longer supported in the pipeline framework"
+ return
+ fi
+
echo "############################################################"
echo "Creating a tmp folder to store results and artifacts"
echo "############################################################"
diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index d2297d0af6..6178d3e475 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -1967,7 +1967,9 @@ set(NR_PDCP_SRC
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity.c
- ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c
+ ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_sdu.c
+ ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_timer_thread.c
+ ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c
${OPENAIR2_DIR}/LAYER2/nr_pdcp/asn1_utils.c
)
@@ -2132,7 +2134,23 @@ set (MCE_APP_SRC
${OPENAIR2_DIR}/MCE_APP/mce_app.c
${OPENAIR2_DIR}/MCE_APP/mce_config.c
)
+set (MISC_NFAPI_LTE
+ ${OPENAIR1_DIR}/SCHED/nfapi_lte_dummy.c
+ )
+
+add_library(MISC_NFAPI_LTE_LIB
+ ${MISC_NFAPI_LTE}
+ )
+
+set (MISC_NFAPI_NR
+ ${OPENAIR1_DIR}/SCHED/nfapi_nr_dummy.c
+ )
+
+
+add_library(MISC_NFAPI_NR_LIB
+ ${MISC_NFAPI_NR}
+ )
add_library(L2
${L2_SRC}
${MAC_SRC}
@@ -2885,7 +2903,7 @@ add_dependencies(lte-softmodem rrc_flag s1ap_flag x2_flag oai_iqplayer)
target_link_libraries (lte-softmodem
-Wl,--start-group
RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB
- PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7
+ PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB MISC_NFAPI_LTE_LIB LFDS7
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB}
-Wl,--end-group z dl)
@@ -2926,7 +2944,7 @@ add_dependencies(ocp-enb rrc_flag s1ap_flag x2_flag oai_iqplayer coding params_l
target_link_libraries (ocp-enb
-Wl,--start-group
RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB
- PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7 SIMU_COMMON
+ PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB MISC_NFAPI_LTE_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7 SIMU_COMMON
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB}
-Wl,--end-group z dl)
target_link_libraries (ocp-enb ${LIBXML2_LIBRARIES} pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${LIB_LMS_LIBRARIES} ${T_LIB})
@@ -2996,7 +3014,7 @@ target_link_libraries (lte-uesoftmodem
-Wl,--start-group
RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP F1AP_LIB
GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON
- PHY_UE PHY_RU LFDS L2_UE L2_LTE LFDS7 SIMU_COMMON SIMU NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
+ PHY_UE PHY_RU LFDS L2_UE L2_LTE LFDS7 SIMU_COMMON SIMU NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB MISC_NFAPI_LTE_LIB
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${ATLAS_LIBRARIES}
-Wl,--end-group z dl)
@@ -3123,6 +3141,8 @@ target_link_libraries (nr-uesoftmodem
-Wl,--start-group
RRC_LIB NR_RRC_LIB NGAP_LIB NGAP_GNB SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB
PHY_COMMON PHY_NR_COMMON PHY_UE PHY_NR_UE PHY_RU LFDS NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB
+ NFAPI_USER_LIB MISC_NFAPI_NR_LIB S1AP_LIB S1AP_ENB
+ ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES}
NFAPI_USER_LIB S1AP_LIB S1AP_ENB
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES} LIB_5GNAS_GNB
-Wl,--end-group z dl)
diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml
index 6d3424b420..089d0503fd 100644
--- a/cmake_targets/autotests/test_case_list.xml
+++ b/cmake_targets/autotests/test_case_list.xml
@@ -1292,7 +1292,9 @@
(Test8: DMRS Type B, 3 DMRS, 2 PTRS, 3 Interpolated Symbols),
(Test9: SC-FDMA, 50 PRBs),
(Test10: SC-FDMA, 75 PRBs),
- (Test11: SC-FDMA, 3 DMRS)
+ (Test11: SC-FDMA, 216 PRBs),
+ (Test12: SC-FDMA, 273 PRBs),
+ (Test13: SC-FDMA, 3 DMRS)
$OPENAIR_DIR/cmake_targets/build_oai
--phy_simulators -c
@@ -1307,10 +1309,13 @@
-n100 -s5 -T 2 1 2 -U 2 0 2
-n100 -s5 -T 2 2 2 -U 2 1 2
-n100 -s5 -a4 -b8 -T 2 1 2 -U 2 1 3
- -n100 -s20 -Z
- -n100 -s20 -Z -r75
- -n100 -s20 -Z -U 2 0 2
-
nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 nr_ulsim.test9 nr_ulsim.test10 nr_ulsim.test11
+ -n100 -s2 -Z
+ -n100 -s2 -Z -r75
+ -n100 -s2 -Z -r216 -R217
+ -n100 -s2 -Z -r270 -R273
+ -n100 -s2 -Z -U 2 0 2
+
+
nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 nr_ulsim.test9 nr_ulsim.test10 nr_ulsim.test11 nr_ulsim.test12 nr_ulsim.test13
PUSCH test OK
segmentation fault|assertion|exiting|fatal
3
diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper
index 674d4a0cac..977827b0c9 100755
--- a/cmake_targets/tools/build_helper
+++ b/cmake_targets/tools/build_helper
@@ -273,6 +273,10 @@ install_protobuf_from_source(){
make -j`nproc`
$SUDO make install
$SUDO ldconfig
+ if [[ -v CI_ENV ]]; then
+ cd /tmp
+ $SUDO rm -rf protobuf*
+ fi
) >& $protobuf_install_log
}
@@ -295,6 +299,10 @@ install_protobuf_c_from_source(){
make -j`nproc`
$SUDO make install
$SUDO ldconfig
+ if [[ -v CI_ENV ]]; then
+ cd /tmp
+ $SUDO rm -rf protobuf*
+ fi
) >& $protobuf_c_install_log
}
@@ -831,6 +839,9 @@ install_asn1c_from_source(){
$SUDO make install
cd -
$SUDO ldconfig
+ if [[ -v CI_ENV ]]; then
+ $SUDO rm -rf /tmp/asn1c
+ fi
) > $asn1_install_log 2>&1
}
diff --git a/common/config/config_load_configmodule.c b/common/config/config_load_configmodule.c
index 61a3984347..740c6e240b 100644
--- a/common/config/config_load_configmodule.c
+++ b/common/config/config_load_configmodule.c
@@ -43,7 +43,7 @@
#include "config_userapi.h"
#include "../utils/LOG/log.h"
#define CONFIG_SHAREDLIBFORMAT "libparams_%s.so"
-
+#include "nfapi/oai_integration/vendor_ext.h"
int load_config_sharedlib(configmodule_interface_t *cfgptr) {
void *lib_handle;
@@ -331,9 +331,10 @@ void end_configmodule(void) {
printf ("[CONFIG] free %u config value pointers\n",cfgptr->numptrs);
for(int i=0; i
numptrs ; i++) {
- if (cfgptr->ptrs[i] != NULL) {
+ if (cfgptr->ptrs[i] != NULL && cfgptr->ptrsAllocated[i] == true) {
free(cfgptr->ptrs[i]);
cfgptr->ptrs[i]=NULL;
+ cfgptr->ptrsAllocated[i] = false;
}
}
diff --git a/common/config/config_load_configmodule.h b/common/config/config_load_configmodule.h
index d0309c62c3..8baaa99bb8 100644
--- a/common/config/config_load_configmodule.h
+++ b/common/config/config_load_configmodule.h
@@ -36,6 +36,8 @@
#include
#include
+#include
+#include
#include "common/config/config_paramdesc.h"
#include "common/utils/T/T.h"
#define CONFIG_MAX_OOPT_PARAMS 10 // maximum number of parameters in the -O option (-O :P1:P2...
@@ -74,6 +76,7 @@ typedef struct configmodule_interface {
uint32_t numptrs;
uint32_t rtflags;
char *ptrs[CONFIG_MAX_ALLOCATEDPTRS];
+ bool ptrsAllocated[CONFIG_MAX_ALLOCATEDPTRS];
} configmodule_interface_t;
#ifdef CONFIG_LOADCONFIG_MAIN
diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c
index 33d6408828..af70cae71e 100644
--- a/common/config/config_userapi.c
+++ b/common/config/config_userapi.c
@@ -62,6 +62,7 @@ char *config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) {
if ( (cfgoptions->paramflags & PARAMFLAG_NOFREE) == 0) {
config_get_if()->ptrs[config_get_if()->numptrs] = (char *)ptr;
+ config_get_if()->ptrsAllocated[config_get_if()->numptrs] = true;
config_get_if()->numptrs++;
}
} else {
@@ -82,7 +83,9 @@ char *config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) {
}
if (*ptr == NULL) {
- *ptr = malloc(length>40?length:40); // LTS: dummy fix, waiting Francois full fix in 4G branch
+ *ptr = malloc(length>40?length:40);
+ // LTS: dummy fix, waiting Francois full fix in 4G branch
+ // the issue is we don't know at this point the size we will get
if ( *ptr != NULL) {
memset(*ptr,0,length);
diff --git a/common/config/libconfig/config_libconfig.c b/common/config/libconfig/config_libconfig.c
index 2e9fd614c5..eb08a70183 100644
--- a/common/config/libconfig/config_libconfig.c
+++ b/common/config/libconfig/config_libconfig.c
@@ -346,6 +346,7 @@ int config_libconfig_init(char *cfgP[], int numP) {
libconfig_privdata.configfile = strdup((char *)cfgP[0]);
config_get_if()->numptrs=0;
memset(config_get_if()->ptrs,0,sizeof(void *) * CONFIG_MAX_ALLOCATEDPTRS);
+ memset(config_get_if()->ptrsAllocated, 0, sizeof(config_get_if()->ptrsAllocated));
/* Read the file. If there is an error, report it and exit. */
if(! config_read_file(&(libconfig_privdata.cfg), libconfig_privdata.configfile)) {
diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c
index 2340c78bf1..4e6ec9d3db 100644
--- a/common/utils/LOG/log.c
+++ b/common/utils/LOG/log.c
@@ -88,17 +88,20 @@ int write_file_matlab(const char *fname,
void *data,
int length,
int dec,
- char format)
+ unsigned int format,
+ int multiVec)
{
FILE *fp=NULL;
int i;
+ AssertFatal((format&~MATLAB_RAW) <16,"");
+
if (data == NULL)
return -1;
//printf("Writing %d elements of type %d to %s\n",length,format,fname);
- if (format == 10 || format ==11 || format == 12 || format == 13 || format == 14) {
+ if (format == 10 || format ==11 || format == 12 || format == 13 || format == 14 || multiVec) {
fp = fopen(fname,"a+");
} else if (format != 10 && format !=11 && format != 12 && format != 13 && format != 14) {
fp = fopen(fname,"w+");
@@ -109,7 +112,32 @@ int write_file_matlab(const char *fname,
return(-1);
}
- if (format != 10 && format !=11 && format != 12 && format != 13 && format != 14)
+ if ( (format&MATLAB_RAW) == MATLAB_RAW ) {
+ int sz[16]={sizeof(short), 2*sizeof(short),
+ sizeof(int), 2*sizeof(int),
+ sizeof(char), 2*sizeof(char),
+ sizeof(long long),
+ sizeof(double), 2*sizeof(double),
+ sizeof(unsigned char),
+ sizeof(short),
+ sizeof(short),
+ sizeof(short),
+ sizeof(short),
+ sizeof(short),
+ sizeof(short)
+ };
+ int eltSz= sz[format&~MATLAB_RAW];
+ if (dec==1)
+ fwrite(data, eltSz, length, fp);
+ else
+ for (i=0; idump_mask & D)
-# define LOG_M(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format);} while(0)/* */
+# define LOG_M(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format, 0);} while(0)/* */
/* define variable only used in LOG macro's */
# define LOG_VAR(A,B) A B
# else /* T_TRACER: remove all debugging and tracing messages, except errors */
@@ -413,7 +432,7 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int
# define LOG_DUMPFLAG(D) (g_log->debug_mask & D)
# define LOG_DUMPMSG(c, f, b, s, x...) do { if(g_log->dump_mask & f) log_dump(c, b, s, LOG_DUMP_CHAR, x) ;} while (0) /* */
-# define LOG_M(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format);} while(0)
+# define LOG_M(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format, 0);} while(0)
# define LOG_VAR(A,B) A B
# endif /* T_TRACER */
/* avoid warnings for variables only used in LOG macro's but set outside debug section */
@@ -421,9 +440,10 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int
#define LOG_USEDINLOG_VAR(A,B) GCC_NOTUSED A B
/* unfiltered macros, useful for simulators or messages at init time, before log is configured */
-#define LOG_UM(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format);} while(0)
+#define LOG_UM(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format, 0);} while(0)
#define LOG_UI(c, x...) do {logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_INFO, x) ; } while(0)
#define LOG_UDUMPMSG(c, b, s, f, x...) do { log_dump(c, b, s, f, x) ;} while (0) /* */
+# define LOG_MM(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format, 1);} while(0)
/* @}*/
diff --git a/common/utils/T/.gitignore b/common/utils/T/.gitignore
index d754ff7c38..6a6e5817c5 100644
--- a/common/utils/T/.gitignore
+++ b/common/utils/T/.gitignore
@@ -4,6 +4,7 @@ T_IDs.h
T_messages.txt.h
genids
tracer/enb
+tracer/gnb
tracer/extract_config
tracer/record
tracer/replay
diff --git a/common/utils/T/T_defs.h b/common/utils/T/T_defs.h
index 1236c96a33..8cd86546cb 100644
--- a/common/utils/T/T_defs.h
+++ b/common/utils/T/T_defs.h
@@ -44,7 +44,7 @@
/* let's have 100 RBs functional for the basic simulator */
# define T_BUFFER_MAX (1024*64*2)
#else
-# define T_BUFFER_MAX (1024*64)
+# define T_BUFFER_MAX (1024*64*2)
#endif
/* size of the local cache for messages (must be pow(2,something)) */
@@ -52,7 +52,7 @@
/* we don't need much space for the basic simulator */
# define T_CACHE_SIZE 1024
#else
-# define T_CACHE_SIZE (8192 * 2)
+# define T_CACHE_SIZE (8192)
#endif
/* maximum number of bytes a message can contain */
diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt
index 3336f2165d..91da823c61 100644
--- a/common/utils/T/T_messages.txt
+++ b/common/utils/T/T_messages.txt
@@ -89,6 +89,10 @@ ID = GNB_PHY_MIB
DESC = NR MIB data
GROUP = ALL:PHY:GNB:WIRESHARK
FORMAT = int,gNB_ID : int,frame : int,slot : buffer,data
+ID = GNB_PHY_PUCCH_PUSCH_IQ
+ DESC = gNodeB input data in the frequency domain for a slot where some PUCCH or PUSCH detection was done
+ GROUP = ALL:PHY:GRAPHIC:HEAVY:GNB
+ FORMAT = int,frame : int,slot : buffer,rxdataF
#MAC logs
ID = ENB_MAC_UE_DL_SDU
diff --git a/common/utils/T/tracer/Makefile b/common/utils/T/tracer/Makefile
index 792c2a407c..0713d9a3df 100644
--- a/common/utils/T/tracer/Makefile
+++ b/common/utils/T/tracer/Makefile
@@ -7,7 +7,8 @@ LIBS=-lm
XLIBS=-lX11 -lpng -lXft
all: record replay extract_config textlog enb ue vcd macpdu2wireshark \
- extract_input_subframe extract_output_subframe to_vcd extract multi
+ extract_input_subframe extract_output_subframe to_vcd extract multi \
+ gnb
record: utils.o record.o database.o config.o
$(CC) $(CFLAGS) -o record $^ $(LIBS)
@@ -60,6 +61,11 @@ macpdu2wireshark: macpdu2wireshark.o database.o utils.o handler.o event.o \
multi: multi.o utils.o database.o config.o
$(CC) $(CFLAGS) -o multi $^ $(LIBS)
+gnb: utils.o gnb.o database.o event.o handler.o config.o \
+ view/view.a gui/gui.a logger/logger.a \
+ filter/filter.a
+ $(CC) $(CFLAGS) -o gnb $^ $(LIBS) $(XLIBS)
+
multi.o: ../T_IDs.h
../T_IDs.h:
@@ -85,7 +91,7 @@ filter/filter.a:
clean:
rm -f *.o core tracer_remote textlog enb ue vcd record replay
rm -f extract_config macpdu2wireshark extract_input_subframe
- rm -f extract_output_subframe to_vcd extract multi
+ rm -f extract_output_subframe to_vcd extract multi gnb
cd gui && $(MAKE) clean
cd view && $(MAKE) clean
cd logger && $(MAKE) clean
diff --git a/common/utils/T/tracer/gnb.c b/common/utils/T/tracer/gnb.c
new file mode 100644
index 0000000000..4aaa4898a1
--- /dev/null
+++ b/common/utils/T/tracer/gnb.c
@@ -0,0 +1,172 @@
+#include
+#include
+#include
+#include
+#include
+#include "database.h"
+#include "handler.h"
+#include "config.h"
+#include "logger/logger.h"
+#include "view/view.h"
+#include "gui/gui.h"
+
+typedef struct {
+ widget *pucch_pusch_iq_plot;
+ logger *pucch_pusch_iq_logger;
+} gnb_gui;
+
+typedef struct {
+ int socket;
+ int *is_on;
+ int nevents;
+ pthread_mutex_t lock;
+ gnb_gui *e;
+ void *database;
+} gnb_data;
+
+void is_on_changed(void *_d)
+{
+ gnb_data *d = _d;
+ char t;
+
+ if (pthread_mutex_lock(&d->lock)) abort();
+
+ if (d->socket == -1) goto no_connection;
+
+ t = 1;
+ if (socket_send(d->socket, &t, 1) == -1 ||
+ socket_send(d->socket, &d->nevents, sizeof(int)) == -1 ||
+ socket_send(d->socket, d->is_on, d->nevents * sizeof(int)) == -1)
+ goto connection_dies;
+
+no_connection:
+ if (pthread_mutex_unlock(&d->lock)) abort();
+ return;
+
+connection_dies:
+ close(d->socket);
+ d->socket = -1;
+ if (pthread_mutex_unlock(&d->lock)) abort();
+}
+
+void usage(void)
+{
+ printf(
+"options:\n"
+" -d this option is mandatory\n"
+" -ip connect to given IP address (default %s)\n"
+" -p connect to given port (default %d)\n",
+ DEFAULT_REMOTE_IP,
+ DEFAULT_REMOTE_PORT
+ );
+ exit(1);
+}
+
+static void *gui_thread(void *_g)
+{
+ gui *g = _g;
+ gui_loop(g);
+ return NULL;
+}
+
+static void gnb_main_gui(gnb_gui *e, gui *g, event_handler *h, void *database,
+ gnb_data *ed)
+{
+ widget *main_window;
+ widget *top_container;
+ widget *line;
+ widget *w;
+ logger *l;
+ view *v;
+
+ main_window = new_toplevel_window(g, 500, 300, "gNB tracer");
+
+ top_container = new_container(g, VERTICAL);
+ widget_add_child(g, main_window, top_container, -1);
+
+ line = new_container(g, HORIZONTAL);
+ widget_add_child(g, top_container, line, -1);
+
+ /* PUCCH/PUSCH IQ data */
+ w = new_xy_plot(g, 55, 55, "", 50);
+ e->pucch_pusch_iq_plot = w;
+ widget_add_child(g, line, w, -1);
+ xy_plot_set_range(g, w, -1000, 1000, -1000, 1000);
+ xy_plot_set_title(g, w, "rxdataF");
+ l = new_iqlog_full(h, database, "GNB_PHY_PUCCH_PUSCH_IQ", "rxdataF");
+ v = new_view_xy(300*12*14,10,g,w,new_color(g,"#000"),XY_FORCED_MODE);
+ logger_add_view(l, v);
+ e->pucch_pusch_iq_logger = l;
+}
+
+int main(int n, char **v)
+{
+ char *database_filename = NULL;
+ void *database;
+ char *ip = DEFAULT_REMOTE_IP;
+ int port = DEFAULT_REMOTE_PORT;
+ int *is_on;
+ int number_of_events;
+ int i;
+ event_handler *h;
+ gnb_data gnb_data;
+ gui *g;
+ gnb_gui eg;
+
+ for (i = 1; i < n; i++) {
+ if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage();
+ if (!strcmp(v[i], "-d"))
+ { if (i > n-2) usage(); database_filename = v[++i]; continue; }
+ usage();
+ }
+
+ if (database_filename == NULL) {
+ printf("ERROR: provide a database file (-d)\n");
+ exit(1);
+ }
+
+ database = parse_database(database_filename);
+
+ load_config_file(database_filename);
+
+ number_of_events = number_of_ids(database);
+ is_on = calloc(number_of_events, sizeof(int));
+ if (is_on == NULL) abort();
+
+ h = new_handler(database);
+
+ on_off(database, "GNB_PHY_PUCCH_PUSCH_IQ", is_on, 1);
+
+ gnb_data.database = database;
+ gnb_data.socket = -1;
+ gnb_data.is_on = is_on;
+ gnb_data.nevents = number_of_events;
+ if (pthread_mutex_init(&gnb_data.lock, NULL)) abort();
+
+ g = gui_init();
+ new_thread(gui_thread, g);
+
+ gnb_main_gui(&eg, g, h, database, &gnb_data);
+
+ OBUF ebuf = { osize: 0, omaxsize: 0, obuf: NULL };
+
+restart:
+ clear_remote_config();
+ if (gnb_data.socket != -1) close(gnb_data.socket);
+ gnb_data.socket = connect_to(ip, port);
+
+ /* send the first message - activate selected traces */
+ is_on_changed(&gnb_data);
+
+ /* read messages */
+ while (1) {
+ event e;
+ e = get_event(gnb_data.socket, &ebuf, database);
+ if (e.type == -1) goto restart;
+ if (pthread_mutex_lock(&gnb_data.lock)) abort();
+ handle_event(h, e);
+ if (pthread_mutex_unlock(&gnb_data.lock)) abort();
+ }
+
+ return 0;
+}
diff --git a/common/utils/T/tracer/logger/iqlog.c b/common/utils/T/tracer/logger/iqlog.c
index 168c50e39b..1947de2bca 100644
--- a/common/utils/T/tracer/logger/iqlog.c
+++ b/common/utils/T/tracer/logger/iqlog.c
@@ -74,6 +74,44 @@ static void _event(void *p, event e)
l->common.v[i]->append(l->common.v[i], l->i, l->q, count);
}
+static void _event_full(void *p, event e)
+{
+ struct iqlog *l = p;
+ int i;
+ void *buffer;
+ int bsize;
+ int nsamples;
+ float *idst, *qdst;
+
+ if (l->common.filter != NULL && filter_eval(l->common.filter, e) == 0)
+ return;
+
+ buffer = e.e[l->buffer_arg].b;
+ bsize = e.e[l->buffer_arg].bsize;
+
+ nsamples = bsize / 4;
+
+ if (nsamples > l->max_length) {
+ l->i = realloc(l->i, nsamples * sizeof(float));
+ if (l->i == NULL) abort();
+ l->q = realloc(l->q, nsamples * sizeof(float));
+ if (l->q == NULL) abort();
+ l->max_length = nsamples;
+ }
+
+ idst = l->i;
+ qdst = l->q;
+ for (i = 0; i < nsamples; i++) {
+ *idst = ((int16_t *)buffer)[i * 2];
+ *qdst = ((int16_t *)buffer)[i * 2 + 1];
+ idst++;
+ qdst++;
+ }
+
+ for (i = 0; i < l->common.vsize; i++)
+ l->common.v[i]->append(l->common.v[i], l->i, l->q, nsamples);
+}
+
logger *new_iqlog(event_handler *h, void *database,
char *event_name, char *nb_rb, char *N_RB_UL, char *symbols_per_tti,
char *buffer_varname)
@@ -149,3 +187,43 @@ logger *new_iqlog(event_handler *h, void *database,
return ret;
}
+
+logger *new_iqlog_full(event_handler *h, void *database, char *event_name,
+ char *buffer_varname)
+{
+ struct iqlog *ret;
+ int event_id;
+ database_event_format f;
+ int i;
+
+ ret = calloc(1, sizeof(struct iqlog)); if (ret == NULL) abort();
+
+ ret->common.event_name = strdup(event_name);
+ if (ret->common.event_name == NULL) abort();
+ ret->database = database;
+
+ event_id = event_id_from_name(database, event_name);
+
+ ret->common.handler_id = register_handler_function(h, event_id, _event_full,
+ ret);
+
+ f = get_format(database, event_id);
+
+ /* look for args */
+ ret->buffer_arg = -1;
+ for (i = 0; i < f.count; i++) {
+ if (!strcmp(f.name[i], buffer_varname)) ret->buffer_arg = i;
+ }
+ if (ret->buffer_arg == -1) {
+ printf("%s:%d: buffer argument '%s' not found in event '%s'\n",
+ __FILE__, __LINE__, buffer_varname, event_name);
+ abort();
+ }
+ if (strcmp(f.type[ret->buffer_arg], "buffer") != 0) {
+ printf("%s:%d: argument '%s' has wrong type (should be 'buffer')\n",
+ __FILE__, __LINE__, buffer_varname);
+ abort();
+ }
+
+ return ret;
+}
diff --git a/common/utils/T/tracer/logger/logger.h b/common/utils/T/tracer/logger/logger.h
index 7c019b4797..d746161e70 100644
--- a/common/utils/T/tracer/logger/logger.h
+++ b/common/utils/T/tracer/logger/logger.h
@@ -23,6 +23,8 @@ logger *new_ticklog(void *event_handler, void *database,
logger *new_iqlog(void *event_handler, void *database,
char *event_name, char *nb_rb, char *N_RB_UL, char *symbols_per_tti,
char *buffer_varname);
+logger *new_iqlog_full(void *event_handler, void *database, char *event_name,
+ char *buffer_varname);
logger *new_iqdotlog(void *event_handler, void *database,
char *event_name, char *I, char *Q);
diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c
index 5f07fc00aa..0671aed813 100644
--- a/common/utils/nr/nr_common.c
+++ b/common/utils/nr/nr_common.c
@@ -32,6 +32,81 @@
#include
#include "assertions.h"
+#include "nr_common.h"
+
+// Table 5.2-1 NR operating bands in FR1 & FR2 (3GPP TS 38.101)
+// Table 5.4.2.3-1 Applicable NR-ARFCN per operating band in FR1 & FR2 (3GPP TS 38.101)
+// Notes:
+// - N_OFFs for bands from 80 to 89 and band 95 is referred to UL
+// - Frequencies are expressed in KHz
+// - col: NR_band ul_min ul_max dl_min dl_max step N_OFFs_DL deltaf_raster
+nr_bandentry_t nr_bandtable[] = {
+ {1, 1920000, 1980000, 2110000, 2170000, 20, 422000, 100},
+ {2, 1850000, 1910000, 1930000, 1990000, 20, 386000, 100},
+ {3, 1710000, 1785000, 1805000, 1880000, 20, 361000, 100},
+ {5, 824000, 849000, 869000, 894000, 20, 173800, 100},
+ {7, 2500000, 2570000, 2620000, 2690000, 20, 524000, 100},
+ {8, 880000, 915000, 925000, 960000, 20, 185000, 100},
+ {12, 698000, 716000, 729000, 746000, 20, 145800, 100},
+ {14, 788000, 798000, 758000, 768000, 20, 151600, 100},
+ {18, 815000, 830000, 860000, 875000, 20, 172000, 100},
+ {20, 832000, 862000, 791000, 821000, 20, 158200, 100},
+ {25, 1850000, 1915000, 1930000, 1995000, 20, 386000, 100},
+ {26, 814000, 849000, 859000, 894000, 20, 171800, 100},
+ {28, 703000, 758000, 758000, 813000, 20, 151600, 100},
+ {29, 000, 000, 717000, 728000, 20, 143400, 100},
+ {30, 2305000, 2315000, 2350000, 2360000, 20, 470000, 100},
+ {34, 2010000, 2025000, 2010000, 2025000, 20, 402000, 100},
+ {38, 2570000, 2620000, 2570000, 2630000, 20, 514000, 100},
+ {39, 1880000, 1920000, 1880000, 1920000, 20, 376000, 100},
+ {40, 2300000, 2400000, 2300000, 2400000, 20, 460000, 100},
+ {41, 2496000, 2690000, 2496000, 2690000, 3, 499200, 15},
+ {41, 2496000, 2690000, 2496000, 2690000, 6, 499200, 30},
+ {47, 5855000, 5925000, 5855000, 5925000, 1, 790334, 15},
+ //{48, 3550000, 3700000, 3550000, 3700000, 1, 636667, 15},
+ //{48, 3550000, 3700000, 3550000, 3700000, 2, 636668, 30},
+ {50, 1432000, 1517000, 1432000, 1517000, 20, 286400, 100},
+ {51, 1427000, 1432000, 1427000, 1432000, 20, 285400, 100},
+ {53, 2483500, 2495000, 2483500, 2495000, 20, 496700, 100},
+ {65, 1920000, 2010000, 2110000, 2200000, 20, 422000, 100},
+ {66, 1710000, 1780000, 2110000, 2200000, 20, 422000, 100},
+ {70, 1695000, 1710000, 1995000, 2020000, 20, 399000, 100},
+ {71, 663000, 698000, 617000, 652000, 20, 123400, 100},
+ {74, 1427000, 1470000, 1475000, 1518000, 20, 295000, 100},
+ {75, 000, 000, 1432000, 1517000, 20, 286400, 100},
+ {76, 000, 000, 1427000, 1432000, 20, 285400, 100},
+ {77, 3300000, 4200000, 3300000, 4200000, 1, 620000, 15},
+ {77, 3300000, 4200000, 3300000, 4200000, 2, 620000, 30},
+ {78, 3300000, 3800000, 3300000, 3800000, 1, 620000, 15},
+ {78, 3300000, 3800000, 3300000, 3800000, 2, 620000, 30},
+ {79, 4400010, 5000000, 4400010, 5000000, 1, 693334, 15},
+ {79, 4400010, 5000000, 4400010, 5000000, 2, 693334, 30},
+ {80, 1710000, 1785000, 000, 000, 20, 342000, 100},
+ {81, 880000, 915000, 000, 000, 20, 176000, 100},
+ {82, 832000, 862000, 000, 000, 20, 166400, 100},
+ {83, 703000, 748000, 000, 000, 20, 140600, 100},
+ {84, 1920000, 1980000, 000, 000, 20, 384000, 100},
+ {86, 1710000, 1785000, 000, 000, 20, 342000, 100},
+ {89, 824000, 849000, 000, 000, 20, 342000, 100},
+ {90, 2496000, 2690000, 2496000, 2690000, 3, 499200, 15},
+ {90, 2496000, 2690000, 2496000, 2690000, 6, 499200, 30},
+ {90, 2496000, 2690000, 2496000, 2690000, 20, 499200, 100},
+ {91, 832000, 862000, 1427000, 1432000, 20, 285400, 100},
+ {92, 832000, 862000, 1432000, 1517000, 20, 286400, 100},
+ {93, 880000, 915000, 1427000, 1432000, 20, 285400, 100},
+ {94, 880000, 915000, 1432000, 1517000, 20, 286400, 100},
+ {95, 2010000, 2025000, 000, 000, 20, 402000, 100},
+ {257,26500020,29500000,26500020,29500000, 1,2054166, 60},
+ {257,26500080,29500000,26500080,29500000, 2,2054167, 120},
+ {258,24250080,27500000,24250080,27500000, 1,2016667, 60},
+ {258,24250080,27500000,24250080,27500000, 2,2016667, 120},
+ {260,37000020,40000000,37000020,40000000, 1,2229166, 60},
+ {260,37000080,40000000,37000080,40000000, 2,2229167, 120},
+ {261,27500040,28350000,27500040,28350000, 1,2070833, 60},
+ {261,27500040,28350000,27500040,28350000, 2,2070833, 120}
+};
+
+const size_t nr_bandtable_size = sizeof(nr_bandtable) / sizeof(nr_bandentry_t);
int NRRIV2BW(int locationAndBandwidth,int N_RB) {
int tmp = locationAndBandwidth/N_RB;
diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h
index 5601c0fcbf..6389c2c094 100644
--- a/common/utils/nr/nr_common.h
+++ b/common/utils/nr/nr_common.h
@@ -36,6 +36,20 @@
#include
#include "assertions.h"
+typedef struct nr_bandentry_s {
+ int16_t band;
+ uint64_t ul_min;
+ uint64_t ul_max;
+ uint64_t dl_min;
+ uint64_t dl_max;
+ uint64_t step_size;
+ uint64_t N_OFFs_DL;
+ uint8_t deltaf_raster;
+} nr_bandentry_t;
+
+extern const size_t nr_bandtable_size;
+extern nr_bandentry_t nr_bandtable[];
+
int NRRIV2BW(int locationAndBandwidth,int N_RB);
int NRRIV2PRBOFFSET(int locationAndBandwidth,int N_RB);
int PRBalloc_to_locationandbandwidth0(int NPRB,int RBstart,int BWPsize);
diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md
index d13b193ff9..8d84646e07 100644
--- a/doc/RUNMODEM.md
+++ b/doc/RUNMODEM.md
@@ -132,9 +132,9 @@ With the RF simulator (on the same machine):
`sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem --do-ra --rfsim --parallel-config PARALLEL_SINGLE_THREAD`
-## sa setup with OAI
+## SA setup with OAI
-The sa flag is used to run gNB in standalone mode. Currently OAI in NR standalone mode transmits and receives SIB1.
+The sa flag is used to run gNB in standalone mode. Currently OAI in NR standalone mode transmits and receives SIB1 and triggers the RA procedure for initial access.
In order to run gNB in standalone mode, the following flag is needed at gNB:
@@ -147,8 +147,9 @@ At the gNB the --sa flag does the following
- it encodes the RRCConfiguration and the RBconfig message and stores them in the binary files rbconfig.raw and reconfig.raw
- the RRC encodes SIB1 according the configuration file and transmits it through PDSCH
-At the UE the --sa flag will
-- read the binary files rbconfig.raw and reconfig.raw from the current directory (a different directory can be specified with the flag --rrc_config_path) and process them.
+At the UE the --sa flag will:
+- Read the binary files rbconfig.raw and reconfig.raw from the current directory (a different directory can be specified with the flag --rrc_config_path) and process them
+- After the successful decoding of a SIB1 at RRC, the UE will start the 5G NR Initial Access Procedure by triggering the RA procedure.
From the `cmake_targets/ran_build/build` folder:
@@ -168,7 +169,7 @@ With the RF simulator (on the same machine):
## IF setup with OAI
-The -C and -CO flags can be used together at UE side to set custom downlink and uplink FR1 intermediate frequencies for the IF equipment.
+The -C and --CO flags can be used together at UE side to set custom downlink and uplink FR1 arbitrary frequencies for the IF equipment.
In order to run this setup, the following flags are needed at the UE side:
@@ -182,9 +183,11 @@ and the following parameters must be configured in the RUs section of the gNB co
`if_offset`
-### Run OAI with custom DL/UL intermediate frequencies
+The values must be given in Hz.
-The following example uses DL frequency 2169.080 MHz and UL frequency offset -400 MHz, with a configuration file for band 66 at gNB side.
+### Run OAI with custom DL/UL arbitrary frequencies
+
+The following example uses DL frequency 2169.080 MHz and UL frequency offset -400 MHz, with a configuration file for band 66 (FDD) at gNB side.
From the `cmake_targets/ran_build/build` folder:
diff --git a/doc/TESTING_GNB_W_COTS_UE.md b/doc/TESTING_GNB_W_COTS_UE.md
index 610cc5bdd4..73ae18351f 100644
--- a/doc/TESTING_GNB_W_COTS_UE.md
+++ b/doc/TESTING_GNB_W_COTS_UE.md
@@ -30,8 +30,6 @@ http://www.saelig.com/MFR00066/ste2300.htm
## Configuration Overview
* Non Standalone (NSA) configuration : initial Control Plane established between UE and RAN eNB, then User Plane established between UE and gNB, Core network is 4G based supporting rel 15
-
-* Commercial UE: Oppo Reno 5G
* OAI Software Defined gNB and eNB
* eNB RF front end: USRP (ETTUS) B200 Mini or B210
* gNB RF front end: USRP (ETTUS) B200 Mini or B210 (N310 will be needed for MIMO and wider BW's)
@@ -40,6 +38,17 @@ http://www.saelig.com/MFR00066/ste2300.htm
* BW: 40MHz
* Antenna scheme: SISO
+## COTS UEs
+
+Our code might not work with all 5G phones yet, but we are constantly improving it. Here is a list of COTS UEs that we know that work with OAI.
+
+* Oppo Reno 5G
+* Samsung A90 5G
+* Google Pixel 5G
+* Simcom SIMCOM8200EA
+* Quectel RM500Q-GL
+
+
## Repository
https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop
diff --git a/executables/main-ocp.c b/executables/main-ocp.c
index 39e7b558ac..ae1db7195b 100644
--- a/executables/main-ocp.c
+++ b/executables/main-ocp.c
@@ -74,6 +74,7 @@ int config_sync_var=-1;
volatile int oai_exit = 0;
double cpuf;
uint16_t sf_ahead=4;
+//uint16_t slot_ahead=6;
int otg_enabled;
uint64_t downlink_frequency[MAX_NUM_CCs][4];
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c
index ecf46894f9..f13e00c84b 100644
--- a/executables/nr-gnb.c
+++ b/executables/nr-gnb.c
@@ -81,10 +81,11 @@
#include "s1ap_eNB.h"
#include "SIMULATION/ETH_TRANSPORT/proto.h"
-
+#include
#include "T.h"
-
+#include "nfapi/oai_integration/vendor_ext.h"
+#include
//#define DEBUG_THREADS 1
//#define USRP_DEBUG 1
@@ -92,17 +93,6 @@
// extern openair0_device openair0;
-extern volatile int start_gNB;
-extern volatile int start_UE;
-extern volatile int oai_exit;
-
-extern openair0_config_t openair0_cfg[MAX_CARDS];
-
-extern int transmission_mode;
-
-extern uint16_t sf_ahead;
-extern uint16_t sl_ahead;
-
//pthread_t main_gNB_thread;
time_stats_t softmodem_stats_mt; // main thread
@@ -111,39 +101,43 @@ time_stats_t softmodem_stats_rxtx_sf; // total tx time
time_stats_t nfapi_meas; // total tx time
time_stats_t softmodem_stats_rx_sf; // total rx time
-/* mutex, cond and variable to serialize phy proc TX calls
- * (this mechanism may be relaxed in the future for better
- * performances)
- */
-static struct {
- pthread_mutex_t mutex_phy_proc_tx;
- pthread_cond_t cond_phy_proc_tx;
- volatile uint8_t phy_proc_CC_id;
-} sync_phy_proc;
-extern double cpuf;
-
-void init_gNB(int,int);
-void stop_gNB(int nb_inst);
-
-int wakeup_txfh(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc, int frame_tx, int slot_tx, uint64_t timestamp_tx);
-int wakeup_tx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_tx, int slot_tx, uint64_t timestamp_tx);
#include "executables/thread-common.h"
-//extern PARALLEL_CONF_t get_thread_parallel_conf(void);
-//extern WORKER_CONF_t get_thread_worker_conf(void);
-void wakeup_prach_gNB(PHY_VARS_gNB *gNB, RU_t *ru, int frame, int subframe);
-
-extern uint8_t nfapi_mode;
-extern void oai_subframe_ind(uint16_t sfn, uint16_t sf);
-extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset);
-
//#define TICK_TO_US(ts) (ts.diff)
#define TICK_TO_US(ts) (ts.trials==0?0:ts.diff/ts.trials)
-static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_tx, int slot_tx, char *thread_name) {
+void tx_func(void *param) {
+
+ processingData_L1_t *info = (processingData_L1_t *) param;
+ PHY_VARS_gNB *gNB = info->gNB;
+ int frame_tx = info->frame_tx;
+ int slot_tx = info->slot_tx;
+
+ phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1);
+
+ // start FH TX processing
+ notifiedFIFO_elt_t *res;
+ res = pullTpool(gNB->resp_RU_tx, gNB->threadPool);
+ processingData_RU_t *syncMsg = (processingData_RU_t *)NotifiedFifoData(res);
+ syncMsg->frame_tx = frame_tx;
+ syncMsg->slot_tx = slot_tx;
+ syncMsg->timestamp_tx = info->timestamp_tx;
+ syncMsg->ru = gNB->RU_list[0];
+ res->key = slot_tx;
+ pushTpool(gNB->threadPool, res);
+}
+
+void rx_func(void *param) {
+
+ processingData_L1_t *info = (processingData_L1_t *) param;
+ PHY_VARS_gNB *gNB = info->gNB;
+ int frame_rx = info->frame_rx;
+ int slot_rx = info->slot_rx;
+ int frame_tx = info->frame_tx;
+ int slot_tx = info->slot_tx;
sl_ahead = sf_ahead*gNB->frame_parms.slots_per_subframe;
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
@@ -151,13 +145,14 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t
// *******************************************************************
// NFAPI not yet supported for NR - this code has to be revised
- if (nfapi_mode == 1) {
+ if (NFAPI_MODE == NFAPI_MODE_PNF) {
// I am a PNF and I need to let nFAPI know that we have a (sub)frame tick
//add_subframe(&frame, &subframe, 4);
//oai_subframe_ind(proc->frame_tx, proc->subframe_tx);
//LOG_D(PHY, "oai_subframe_ind(frame:%u, subframe:%d) - NOT CALLED ********\n", frame, subframe);
start_meas(&nfapi_meas);
- oai_subframe_ind(frame_rx, slot_rx);
+ // oai_subframe_ind(frame_rx, slot_rx);
+ oai_slot_ind(frame_rx, slot_rx);
stop_meas(&nfapi_meas);
/*if (gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus||
@@ -233,12 +228,6 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t
rnti_to_remove_count = 0;
if (pthread_mutex_unlock(&rnti_to_remove_mutex)) exit(1);
- /*
- // if this is IF5 or 3GPP_gNB
- if (gNB && gNB->RU_list && gNB->RU_list[0] && gNB->RU_list[0]->function < NGFI_RAU_IF4p5) {
- wakeup_prach_gNB(gNB,NULL,proc->frame_rx,proc->slot_rx);
- }
- */
// Call the scheduler
pthread_mutex_lock(&gNB->UL_INFO_mutex);
@@ -272,23 +261,24 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t
phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx);
}
- if (oai_exit) return(-1);
-
- // *****************************************
- // TX processing for subframe n+sf_ahead
- // run PHY TX procedures the one after the other for all CCs to avoid race conditions
- // (may be relaxed in the future for performance reasons)
- // *****************************************
-
- if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT) {
-
- if(get_thread_parallel_conf() != PARALLEL_RU_L1_TRX_SPLIT) {
- phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1);
- }
- }
-
stop_meas( &softmodem_stats_rxtx_sf );
LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, frame_rx, slot_rx, frame_tx, slot_tx);
+
+ notifiedFIFO_elt_t *res;
+
+ if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT) {
+ res = pullTpool(gNB->resp_L1_tx, gNB->threadPool);
+ processingData_L1_t *syncMsg = (processingData_L1_t *)NotifiedFifoData(res);
+ syncMsg->gNB = gNB;
+ syncMsg->frame_rx = frame_rx;
+ syncMsg->slot_rx = slot_rx;
+ syncMsg->frame_tx = frame_tx;
+ syncMsg->slot_tx = slot_tx;
+ syncMsg->timestamp_tx = info->timestamp_tx;
+ res->key = slot_tx;
+ pushTpool(gNB->threadPool, res);
+ }
+
#if 0
LOG_D(PHY, "rxtx:%lld nfapi:%lld phy:%lld tx:%lld rx:%lld prach:%lld ofdm:%lld ",
softmodem_stats_rxtx_sf.diff_now, nfapi_meas.diff_now,
@@ -328,466 +318,7 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t
TICK_TO_US(gNB->ulsch_tc_intl2_stats)
);
#endif
- return(0);
}
-
-static void *gNB_L1_thread_tx(void *param) {
- PHY_VARS_gNB *gNB = (PHY_VARS_gNB *)param;
- gNB_L1_proc_t *gNB_proc = &gNB->proc;
- gNB_L1_rxtx_proc_t *L1_proc_tx = &gNB_proc->L1_proc_tx;
- //PHY_VARS_gNB *gNB = RC.gNB[0][proc->CC_id];
- char thread_name[100];
-
- sprintf(thread_name,"gNB_L1_thread_tx\n");
-
- while (!oai_exit) {
- if (wait_on_condition(&L1_proc_tx->mutex,&L1_proc_tx->cond,&L1_proc_tx->instance_cnt,thread_name)<0) break;
-
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 1 );
-
- if (oai_exit) break;
-
- // *****************************************
- // TX processing for subframe n+4
- // run PHY TX procedures the one after the other for all CCs to avoid race conditions
- // (may be relaxed in the future for performance reasons)
- // *****************************************
- int frame_tx = L1_proc_tx->frame_tx;
- int slot_tx = L1_proc_tx->slot_tx;
- uint64_t timestamp_tx = L1_proc_tx->timestamp_tx;
- VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX1_GNB,slot_tx);
- VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_GNB,frame_tx);
- phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1);
-
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_WAKEUP_TXFH, 1 );
- pthread_mutex_lock( &L1_proc_tx->mutex );
- L1_proc_tx->instance_cnt = -1;
-
- // the thread can now be woken up
- if (pthread_cond_signal(&L1_proc_tx->cond) != 0) {
- LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB TXnp4 thread\n");
- exit_fun( "ERROR pthread_cond_signal" );
- }
- pthread_mutex_unlock(&L1_proc_tx->mutex);
-
- wakeup_txfh(gNB,L1_proc_tx,frame_tx,slot_tx,timestamp_tx);
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_WAKEUP_TXFH, 0 );
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 0 );
- }
-
- return 0;
-}
-
-/*!
- * \brief The RX UE-specific and TX thread of gNB.
- * \param param is a \ref gNB_L1_proc_t structure which contains the info what to process.
- * \returns a pointer to an int. The storage is not on the heap and must not be freed.
- */
-
-static void *gNB_L1_thread( void *param ) {
- static int gNB_thread_rxtx_status;
- PHY_VARS_gNB *gNB = (PHY_VARS_gNB *)param;
- gNB_L1_proc_t *gNB_proc = &gNB->proc;
- gNB_L1_rxtx_proc_t *L1_proc = &gNB_proc->L1_proc;
- //PHY_VARS_gNB *gNB = RC.gNB[0][proc->CC_id];
- char thread_name[100];
- // set default return value
- // set default return value
- gNB_thread_rxtx_status = 0;
-
- sprintf(thread_name,"gNB_L1_thread");
-
-
- while (!oai_exit) {
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0, 0 );
- if (wait_on_condition(&L1_proc->mutex,&L1_proc->cond,&L1_proc->instance_cnt,thread_name)<0) break;
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0, 1 );
-
- int frame_rx = L1_proc->frame_rx;
- int slot_rx = L1_proc->slot_rx;
- int frame_tx = L1_proc->frame_tx;
- int slot_tx = L1_proc->slot_tx;
- uint64_t timestamp_tx = L1_proc->timestamp_tx;
-
-
- VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX0_GNB,slot_tx);
- VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX0_GNB,slot_rx);
- VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_GNB,frame_tx);
- VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_GNB,frame_rx);
-
- if (oai_exit) break;
-
- if (gNB->CC_id==0) {
- if (rxtx(gNB,frame_rx,slot_rx,frame_tx,slot_tx,thread_name) < 0) break;
- }
-
- if (release_thread(&L1_proc->mutex,&L1_proc->instance_cnt,thread_name)<0) break;
-
- if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) wakeup_tx(gNB,frame_rx,slot_rx,frame_tx,slot_tx,timestamp_tx);
- else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) wakeup_txfh(gNB,L1_proc,frame_tx,slot_tx,timestamp_tx);
- } // while !oai_exit
-
- LOG_D(PHY, " *** Exiting gNB thread RXn_TXnp4\n");
- gNB_thread_rxtx_status = 0;
- return &gNB_thread_rxtx_status;
-}
-
-
-#if 0
-// Wait for gNB application initialization to be complete (gNB registration to MME)
-static void wait_system_ready (char *message, volatile int *start_flag) {
- static char *indicator[] = {". ", ".. ", "... ", ".... ", ".....",
- " ....", " ...", " ..", " .", " "
- };
- int i = 0;
-
- while ((!oai_exit) && (*start_flag == 0)) {
- LOG_N(EMU, message, indicator[i]);
- fflush(stdout);
- i = (i + 1) % (sizeof(indicator) / sizeof(indicator[0]));
- usleep(200000);
- }
-
- LOG_D(EMU,"\n");
-}
-#endif
-
-
-
-
-
-void gNB_top(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, char *string, struct RU_t_s *ru) {
- gNB_L1_proc_t *proc = &gNB->proc;
- gNB_L1_rxtx_proc_t *L1_proc = &proc->L1_proc;
- NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
- RU_proc_t *ru_proc=&ru->proc;
- proc->frame_rx = frame_rx;
- proc->slot_rx = slot_rx;
- sl_ahead = sf_ahead*fp->slots_per_subframe;
-
- if (!oai_exit) {
- T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->slot_rx));
- L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_subframe);
- L1_proc->frame_rx = ru_proc->frame_rx;
- L1_proc->slot_rx = ru_proc->tti_rx;
- L1_proc->frame_tx = (L1_proc->slot_rx > (fp->slots_per_frame-1-(fp->slots_per_subframe*sf_ahead))) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx;
- L1_proc->slot_tx = (L1_proc->slot_rx + (fp->slots_per_subframe*sf_ahead))%fp->slots_per_frame;
-
- if (rxtx(gNB,L1_proc->frame_rx,L1_proc->slot_rx,L1_proc->frame_tx,L1_proc->slot_tx,string) < 0) LOG_E(PHY,"gNB %d CC_id %d failed during execution\n",gNB->Mod_id,gNB->CC_id);
-
- ru_proc->timestamp_tx = L1_proc->timestamp_tx;
- ru_proc->tti_tx = L1_proc->slot_tx;
- ru_proc->frame_tx = L1_proc->frame_tx;
- }
-}
-
-int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot_tx,uint64_t timestamp_tx) {
-
- RU_t *ru;
- RU_proc_t *ru_proc;
-
- int waitret = 0, ret = 0, time_ns = 1000*1000;
- struct timespec now, abstime;
- // note this should depend on the numerology used by the TX L1 thread, set here for 500us slot time
- // note this should depend on the numerology used by the TX L1 thread, set here for 500us slot time
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,1);
- time_ns = time_ns/gNB->frame_parms.slots_per_subframe;
- AssertFatal((ret = pthread_mutex_lock(&proc->mutex_RUs_tx))==0,"mutex_lock returns %d\n",ret);
- while (proc->instance_cnt_RUs < 0) {
- clock_gettime(CLOCK_REALTIME, &now);
- abstime.tv_sec = now.tv_sec;
- abstime.tv_nsec = now.tv_nsec + time_ns;
-
- if (abstime.tv_nsec >= 1000*1000*1000) {
- abstime.tv_nsec -= 1000*1000*1000;
- abstime.tv_sec += 1;
- }
- if((waitret = pthread_cond_timedwait(&proc->cond_RUs,&proc->mutex_RUs_tx,&abstime)) == 0) break; // this unlocks mutex_rxtx while waiting and then locks it again
- }
- proc->instance_cnt_RUs = -1;
- VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs);
- AssertFatal((ret = pthread_mutex_unlock(&proc->mutex_RUs_tx))==0,"mutex_unlock returns %d\n",ret);
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,0);
-
- if (waitret == ETIMEDOUT) {
- LOG_W(PHY,"Dropping TX slot (%d.%d) because FH is blocked more than 1 slot times (500us)\n",frame_tx,slot_tx);
-
- AssertFatal((ret=pthread_mutex_lock(&gNB->proc.mutex_RU_tx))==0,"mutex_lock returns %d\n",ret);
- gNB->proc.RU_mask_tx = 0;
- AssertFatal((ret=pthread_mutex_unlock(&gNB->proc.mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret);
- AssertFatal((ret=pthread_mutex_lock(&proc->mutex_RUs_tx))==0,"mutex_lock returns %d\n",ret);
- proc->instance_cnt_RUs = 0;
- VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs);
- AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_RUs_tx))==0,"mutex_unlock returns %d\n",ret);
-
- VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_UE,1);
- VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_UE,0);
-
- return(-1);
- }
-
- for(int i=0; inum_RU; i++)
- {
- ru = gNB->RU_list[i];
- ru_proc = &ru->proc;
-
-
- if (ru_proc->instance_cnt_gNBs == 0) {
- VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST_UE, 1);
- LOG_E(PHY,"Frame %d, subframe %d: TX FH thread busy, dropping Frame %d, subframe %d\n", ru_proc->frame_tx, ru_proc->tti_tx, proc->frame_rx, proc->slot_rx);
- AssertFatal((ret=pthread_mutex_lock(&gNB->proc.mutex_RU_tx))==0,"mutex_lock returns %d\n",ret);
- gNB->proc.RU_mask_tx = 0;
- AssertFatal((ret=pthread_mutex_unlock(&gNB->proc.mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret);
-
- VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST_UE, 0);
- return(-1);
- }
- AssertFatal((ret = pthread_mutex_lock(&ru_proc->mutex_gNBs))==0,"ERROR pthread_mutex_lock failed on mutex_gNBs L1_thread_tx with ret=%d\n",ret);
-
- ru_proc->instance_cnt_gNBs = 0;
- ru_proc->timestamp_tx = timestamp_tx;
- ru_proc->tti_tx = slot_tx;
- ru_proc->frame_tx = frame_tx;
-
- VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_UE, ru_proc->instance_cnt_gNBs);
-
- LOG_D(PHY,"Signaling tx_thread_fh for %d.%d\n",frame_tx,slot_tx);
- // the thread can now be woken up
- AssertFatal(pthread_cond_signal(&ru_proc->cond_gNBs) == 0,
- "[gNB] ERROR pthread_cond_signal for gNB TXnp4 thread\n");
- AssertFatal((ret=pthread_mutex_unlock(&ru_proc->mutex_gNBs))==0,"mutex_unlock returned %d\n",ret);
-
- }
- return(0);
-}
-
-int wakeup_tx(PHY_VARS_gNB *gNB,int frame_rx,int slot_rx,int frame_tx,int slot_tx,uint64_t timestamp_tx) {
-
-
- gNB_L1_rxtx_proc_t *L1_proc_tx = &gNB->proc.L1_proc_tx;
-
- int ret;
-
-
- AssertFatal((ret = pthread_mutex_lock(&L1_proc_tx->mutex))==0,"mutex_lock returns %d\n",ret);
-
-
- while(L1_proc_tx->instance_cnt == 0) {
- pthread_cond_wait(&L1_proc_tx->cond,&L1_proc_tx->mutex);
- }
-
- L1_proc_tx->instance_cnt = 0;
-
-
- L1_proc_tx->slot_rx = slot_rx;
- L1_proc_tx->frame_rx = frame_rx;
- L1_proc_tx->slot_tx = slot_tx;
- L1_proc_tx->frame_tx = frame_tx;
- L1_proc_tx->timestamp_tx = timestamp_tx;
-
-
- VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_UE,1);
- VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_UE,0);
- // the thread can now be woken up
- // the thread can now be woken up
- AssertFatal(pthread_cond_signal(&L1_proc_tx->cond) == 0, "ERROR pthread_cond_signal for gNB L1 thread\n");
-
- AssertFatal((ret=pthread_mutex_unlock(&L1_proc_tx->mutex))==0,"mutex_unlock returns %d\n",ret);
-
- return(0);
-}
-
-int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) {
- gNB_L1_proc_t *proc=&gNB->proc;
- gNB_L1_rxtx_proc_t *L1_proc=&proc->L1_proc;
- NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
- RU_proc_t *ru_proc=&ru->proc;
- int ret;
- int i;
- struct timespec abstime;
- int time_ns = 50000;
- int wait_timer = 0;
- bool do_last_check = 1;
-
- AssertFatal((ret=pthread_mutex_lock(&proc->mutex_RU))==0,"mutex_lock returns %d\n",ret);
- for (i=0; inum_RU; i++) {
- if (ru == gNB->RU_list[i]) {
- if ((proc->RU_mask&(1< 0)
- LOG_E(PHY,"gNB %d frame %d, subframe %d : previous information from RU %d (num_RU %d,mask %x) has not been served yet!\n",
- gNB->Mod_id,proc->frame_rx,proc->slot_rx,ru->idx,gNB->num_RU,proc->RU_mask);
- proc->RU_mask |= (1<RU_mask != (1<num_RU)-1) { // not all RUs have provided their information so return
- LOG_E(PHY,"Not all RUs have provided their info\n");
- AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_RU))==0,"mutex_unlock returns %d\n",ret);
- return(0);
- }
- else { // all RUs have provided their information so continue on and wakeup gNB processing
- proc->RU_mask = 0;
- AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_RU))==0,"muex_unlock returns %d\n",ret);
- }
-
- // wake up TX for subframe n+sf_ahead
- // lock the TX mutex and make sure the thread is ready
- while (wait_timer < 200) {
- clock_gettime(CLOCK_REALTIME, &abstime);
- abstime.tv_nsec = abstime.tv_nsec + time_ns;
-
- if (abstime.tv_nsec >= 1000*1000*1000) {
- abstime.tv_nsec -= 1000*1000*1000;
- abstime.tv_sec += 1;
- }
-
- AssertFatal((ret=pthread_mutex_timedlock(&L1_proc->mutex, &abstime)) == 0,"mutex_lock returns %d\n", ret);
-
- if (L1_proc->instance_cnt == 0) { // L1_thread is busy so wait for a bit
- AssertFatal((ret=pthread_mutex_unlock( &L1_proc->mutex))==0,"muex_unlock return %d\n",ret);
- wait_timer += 50;
- usleep(50);
- }
- else {
- do_last_check = 0;
- break;
- }
- }
- if (do_last_check) {
- AssertFatal((ret=pthread_mutex_timedlock(&L1_proc->mutex, &abstime)) == 0,"mutex_lock returns %d\n", ret);
- if (L1_proc->instance_cnt == 0) { // L1_thread is busy so abort the subframe
- AssertFatal((ret=pthread_mutex_unlock( &L1_proc->mutex))==0,"muex_unlock return %d\n",ret);
- LOG_W(PHY,"L1_thread isn't ready in %d.%d, aborting RX processing\n",ru_proc->frame_rx,ru_proc->tti_rx);
- return (-1);
- }
- }
-
- ++L1_proc->instance_cnt;
- // We have just received and processed the common part of a subframe, say n.
- // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired
- // transmitted timestamp of the next TX slot (first).
-
- // The last (TS_rx mod samples_per_frame) was n*samples_per_tti,
- // we want to generate subframe (n+sf_ahead), so TS_tx = TX_rx+sf_ahead*samples_per_tti,
- // and proc->slot_tx = proc->slot_rx+sf_ahead
- L1_proc->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_subframe);
- L1_proc->frame_rx = ru_proc->frame_rx;
- L1_proc->slot_rx = ru_proc->tti_rx;
- L1_proc->frame_tx = (L1_proc->slot_rx > (fp->slots_per_frame-1-(fp->slots_per_subframe*sf_ahead))) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx;
- L1_proc->slot_tx = (L1_proc->slot_rx + (fp->slots_per_subframe*sf_ahead))%fp->slots_per_frame;
-
- LOG_D(PHY,"wakeupL1: passing parameter IC = %d, RX: %d.%d, TX: %d.%d to L1 sf_ahead = %d\n", L1_proc->instance_cnt, L1_proc->frame_rx, L1_proc->slot_rx, L1_proc->frame_tx, L1_proc->slot_tx, sf_ahead);
-
- pthread_mutex_unlock( &L1_proc->mutex );
-
- // 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");
- exit_fun( "ERROR pthread_cond_signal" );
- return(-1);
- }
-
- return(0);
-}
-/*
-void wakeup_prach_gNB(PHY_VARS_gNB *gNB,RU_t *ru,int frame,int subframe) {
-
- gNB_L1_proc_t *proc = &gNB->proc;
- LTE_DL_FRAME_PARMS *fp=&gNB->frame_parms;
- int i;
-
- if (ru!=NULL) {
- pthread_mutex_lock(&proc->mutex_RU_PRACH);
- for (i=0;inum_RU;i++) {
- if (ru == gNB->RU_list[i]) {
- LOG_D(PHY,"frame %d, subframe %d: RU %d for gNB %d signals PRACH (mask %x, num_RU %d)\n",frame,subframe,i,gNB->Mod_id,proc->RU_mask_prach,gNB->num_RU);
- if ((proc->RU_mask_prach&(1< 0)
- LOG_E(PHY,"gNB %d frame %d, subframe %d : previous information (PRACH) from RU %d (num_RU %d, mask %x) has not been served yet!\n",
- gNB->Mod_id,frame,subframe,ru->idx,gNB->num_RU,proc->RU_mask_prach);
- proc->RU_mask_prach |= (1<RU_mask_prach != (1<num_RU)-1) { // not all RUs have provided their information so return
- pthread_mutex_unlock(&proc->mutex_RU_PRACH);
- return;
- }
- else { // all RUs have provided their information so continue on and wakeup gNB processing
- proc->RU_mask_prach = 0;
- pthread_mutex_unlock(&proc->mutex_RU_PRACH);
- }
- }
-
- // check if we have to detect PRACH first
- if (is_prach_subframe(fp,frame,subframe)>0) {
- LOG_D(PHY,"Triggering prach processing, frame %d, subframe %d\n",frame,subframe);
- if (proc->instance_cnt_prach == 0) {
- LOG_W(PHY,"[gNB] Frame %d Subframe %d, dropping PRACH\n", frame,subframe);
- return;
- }
-
- // wake up thread for PRACH RX
- if (pthread_mutex_lock(&proc->mutex_prach) != 0) {
- LOG_E( PHY, "[gNB] ERROR pthread_mutex_lock for gNB PRACH thread %d (IC %d)\n", proc->thread_index, proc->instance_cnt_prach);
- exit_fun( "error locking mutex_prach" );
- return;
- }
-
- ++proc->instance_cnt_prach;
- // set timing for prach thread
- proc->frame_prach = frame;
- proc->subframe_prach = subframe;
-
- // the thread can now be woken up
- if (pthread_cond_signal(&proc->cond_prach) != 0) {
- LOG_E( PHY, "[gNB] ERROR pthread_cond_signal for gNB PRACH thread %d\n", proc->thread_index);
- exit_fun( "ERROR pthread_cond_signal" );
- return;
- }
-
- pthread_mutex_unlock( &proc->mutex_prach );
- }
-
-}*/
-
-/*!
- * \brief The prach receive thread of gNB.
- * \param param is a \ref gNB_L1_proc_t structure which contains the info what to process.
- * \returns a pointer to an int. The storage is not on the heap and must not be freed.
- */
-/*
-static void* gNB_thread_prach( void* param ) {
- static int gNB_thread_prach_status;
-
-
- PHY_VARS_gNB *gNB= (PHY_VARS_gNB *)param;
- gNB_L1_proc_t *proc = &gNB->proc;
-
- // set default return value
- gNB_thread_prach_status = 0;
-
-
-
- while (!oai_exit) {
-
- if (oai_exit) break;
-
-
- if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"gNB_prach_thread") < 0) break;
-
- LOG_D(PHY,"Running gNB prach procedures\n");
- prach_procedures(gNB ,0);
-
- if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"gNB_prach_thread") < 0) break;
- }
-
- LOG_I(PHY, "Exiting gNB thread PRACH\n");
-
- gNB_thread_prach_status = 0;
- return &gNB_thread_prach_status;
-}
-*/
-
-extern void init_td_thread(PHY_VARS_gNB *);
-extern void init_te_thread(PHY_VARS_gNB *);
-
static void *process_stats_thread(void *param) {
PHY_VARS_gNB *gNB = (PHY_VARS_gNB *)param;
@@ -808,71 +339,13 @@ static void *process_stats_thread(void *param) {
return(NULL);
}
-
-void init_gNB_proc(int inst) {
- int i=0;
- int CC_id = 0;
+void init_gNB_Tpool(int inst) {
PHY_VARS_gNB *gNB;
- gNB_L1_proc_t *proc;
- gNB_L1_rxtx_proc_t *L1_proc,*L1_proc_tx;
-// LOG_I(PHY,"%s(inst:%d) RC.nb_nr_CC[inst]:%d \n",__FUNCTION__,inst,RC.nb_nr_CC[inst]);
gNB = RC.gNB[inst];
- LOG_I(PHY,"Initializing gNB processes instance:%d CC_id %d \n",inst,CC_id);
-
- proc = &gNB->proc;
- L1_proc = &proc->L1_proc;
- L1_proc_tx = &proc->L1_proc_tx;
- L1_proc->instance_cnt = -1;
- L1_proc_tx->instance_cnt = -1;
- L1_proc->instance_cnt_RUs = 0;
- L1_proc_tx->instance_cnt_RUs = 0;
- proc->instance_cnt_prach = -1;
- proc->instance_cnt_asynch_rxtx = -1;
- proc->CC_id = CC_id;
- proc->first_rx =1;
- proc->first_tx =1;
- proc->RU_mask =0;
- proc->RU_mask_tx = (1<num_RU)-1;
- proc->RU_mask_prach =0;
- pthread_mutex_init( &gNB->UL_INFO_mutex, NULL);
- pthread_mutex_init( &L1_proc->mutex, NULL);
- pthread_mutex_init( &L1_proc_tx->mutex, NULL);
- pthread_cond_init( &L1_proc->cond, NULL);
- pthread_cond_init( &L1_proc_tx->cond, NULL);
- pthread_mutex_init( &proc->mutex_prach, NULL);
- pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL);
- pthread_mutex_init( &proc->mutex_RU,NULL);
- pthread_mutex_init( &proc->mutex_RU_tx,NULL);
- pthread_mutex_init( &proc->mutex_RU_PRACH,NULL);
- pthread_cond_init( &proc->cond_prach, NULL);
- pthread_cond_init( &proc->cond_asynch_rxtx, NULL);
- LOG_I(PHY,"gNB->single_thread_flag:%d\n", gNB->single_thread_flag);
-
- if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) {
- threadCreate( &L1_proc->pthread, gNB_L1_thread, gNB, "L1_proc", -1, OAI_PRIORITY_RT );
- threadCreate( &L1_proc_tx->pthread, gNB_L1_thread_tx, gNB,"L1_proc_tx", -1, OAI_PRIORITY_RT);
- }
-
- if(opp_enabled == 1) threadCreate(&proc->L1_stats_thread, process_stats_thread,(void *)gNB, "time_meas", -1, OAI_PRIORITY_RT_LOW);
- //pthread_create( &proc->pthread_prach, attr_prach, gNB_thread_prach, gNB );
- char name[16];
-
- if (gNB->single_thread_flag==0) {
- snprintf( name, sizeof(name), "L1 %d", i );
- pthread_setname_np( L1_proc->pthread, name );
- snprintf( name, sizeof(name), "L1TX %d", i );
- pthread_setname_np( L1_proc_tx->pthread, name );
- }
-
- AssertFatal(proc->instance_cnt_prach == -1,"instance_cnt_prach = %d\n",proc->instance_cnt_prach);
-
- /* setup PHY proc TX sync mechanism */
- pthread_mutex_init(&sync_phy_proc.mutex_phy_proc_tx, NULL);
- pthread_cond_init(&sync_phy_proc.cond_phy_proc_tx, NULL);
- sync_phy_proc.phy_proc_CC_id = 0;
+ gNB_L1_proc_t *proc = &gNB->proc;
+ // ULSCH decoding threadpool
gNB->threadPool = (tpool_t*)malloc(sizeof(tpool_t));
- gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
int numCPU = sysconf(_SC_NPROCESSORS_ONLN);
int threadCnt = min(numCPU, gNB->pusch_proc_threads);
char ul_pool[80];
@@ -883,70 +356,40 @@ void init_gNB_proc(int inst) {
s_offset += 3;
}
initTpool(ul_pool, gNB->threadPool, false);
+ // ULSCH decoder result FIFO
+ gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
initNotifiedFIFO(gNB->respDecode);
-}
+ // L1 RX result FIFO
+ gNB->resp_L1 = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
+ initNotifiedFIFO(gNB->resp_L1);
+
+ // L1 TX result FIFO
+ gNB->resp_L1_tx = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
+ initNotifiedFIFO(gNB->resp_L1_tx);
+
+ // RU TX result FIFO
+ gNB->resp_RU_tx = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
+ initNotifiedFIFO(gNB->resp_RU_tx);
+
+ // Stats measurement thread
+ if(opp_enabled == 1) threadCreate(&proc->L1_stats_thread, process_stats_thread,(void *)gNB, "time_meas", -1, OAI_PRIORITY_RT_LOW);
+}
/*!
* \brief Terminate gNB TX and RX threads.
*/
void kill_gNB_proc(int inst) {
- int *status;
PHY_VARS_gNB *gNB;
- gNB_L1_proc_t *proc;
- gNB_L1_rxtx_proc_t *L1_proc, *L1_proc_tx;
gNB=RC.gNB[inst];
- proc = &gNB->proc;
- L1_proc = &proc->L1_proc;
- L1_proc_tx = &proc->L1_proc_tx;
- LOG_I(PHY, "Killing TX inst %d\n",inst );
- if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) {
- pthread_mutex_lock(&L1_proc->mutex);
- L1_proc->instance_cnt = 0;
- pthread_cond_signal(&L1_proc->cond);
- pthread_mutex_unlock(&L1_proc->mutex);
- pthread_mutex_lock(&L1_proc_tx->mutex);
- L1_proc_tx->instance_cnt = 0;
- pthread_cond_signal(&L1_proc_tx->cond);
- pthread_mutex_unlock(&L1_proc_tx->mutex);
- }
-
- proc->instance_cnt_prach = 0;
- pthread_cond_signal( &proc->cond_prach );
- pthread_cond_signal( &proc->cond_asynch_rxtx );
- pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx);
- // LOG_D(PHY, "joining pthread_prach\n");
- // pthread_join( proc->pthread_prach, (void**)&status );
- LOG_I(PHY, "Destroying prach mutex/cond\n");
- pthread_mutex_destroy( &proc->mutex_prach );
- pthread_cond_destroy( &proc->cond_prach );
LOG_I(PHY, "Destroying UL_INFO mutex\n");
pthread_mutex_destroy(&gNB->UL_INFO_mutex);
- if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) {
- LOG_I(PHY, "Joining L1_proc mutex/cond\n");
- pthread_join( L1_proc->pthread, (void **)&status );
- LOG_I(PHY, "Joining L1_proc_tx mutex/cond\n");
- pthread_join( L1_proc_tx->pthread, (void **)&status );
- }
-
- LOG_I(PHY, "Destroying L1_proc mutex/cond\n");
- pthread_mutex_destroy( &L1_proc->mutex );
- pthread_cond_destroy( &L1_proc->cond );
- LOG_I(PHY, "Destroying L1_proc_tx mutex/cond\n");
- pthread_mutex_destroy( &L1_proc_tx->mutex );
- pthread_cond_destroy( &L1_proc_tx->cond );
- pthread_mutex_destroy( &proc->mutex_RU );
- pthread_mutex_destroy( &proc->mutex_RU_tx );
-
}
-
-
-
void reset_opp_meas(void) {
int sfn;
reset_meas(&softmodem_stats_mt);
@@ -999,7 +442,13 @@ void init_eNB_afterRU(void) {
for (i=0; iRU_list[ru_id]->nb_rx; aa++,i++) {
LOG_I(PHY,"Attaching RU %d antenna %d to gNB antenna %d\n",gNB->RU_list[ru_id]->idx,i,aa);
gNB->prach_vars.rxsigF[aa] = gNB->RU_list[ru_id]->prach_rxsigF[0][i];
+#if 0
+printf("before %p\n", gNB->common_vars.rxdataF[aa]);
+#endif
gNB->common_vars.rxdataF[aa] = gNB->RU_list[ru_id]->common.rxdataF[i];
+#if 0
+printf("after %p\n", gNB->common_vars.rxdataF[aa]);
+#endif
}
}
@@ -1008,15 +457,9 @@ void init_eNB_afterRU(void) {
* (not tested in other modes).
*/
//init_precoding_weights(RC.gNB[inst]);
- init_gNB_proc(inst);
+ init_gNB_Tpool(inst);
}
- for (ru_id=0; ru_idnr_wakeup_rxtx = wakeup_rxtx;
- // RC.ru[ru_id]->wakeup_prach_eNB = wakeup_prach_gNB;
- RC.ru[ru_id]->gNB_top = gNB_top;
- }
}
void init_gNB(int single_thread_flag,int wait_for_sync) {
diff --git a/executables/nr-ru.c b/executables/nr-ru.c
index feff0c29c2..9dbd025680 100644
--- a/executables/nr-ru.c
+++ b/executables/nr-ru.c
@@ -114,6 +114,7 @@ int attach_rru(RU_t *ru);
int connect_rau(RU_t *ru);
uint16_t sf_ahead;
+uint16_t slot_ahead;
uint16_t sl_ahead;
extern int emulate_rf;
@@ -787,259 +788,6 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
}
}
-
-
-/*!
- * \brief The Asynchronous RX/TX FH thread of RAU/RCC/gNB/RRU.
- * This handles the RX FH for an asynchronous RRU/UE
- * \param param is a \ref gNB_L1_proc_t structure which contains the info what to process.
- * \returns a pointer to an int. The storage is not on the heap and must not be freed.
- */
-void *ru_thread_asynch_rxtx( void *param ) {
- static int ru_thread_asynch_rxtx_status;
- RU_t *ru = (RU_t *)param;
- RU_proc_t *proc = &ru->proc;
- nfapi_nr_config_request_scf_t *cfg = &ru->config;
- int slot=0, frame=0;
- // wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe
- wait_sync("ru_thread_asynch_rxtx");
- // wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe
- printf( "waiting for devices (ru_thread_asynch_rx)\n");
- wait_on_condition(&proc->mutex_asynch_rxtx,&proc->cond_asynch_rxtx,&proc->instance_cnt_asynch_rxtx,"thread_asynch");
- printf( "devices ok (ru_thread_asynch_rx)\n");
-
- while (!oai_exit) {
-
- if (slot==ru->nr_frame_parms->slots_per_frame) {
- slot=0;
- frame++;
- frame&=1023;
- } else {
- slot++;
- }
-
- LOG_D(PHY,"ru_thread_asynch_rxtx: Waiting on incoming fronthaul\n");
-
- // asynchronous receive from north (RRU IF4/IF5)
- if (ru->fh_north_asynch_in) {
- if ((nr_slot_select(cfg,frame,slot) & NR_DOWNLINK_SLOT)>0)
- ru->fh_north_asynch_in(ru,&frame,&slot);
- } else AssertFatal(1==0,"Unknown function in ru_thread_asynch_rxtx\n");
- }
-
- ru_thread_asynch_rxtx_status=0;
- return(&ru_thread_asynch_rxtx_status);
-}
-
-
-
-
-/*!
- * \brief The prach receive thread of RU.
- * \param param is a \ref RU_proc_t structure which contains the info what to process.
- * \returns a pointer to an int. The storage is not on the heap and must not be freed.
- */
-void *ru_thread_prach( void *param ) {
- static int ru_thread_prach_status;
- RU_t *ru = (RU_t *)param;
- RU_proc_t *proc = (RU_proc_t *)&ru->proc;
- // set default return value
- ru_thread_prach_status = 0;
-
- while (RC.ru_mask>0) {
- usleep(1e6);
- LOG_I(PHY,"%s() RACH waiting for RU to be configured\n", __FUNCTION__);
- }
-
- LOG_I(PHY,"%s() RU configured - RACH processing thread running\n", __FUNCTION__);
-
- while (!oai_exit) {
-
-
- if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"ru_prach_thread") < 0) break;
-
- /*VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 1 );
-
- if (ru->gNB_list[0]){
- prach_procedures(
- ru->gNB_list[0],0
- );
- }
- else {
- rx_prach(NULL,
- ru,
- NULL,
- NULL,
- NULL,
- proc->frame_prach,
- 0,0
- );
- }
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 0 );*/
- if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"ru_prach_thread") < 0) break;
- }
-
- LOG_I(PHY, "Exiting RU thread PRACH\n");
- ru_thread_prach_status = 0;
- return &ru_thread_prach_status;
-}
-
-
-int wakeup_synch(RU_t *ru) {
- struct timespec wait;
- wait.tv_sec=0;
- wait.tv_nsec=5000000L;
-
- // wake up synch thread
- // lock the synch mutex and make sure the thread is ready
- if (pthread_mutex_timedlock(&ru->proc.mutex_synch,&wait) != 0) {
- LOG_E( PHY, "[RU] ERROR pthread_mutex_lock for RU synch thread (IC %d)\n", ru->proc.instance_cnt_synch );
- exit_fun( "error locking mutex_synch" );
- return(-1);
- }
-
- ++ru->proc.instance_cnt_synch;
-
- // the thread can now be woken up
- if (pthread_cond_signal(&ru->proc.cond_synch) != 0) {
- LOG_E( PHY, "[RU] ERROR pthread_cond_signal for RU synch thread\n");
- exit_fun( "ERROR pthread_cond_signal" );
- return(-1);
- }
-
- pthread_mutex_unlock( &ru->proc.mutex_synch );
- return(0);
-}
-
-void do_ru_synch(RU_t *ru) {
- NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
- RU_proc_t *proc = &ru->proc;
- int i;
- void *rxp[2],*rxp2[2];
- int32_t dummy_rx[ru->nb_rx][fp->samples_per_subframe] __attribute__((aligned(32)));
- int rxs;
- int ic;
-
- // initialize the synchronization buffer to the common_vars.rxdata
- for (int i=0; inb_rx; i++)
- rxp[i] = &ru->common.rxdata[i][0];
-
- double temp_freq1 = ru->rfdevice.openair0_cfg->rx_freq[0];
- double temp_freq2 = ru->rfdevice.openair0_cfg->tx_freq[0];
-
- for (i=0; i<4; i++) {
- ru->rfdevice.openair0_cfg->rx_freq[i] = ru->rfdevice.openair0_cfg->tx_freq[i];
- ru->rfdevice.openair0_cfg->tx_freq[i] = temp_freq1;
- }
-
- ru->rfdevice.trx_set_freq_func(&ru->rfdevice,ru->rfdevice.openair0_cfg,0);
-
- while ((ru->in_synch ==0)&&(!oai_exit)) {
- // read in frame
- rxs = ru->rfdevice.trx_read_func(&ru->rfdevice,
- &(proc->timestamp_rx),
- rxp,
- fp->samples_per_subframe*10,
- ru->nb_rx);
-
- if (rxs != fp->samples_per_subframe*10) LOG_E(PHY,"requested %d samples, got %d\n",fp->samples_per_subframe*10,rxs);
-
- // wakeup synchronization processing thread
- wakeup_synch(ru);
- ic=0;
-
- while ((ic>=0)&&(!oai_exit)) {
- // continuously read in frames, 1ms at a time,
- // until we are done with the synchronization procedure
- for (i=0; inb_rx; i++)
- rxp2[i] = (void *)&dummy_rx[i][0];
-
- for (i=0; i<10; i++)
- rxs = ru->rfdevice.trx_read_func(&ru->rfdevice,
- &(proc->timestamp_rx),
- rxp2,
- fp->samples_per_subframe,
- ru->nb_rx);
-
- pthread_mutex_lock(&ru->proc.mutex_synch);
- ic = ru->proc.instance_cnt_synch;
- pthread_mutex_unlock(&ru->proc.mutex_synch);
- } // ic>=0
- } // in_synch==0
-
- // read in rx_offset samples
- LOG_I(PHY,"Resynchronizing by %d samples\n",ru->rx_offset);
- rxs = ru->rfdevice.trx_read_func(&ru->rfdevice,
- &(proc->timestamp_rx),
- rxp,
- ru->rx_offset,
- ru->nb_rx);
-
- for (i=0; i<4; i++) {
- ru->rfdevice.openair0_cfg->rx_freq[i] = temp_freq1;
- ru->rfdevice.openair0_cfg->tx_freq[i] = temp_freq2;
- }
-
- ru->rfdevice.trx_set_freq_func(&ru->rfdevice,ru->rfdevice.openair0_cfg,0);
-}
-
-
-
-void wakeup_gNB_L1s(RU_t *ru) {
- int i;
- PHY_VARS_gNB **gNB_list = ru->gNB_list;
- LOG_D(PHY,"wakeup_gNB_L1s (num %d) for RU %d ru->gNB_top:%p\n",ru->num_gNB,ru->idx, ru->gNB_top);
-
- if (ru->num_gNB==1 && ru->gNB_top!=0 && get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD) {
- // call gNB function directly
- char string[20];
- sprintf(string,"Incoming RU %u",ru->idx);
- LOG_D(PHY,"RU %d Call gNB_top\n",ru->idx);
- ru->gNB_top(gNB_list[0],ru->proc.frame_rx,ru->proc.tti_rx,string,ru);
- } else {
- LOG_D(PHY,"ru->num_gNB:%d\n", ru->num_gNB);
-
- for (i=0; inum_gNB; i++) {
- LOG_D(PHY,"ru->wakeup_rxtx:%p\n", ru->nr_wakeup_rxtx);
-
- if (ru->nr_wakeup_rxtx!=0 && ru->nr_wakeup_rxtx(gNB_list[i],ru) < 0) {
- LOG_E(PHY,"could not wakeup gNB rxtx process for subframe %d\n", ru->proc.tti_rx);
- }
- }
- }
-}
-
-int wakeup_prach_ru(RU_t *ru) {
- struct timespec wait;
- wait.tv_sec=0;
- wait.tv_nsec=5000000L;
-
- if (pthread_mutex_timedlock(&ru->proc.mutex_prach,&wait) !=0) {
- LOG_E( PHY, "[RU] ERROR pthread_mutex_lock for RU prach thread (IC %d)\n", ru->proc.instance_cnt_prach);
- exit_fun( "error locking mutex_rxtx" );
- return(-1);
- }
-
- if (ru->proc.instance_cnt_prach==-1) {
- ++ru->proc.instance_cnt_prach;
- ru->proc.frame_prach = ru->proc.frame_rx;
- ru->proc.subframe_prach = ru->proc.tti_rx;
-
- // DJP - think prach_procedures() is looking at gNB frame_prach
- if (ru->gNB_list[0]) {
- ru->gNB_list[0]->proc.frame_prach = ru->proc.frame_rx;
- ru->gNB_list[0]->proc.slot_prach = ru->proc.tti_rx;
- }
-
- LOG_I(PHY,"RU %d: waking up PRACH thread\n",ru->idx);
- // the thread can now be woken up
- AssertFatal(pthread_cond_signal(&ru->proc.cond_prach) == 0, "ERROR pthread_cond_signal for RU prach thread\n");
- } else LOG_W(PHY,"RU prach thread busy, skipping\n");
-
- pthread_mutex_unlock( &ru->proc.mutex_prach );
- return(0);
-}
-
// this is for RU with local RF unit
void fill_rf_config(RU_t *ru, char *rf_config_file) {
int i;
@@ -1298,136 +1046,61 @@ void *ru_stats_thread(void *param) {
return(NULL);
}
-void *ru_thread_tx( void *param ) {
- RU_t *ru = (RU_t *)param;
- RU_proc_t *proc = &ru->proc;
- NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
- PHY_VARS_gNB *gNB;
- gNB_L1_proc_t *gNB_proc;
- gNB_L1_rxtx_proc_t *L1_proc;
- char filename[40];
- int print_frame = 8;
- int i = 0;
- int ret;
-
+void ru_tx_func(void *param) {
- wait_on_condition(&proc->mutex_FH1,&proc->cond_FH1,&proc->instance_cnt_FH1,"ru_thread_tx");
- printf( "ru_thread_tx ready\n");
+ processingData_RU_t *info = (processingData_RU_t *) param;
+ RU_t *ru = info->ru;
+ NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
+ int frame_tx = info->frame_tx;
+ int slot_tx = info->slot_tx;
+ int print_frame = 8;
+ char filename[40];
- while (!oai_exit) {
+ // do TX front-end processing if needed (precoding and/or IDFTs)
+ if (ru->feptx_prec) ru->feptx_prec(ru,frame_tx,slot_tx);
- LOG_D(PHY,"ru_thread_tx: Waiting for TX processing\n");
- // wait until eNBs are finished subframe RX n and TX n+4
+ // do OFDM with/without TX front-end processing if needed
+ if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,frame_tx,slot_tx);
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RU_TX_WAIT, 1 );
- wait_on_condition(&proc->mutex_gNBs,&proc->cond_gNBs,&proc->instance_cnt_gNBs,"ru_thread_tx");
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RU_TX_WAIT, 0 );
+ if(!emulate_rf) {
+ // do outgoing fronthaul (south) if needed
+ if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,frame_tx,slot_tx,info->timestamp_tx);
- ret = pthread_mutex_lock(&proc->mutex_gNBs);
- AssertFatal(ret == 0,"mutex_lock return %d\n",ret);
- int frame_tx=proc->frame_tx;
- int tti_tx =proc->tti_tx;
- uint64_t timestamp_tx = proc->timestamp_tx;
+ if (ru->fh_north_out) ru->fh_north_out(ru);
+ } else {
+ if(frame_tx == print_frame) {
+ for (int i=0; inb_tx; i++) {
- ret = pthread_mutex_unlock(&proc->mutex_gNBs);
- AssertFatal(ret == 0,"mutex_lock returns %d\n",ret);
+ if(slot_tx == 0) {
+ sprintf(filename,"gNBdataF_frame%d_sl%d.m", print_frame, slot_tx);
+ LOG_M(filename,"txdataF_frame",&ru->gNB_list[0]->common_vars.txdataF[i][0],fp->samples_per_frame_wCP, 1, 1);
- if (oai_exit) break;
+ sprintf(filename,"tx%ddataF_frame%d_sl%d.m", i, print_frame, slot_tx);
+ LOG_M(filename,"txdataF_frame",&ru->common.txdataF[i][0],fp->samples_per_frame_wCP, 1, 1);
- VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame_tx );
- VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, tti_tx );
-
- // do TX front-end processing if needed (precoding and/or IDFTs)
- if (ru->feptx_prec) ru->feptx_prec(ru,frame_tx,tti_tx);
-
- // do OFDM with/without TX front-end processing if needed
- if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,frame_tx,tti_tx);
-
- if(!emulate_rf) {
- // do outgoing fronthaul (south) if needed
- if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,frame_tx,tti_tx,timestamp_tx);
-
- if (ru->fh_north_out) ru->fh_north_out(ru);
- } else {
- if(proc->frame_tx == print_frame) {
- for (i=0; inb_tx; i++) {
-
- if(proc->tti_tx == 0) {
- sprintf(filename,"gNBdataF_frame%d_sl%d.m", print_frame, proc->tti_tx);
- LOG_M(filename,"txdataF_frame",&ru->gNB_list[0]->common_vars.txdataF[i][0],fp->samples_per_frame_wCP, 1, 1);
-
- sprintf(filename,"tx%ddataF_frame%d_sl%d.m", i, print_frame, proc->tti_tx);
- LOG_M(filename,"txdataF_frame",&ru->common.txdataF[i][0],fp->samples_per_frame_wCP, 1, 1);
-
- sprintf(filename,"tx%ddataF_BF_frame%d_sl%d.m", i, print_frame, proc->tti_tx);
- LOG_M(filename,"txdataF_BF_frame",&ru->common.txdataF_BF[i][0],fp->samples_per_subframe_wCP, 1, 1);
- }
-
- if(proc->tti_tx == 9) {
- sprintf(filename,"tx%ddata_frame%d.m", i, print_frame);
- LOG_M(filename,"txdata_frame",&ru->common.txdata[i][0],fp->samples_per_frame, 1, 1);
- sprintf(filename,"tx%ddata_frame%d.dat", i, print_frame);
- FILE *output_fd = fopen(filename,"w");
-
- if (output_fd) {
- fwrite(&ru->common.txdata[i][0],
- sizeof(int32_t),
- fp->samples_per_frame,
- output_fd);
- fclose(output_fd);
- } else {
- LOG_E(PHY,"Cannot write to file %s\n",filename);
- }
- }//if(proc->tti_tx == 9)
- }//for (i=0; inb_tx; i++)
- }//if(proc->frame_tx == print_frame)
- }//else emulate_rf
-
- release_thread(&proc->mutex_gNBs,&proc->instance_cnt_gNBs,"ru_thread_tx");
- VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_UE, proc->instance_cnt_gNBs);
-
- for(i = 0; inum_gNB; i++) {
- gNB = ru->gNB_list[i];
- gNB_proc = &gNB->proc;
- L1_proc = (get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)? &gNB_proc->L1_proc_tx : &gNB_proc->L1_proc;
- ret = pthread_mutex_lock(&gNB_proc->mutex_RU_tx);
- AssertFatal(ret == 0,"mutex_lock returns %d\n",ret);
-
- for (int j=0; jnum_RU; j++) {
- if (ru == gNB->RU_list[j]) {
- if ((gNB_proc->RU_mask_tx&(1< 0)
- LOG_E(PHY,"gNB %d frame %d, subframe %d : previous information from RU tx %d (num_RU %d,mask %x) has not been served yet!\n",
- gNB->Mod_id,gNB_proc->frame_rx,gNB_proc->slot_rx,ru->idx,gNB->num_RU,gNB_proc->RU_mask_tx);
-
- gNB_proc->RU_mask_tx |= (1<common.txdataF_BF[i][0],fp->samples_per_subframe_wCP, 1, 1);
}
- }
- if (gNB_proc->RU_mask_tx != (1<num_RU)-1) { // not all RUs have provided their information so return
- ret = pthread_mutex_unlock(&gNB_proc->mutex_RU_tx);
- AssertFatal(ret == 0,"mutex_unlock returns %d\n",ret);
- } else { // all RUs TX are finished so send the ready signal to gNB processing
- gNB_proc->RU_mask_tx = 0;
- ret = pthread_mutex_unlock(&gNB_proc->mutex_RU_tx);
- AssertFatal(ret == 0,"mutex_unlock returns %d\n",ret);
+ if(slot_tx == 9) {
+ sprintf(filename,"tx%ddata_frame%d.m", i, print_frame);
+ LOG_M(filename,"txdata_frame",&ru->common.txdata[i][0],fp->samples_per_frame, 1, 1);
+ sprintf(filename,"tx%ddata_frame%d.dat", i, print_frame);
+ FILE *output_fd = fopen(filename,"w");
- ret = pthread_mutex_lock(&L1_proc->mutex_RUs_tx);
- AssertFatal(ret == 0,"mutex_lock returns %d\n",ret);
- // the thread can now be woken up
- if (L1_proc->instance_cnt_RUs == -1) {
- L1_proc->instance_cnt_RUs = 0;
- VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,L1_proc->instance_cnt_RUs);
- AssertFatal(pthread_cond_signal(&L1_proc->cond_RUs) == 0,
- "ERROR pthread_cond_signal for gNB_L1_thread\n");
- } //else AssertFatal(1==0,"gNB TX thread is not ready\n");
- ret = pthread_mutex_unlock(&L1_proc->mutex_RUs_tx);
- AssertFatal(ret == 0,"mutex_unlock returns %d\n",ret);
- }
- }
- }
-
- release_thread(&proc->mutex_FH1,&proc->instance_cnt_FH1,"ru_thread_tx");
- return 0;
+ if (output_fd) {
+ fwrite(&ru->common.txdata[i][0],
+ sizeof(int32_t),
+ fp->samples_per_frame,
+ output_fd);
+ fclose(output_fd);
+ } else {
+ LOG_E(PHY,"Cannot write to file %s\n",filename);
+ }
+ }//if(slot_tx == 9)
+ }//for (i=0; inb_tx; i++)
+ }//if(frame_tx == print_frame)
+ }//else emulate_rf
}
void *ru_thread( void *param ) {
@@ -1435,12 +1108,11 @@ void *ru_thread( void *param ) {
RU_t *ru = (RU_t *)param;
RU_proc_t *proc = &ru->proc;
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
+ PHY_VARS_gNB *gNB = RC.gNB[0];
int ret;
int slot = fp->slots_per_frame-1;
int frame = 1023;
- char filename[40], threadname[40];
- int print_frame = 8;
- int i = 0;
+ char threadname[40];
int aa;
nfapi_nr_config_request_scf_t *cfg = &ru->config;
@@ -1500,6 +1172,15 @@ void *ru_thread( void *param ) {
pthread_mutex_unlock(&RC.ru_mutex);
wait_sync("ru_thread");
+ notifiedFIFO_elt_t *msg = newNotifiedFIFO_elt(sizeof(processingData_L1_t),0,gNB->resp_L1,rx_func);
+ notifiedFIFO_elt_t *msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1_t),0,gNB->resp_L1_tx,tx_func);
+ notifiedFIFO_elt_t *msgRUTx = newNotifiedFIFO_elt(sizeof(processingData_L1_t),0,gNB->resp_RU_tx,ru_tx_func);
+ processingData_L1_t *syncMsg;
+ notifiedFIFO_elt_t *res;
+ pushNotifiedFIFO(gNB->resp_L1,msg); // to unblock the process in the beginning
+ pushNotifiedFIFO(gNB->resp_L1_tx,msgL1Tx); // to unblock the process in the beginning
+ pushNotifiedFIFO(gNB->resp_RU_tx,msgRUTx); // to unblock the process in the beginning
+
if(!emulate_rf) {
// Start RF device if any
if (ru->start_rf) {
@@ -1508,19 +1189,6 @@ void *ru_thread( void *param ) {
else LOG_I(PHY,"RU %d rf device ready\n",ru->idx);
} else LOG_I(PHY,"RU %d no rf device\n",ru->idx);
- // if an asnych_rxtx thread exists
- // wakeup the thread because the devices are ready at this point
-
- if ((ru->fh_south_asynch_in)||(ru->fh_north_asynch_in)) {
- pthread_mutex_lock(&proc->mutex_asynch_rxtx);
- proc->instance_cnt_asynch_rxtx=0;
- pthread_mutex_unlock(&proc->mutex_asynch_rxtx);
- pthread_cond_signal(&proc->cond_asynch_rxtx);
- } else LOG_I(PHY,"RU %d no asynch_south interface\n",ru->idx);
-
- // if this is a slave RRU, try to synchronize on the DL frequency
- if ((ru->is_slave) && (ru->if_south == LOCAL_RF)) do_ru_synch(ru);
-
// start trx write thread
if(usrp_tx_thread == 1){
if (ru->start_write_thread){
@@ -1534,11 +1202,6 @@ void *ru_thread( void *param ) {
}
}
- pthread_mutex_lock(&proc->mutex_FH1);
- proc->instance_cnt_FH1 = 0;
- pthread_mutex_unlock(&proc->mutex_FH1);
- pthread_cond_signal(&proc->cond_FH1);
-
// This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices
while (!oai_exit) {
// these are local subframe/frame counters to check that we are in synch with the fronthaul timing.
@@ -1556,31 +1219,23 @@ void *ru_thread( void *param ) {
if (ru->fh_south_in) ru->fh_south_in(ru,&frame,&slot);
else AssertFatal(1==0, "No fronthaul interface at south port");
+ proc->timestamp_tx = proc->timestamp_rx + (sf_ahead*fp->samples_per_subframe);
+ proc->frame_tx = (proc->tti_rx > (fp->slots_per_frame-1-(fp->slots_per_subframe*sf_ahead))) ? (proc->frame_rx+1)&1023 : proc->frame_rx;
+ proc->tti_tx = (proc->tti_rx + (fp->slots_per_subframe*sf_ahead))%fp->slots_per_frame;
+
LOG_D(PHY,"AFTER fh_south_in - SFN/SL:%d%d RU->proc[RX:%d.%d TX:%d.%d] RC.gNB[0]:[RX:%d%d TX(SFN):%d]\n",
frame,slot,
proc->frame_rx,proc->tti_rx,
proc->frame_tx,proc->tti_tx,
RC.gNB[0]->proc.frame_rx,RC.gNB[0]->proc.slot_rx,
RC.gNB[0]->proc.frame_tx);
- /*
- LOG_D(PHY,"RU thread (do_prach %d, is_prach_subframe %d), received frame %d, subframe %d\n",
- ru->do_prach,
- is_prach_subframe(fp, proc->frame_rx, proc->tti_rx),
- proc->frame_rx,proc->tti_rx);
- if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->tti_rx)==1)) {
- wakeup_prach_ru(ru);
- }*/
-
- // adjust for timing offset between RU
- //printf("~~~~~~~~~~~~~~~~~~~~~~~~~~%d.%d in ru_thread is in process\n", proc->frame_rx, proc->tti_rx);
if (ru->idx!=0) proc->frame_tx = (proc->frame_tx+proc->frame_offset)&1023;
// do RX front-end processing (frequency-shift, dft) if needed
int slot_type = nr_slot_select(cfg,proc->frame_rx,proc->tti_rx);
if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) {
- //if (proc->tti_rx==8) {
if (ru->feprx) {
ru->feprx(ru,proc->tti_rx);
@@ -1630,50 +1285,17 @@ void *ru_thread( void *param ) {
}
// At this point, all information for subframe has been received on FH interface
+ res = pullTpool(gNB->resp_L1, gNB->threadPool);
+ syncMsg = (processingData_L1_t *)NotifiedFifoData(res);
+ syncMsg->gNB = gNB;
+ syncMsg->frame_rx = proc->frame_rx;
+ syncMsg->slot_rx = proc->tti_rx;
+ syncMsg->frame_tx = proc->frame_tx;
+ syncMsg->slot_tx = proc->tti_tx;
+ syncMsg->timestamp_tx = proc->timestamp_tx;
+ res->key = proc->tti_rx;
+ pushTpool(gNB->threadPool, res);
- // wakeup all gNB processes waiting for this RU
- if (ru->num_gNB>0) wakeup_gNB_L1s(ru);
-
- if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD || ru->num_gNB==0) {
- // do TX front-end processing if needed (precoding and/or IDFTs)
- if (ru->feptx_prec) ru->feptx_prec(ru,proc->frame_tx,proc->tti_tx);
-
- // do OFDM with/without TX front-end processing if needed
- if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,proc->frame_tx,proc->tti_tx);
-
- if(!emulate_rf) {
- // do outgoing fronthaul (south) if needed
- if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru,proc->frame_tx,proc->tti_tx,proc->timestamp_tx);
-
- if (ru->fh_north_out) ru->fh_north_out(ru);
- } else {
- if(proc->frame_tx == print_frame) {
- for (i=0; inb_tx; i++) {
- sprintf(filename,"tx%ddataF_frame%d_sl%d.m", i, print_frame, proc->tti_tx);
- LOG_M(filename,"txdataF_frame",&ru->common.txdataF_BF[i][0],fp->samples_per_slot_wCP, 1, 1);
-
- if(proc->tti_tx == 9) {
- sprintf(filename,"tx%ddata_frame%d.m", i, print_frame);
- LOG_M(filename,"txdata_frame",&ru->common.txdata[i][0],fp->samples_per_frame, 1, 1);
- sprintf(filename,"tx%ddata_frame%d.dat", i, print_frame);
- FILE *output_fd = fopen(filename,"w");
-
- if (output_fd) {
- fwrite(&ru->common.txdata[i][0],
- sizeof(int32_t),
- fp->samples_per_frame,
- output_fd);
- fclose(output_fd);
- } else {
- LOG_E(PHY,"Cannot write to file %s\n",filename);
- }
- }//if(proc->tti_tx == 9)
- }//for (i=0; inb_tx; i++)
- }//if(proc->frame_tx == print_frame)
- }//else emulate_rf
-
- proc->emulate_rf_busy = 0;
- }//if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD)
}
printf( "Exiting ru_thread \n");
@@ -1684,85 +1306,13 @@ void *ru_thread( void *param ) {
else LOG_I(PHY,"RU %d rf device stopped\n",ru->idx);
}
+ delNotifiedFIFO_elt(msg);
+ delNotifiedFIFO_elt(msgL1Tx);
+ delNotifiedFIFO_elt(msgRUTx);
+
ru_thread_status = 0;
return &ru_thread_status;
}
-/*
-// This thread run the initial synchronization like a UE
-void *ru_thread_synch(void *arg) {
-
- RU_t *ru = (RU_t*)arg;
- NR_DL_FRAME_PARMS *fp=ru->nr_frame_parms;
- int32_t sync_pos,sync_pos2;
- uint32_t peak_val;
- uint32_t sync_corr[307200] __attribute__((aligned(32)));
- static int ru_thread_synch_status;
-
-
-
- wait_sync("ru_thread_synch");
-
- // initialize variables for PSS detection
- lte_sync_time_init(ru->nr_frame_parms);
-
- while (!oai_exit) {
-
- // wait to be woken up
- if (wait_on_condition(&ru->proc.mutex_synch,&ru->proc.cond_synch,&ru->proc.instance_cnt_synch,"ru_thread_synch")<0) break;
-
- // if we're not in synch, then run initial synch
- if (ru->in_synch == 0) {
- // run intial synch like UE
- LOG_I(PHY,"Running initial synchronization\n");
-
- sync_pos = lte_sync_time_gNB(ru->common.rxdata,
- fp,
- fp->samples_per_subframe*5,
- &peak_val,
- sync_corr);
- LOG_I(PHY,"RU synch: %d, val %d\n",sync_pos,peak_val);
-
- if (sync_pos >= 0) {
- if (sync_pos >= fp->nb_prefix_samples)
- sync_pos2 = sync_pos - fp->nb_prefix_samples;
- else
- sync_pos2 = sync_pos + (fp->samples_per_subframe*10) - fp->nb_prefix_samples;
-
- if (fp->frame_type == FDD) {
-
- // PSS is hypothesized in last symbol of first slot in Frame
- int sync_pos_slot = (fp->samples_per_subframe>>1) - fp->ofdm_symbol_size - fp->nb_prefix_samples;
-
- if (sync_pos2 >= sync_pos_slot)
- ru->rx_offset = sync_pos2 - sync_pos_slot;
- else
- ru->rx_offset = (fp->samples_per_subframe*10) + sync_pos2 - sync_pos_slot;
- }
- else {
-
- }
-
- LOG_I(PHY,"Estimated sync_pos %d, peak_val %d => timing offset %d\n",sync_pos,peak_val,ru->rx_offset);
-
- if ((peak_val > 300000) && (sync_pos > 0)) {
- // if (sync_pos++ > 3) {
- write_output("ru_sync.m","sync",(void*)&sync_corr[0],fp->samples_per_subframe*5,1,2);
- write_output("ru_rx.m","rxs",(void*)ru->ru_time.rxdata[0][0],fp->samples_per_subframe*10,1,1);
- exit(-1);
- }
-
- ru->in_synch=1;
- }
- }
-
- if (release_thread(&ru->proc.mutex_synch,&ru->proc.instance_cnt_synch,"ru_synch_thread") < 0) break;
- } // oai_exit
-
- ru_thread_synch_status = 0;
- return &ru_thread_synch_status;
-
-}
-*/
int nr_start_if(struct RU_t_s *ru, struct PHY_VARS_gNB_s *gNB) {
return(ru->ifdevice.trx_start_func(&ru->ifdevice));
@@ -1784,17 +1334,10 @@ int start_write_thread(RU_t *ru) {
void init_RU_proc(RU_t *ru) {
int i=0;
RU_proc_t *proc;
- char name[100];
LOG_I(PHY,"Initializing RU proc %d (%s,%s),\n",ru->idx,NB_functions[ru->function],NB_timing[ru->if_timing]);
proc = &ru->proc;
memset((void *)proc,0,sizeof(RU_proc_t));
proc->ru = ru;
- proc->instance_cnt_prach = -1;
- proc->instance_cnt_synch = -1;
- proc->instance_cnt_FH = -1;
- proc->instance_cnt_FH1 = -1;
- proc->instance_cnt_gNBs = -1;
- proc->instance_cnt_asynch_rxtx = -1;
proc->instance_cnt_emulateRF = -1;
proc->first_rx = 1;
proc->first_tx = 1;
@@ -1805,44 +1348,13 @@ void init_RU_proc(RU_t *ru) {
for (i=0; i<10; i++) proc->symbol_mask[i]=0;
- pthread_mutex_init( &proc->mutex_prach, NULL);
- pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL);
- pthread_mutex_init( &proc->mutex_synch,NULL);
- pthread_mutex_init( &proc->mutex_FH,NULL);
- pthread_mutex_init( &proc->mutex_FH1,NULL);
pthread_mutex_init( &proc->mutex_emulateRF,NULL);
- pthread_mutex_init( &proc->mutex_gNBs, NULL);
- pthread_cond_init( &proc->cond_prach, NULL);
- pthread_cond_init( &proc->cond_FH, NULL);
- pthread_cond_init( &proc->cond_FH1, NULL);
pthread_cond_init( &proc->cond_emulateRF, NULL);
- pthread_cond_init( &proc->cond_asynch_rxtx, NULL);
- pthread_cond_init( &proc->cond_synch,NULL);
- pthread_cond_init( &proc->cond_gNBs, NULL);
threadCreate( &proc->pthread_FH, ru_thread, (void *)ru, "thread_FH", -1, OAI_PRIORITY_RT_MAX );
- if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)
- threadCreate( &proc->pthread_FH1, ru_thread_tx, (void *)ru, "thread_FH1", -1, OAI_PRIORITY_RT );
-
if(emulate_rf)
threadCreate( &proc->pthread_emulateRF, emulatedRF_thread, (void *)proc, "emulateRF", -1, OAI_PRIORITY_RT );
- if (ru->function == NGFI_RRU_IF4p5) {
- threadCreate( &proc->pthread_prach, ru_thread_prach, (void *)ru, "RACH", -1, OAI_PRIORITY_RT );
- ///tmp deactivation of synch thread
- // if (ru->is_slave == 1) pthread_create( &proc->pthread_synch, attr_synch, ru_thread_synch, (void*)ru);
-
- if ((ru->if_timing == synch_to_other) ||
- (ru->function == NGFI_RRU_IF5) ||
- (ru->function == NGFI_RRU_IF4p5)) threadCreate( &proc->pthread_asynch_rxtx, ru_thread_asynch_rxtx, (void *)ru, "asynch_rxtx", -1, OAI_PRIORITY_RT );
-
- snprintf( name, sizeof(name), "ru_thread_FH %d", ru->idx );
- pthread_setname_np( proc->pthread_FH, name );
- } else if (ru->function == gNodeB_3GPP && ru->if_south == LOCAL_RF) { // DJP - need something else to distinguish between monolithic and PNF
- LOG_I(PHY,"%s() DJP - added creation of pthread_prach\n", __FUNCTION__);
- threadCreate( &proc->pthread_prach, ru_thread_prach, (void *)ru,"RACH", -1, OAI_PRIORITY_RT );
- }
-
if (get_thread_worker_conf() == WORKER_ENABLE) {
if (ru->feprx) nr_init_feprx_thread(ru);
@@ -1855,46 +1367,9 @@ void init_RU_proc(RU_t *ru) {
void kill_NR_RU_proc(int inst) {
RU_t *ru = RC.ru[inst];
RU_proc_t *proc = &ru->proc;
- pthread_mutex_lock(&proc->mutex_FH);
- proc->instance_cnt_FH = 0;
- pthread_mutex_unlock(&proc->mutex_FH);
- pthread_cond_signal(&proc->cond_FH);
- pthread_mutex_lock(&proc->mutex_prach);
- proc->instance_cnt_prach = 0;
- pthread_mutex_unlock(&proc->mutex_prach);
- pthread_cond_signal(&proc->cond_prach);
- pthread_mutex_lock(&proc->mutex_synch);
- proc->instance_cnt_synch = 0;
- pthread_mutex_unlock(&proc->mutex_synch);
- pthread_cond_signal(&proc->cond_synch);
- pthread_mutex_lock(&proc->mutex_gNBs);
- proc->instance_cnt_gNBs = 0;
- pthread_mutex_unlock(&proc->mutex_gNBs);
- pthread_cond_signal(&proc->cond_gNBs);
- pthread_mutex_lock(&proc->mutex_asynch_rxtx);
- proc->instance_cnt_asynch_rxtx = 0;
- pthread_mutex_unlock(&proc->mutex_asynch_rxtx);
- pthread_cond_signal(&proc->cond_asynch_rxtx);
LOG_D(PHY, "Joining pthread_FH\n");
pthread_join(proc->pthread_FH, NULL);
- if (ru->function == NGFI_RRU_IF4p5) {
- LOG_D(PHY, "Joining pthread_prach\n");
- pthread_join(proc->pthread_prach, NULL);
-
- if (ru->is_slave) {
- LOG_D(PHY, "Joining pthread_\n");
- pthread_join(proc->pthread_synch, NULL);
- }
-
- if ((ru->if_timing == synch_to_other) ||
- (ru->function == NGFI_RRU_IF5) ||
- (ru->function == NGFI_RRU_IF4p5)) {
- LOG_D(PHY, "Joining pthread_asynch_rxtx\n");
- pthread_join(proc->pthread_asynch_rxtx, NULL);
- }
- }
-
if (get_nprocs() >= 2) {
if (ru->feprx) {
pthread_mutex_lock(&proc->mutex_fep);
@@ -1923,17 +1398,6 @@ void kill_NR_RU_proc(int inst) {
LOG_D(PHY, "Joining ru_stats_thread\n");
pthread_join(ru->ru_stats_thread, NULL);
}
-
- pthread_mutex_destroy(&proc->mutex_prach);
- pthread_mutex_destroy(&proc->mutex_asynch_rxtx);
- pthread_mutex_destroy(&proc->mutex_synch);
- pthread_mutex_destroy(&proc->mutex_FH);
- pthread_mutex_destroy(&proc->mutex_gNBs);
- pthread_cond_destroy(&proc->cond_prach);
- pthread_cond_destroy(&proc->cond_FH);
- pthread_cond_destroy(&proc->cond_asynch_rxtx);
- pthread_cond_destroy(&proc->cond_synch);
- pthread_cond_destroy(&proc->cond_gNBs);
}
int check_capabilities(RU_t *ru,RRU_capabilities_t *cap)
diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c
index d986e98267..924c32b8a7 100644
--- a/executables/nr-softmodem.c
+++ b/executables/nr-softmodem.c
@@ -85,12 +85,13 @@ unsigned short config_frames[4] = {2,9,11,13};
#include "x2ap_eNB.h"
#include "ngap_gNB.h"
#include "gnb_paramdef.h"
+#include "nfapi/oai_integration/vendor_ext.h"
pthread_cond_t nfapi_sync_cond;
pthread_mutex_t nfapi_sync_mutex;
int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex
-uint8_t nfapi_mode = 0; // Default to monolithic mode
+extern uint8_t nfapi_mode; // Default to monolithic mode
pthread_cond_t sync_cond;
pthread_mutex_t sync_mutex;
@@ -811,7 +812,7 @@ if(!IS_SOFTMODEM_NOS1)
AssertFatal(create_gNB_tasks(1) == 0,"cannot create ITTI tasks\n");
} else {
printf("No ITTI, Initializing L1\n");
- RCconfig_L1();
+ RCconfig_NR_L1();
}
/* Start the agent. If it is turned off in the configuration, it won't start */
@@ -832,7 +833,7 @@ if(!IS_SOFTMODEM_NOS1)
usleep(1000);
- if (nfapi_mode) {
+ if (NFAPI_MODE) {
printf("NFAPI*** - mutex and cond created - will block shortly for completion of PNF connection\n");
pthread_cond_init(&sync_cond,NULL);
pthread_mutex_init(&sync_mutex, NULL);
@@ -840,7 +841,7 @@ if(!IS_SOFTMODEM_NOS1)
const char *nfapi_mode_str = "";
- switch(nfapi_mode) {
+ switch(NFAPI_MODE) {
case 0:
nfapi_mode_str = "MONOLITHIC";
break;
@@ -860,7 +861,7 @@ if(!IS_SOFTMODEM_NOS1)
printf("NFAPI MODE:%s\n", nfapi_mode_str);
- if (nfapi_mode==2) // VNF
+ if (NFAPI_MODE==NFAPI_MODE_VNF)
wait_nfapi_init("main?");
printf("START MAIN THREADS\n");
@@ -889,7 +890,7 @@ if(!IS_SOFTMODEM_NOS1)
config_sync_var=0;
- if (nfapi_mode==1) { // PNF
+ if (NFAPI_MODE==NFAPI_MODE_PNF) {
wait_nfapi_init("main?");
}
@@ -909,7 +910,7 @@ if(!IS_SOFTMODEM_NOS1)
load_softscope("nr",&p);
}
- if (nfapi_mode != 1 && nfapi_mode != 2) {
+ if (NFAPI_MODE != NFAPI_MODE_PNF && NFAPI_MODE != NFAPI_MODE_VNF) {
printf("Not NFAPI mode - call init_eNB_afterRU()\n");
init_eNB_afterRU();
} else {
diff --git a/executables/nr-ue.c b/executables/nr-ue.c
index 9cea723664..25e6d85695 100644
--- a/executables/nr-ue.c
+++ b/executables/nr-ue.c
@@ -703,16 +703,23 @@ void *UE_thread(void *arg) {
int flags = 0;
int slot_tx_usrp = slot_nr + DURATION_RX_TO_TX - RX_NB_TH;
- uint8_t tdd_period = mac->phy_config.config_req.tdd_table.tdd_period_in_slots;
- uint8_t num_UL_slots = mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots +
- (mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols!=0);
- uint8_t first_tx_slot = tdd_period - num_UL_slots;
- if (slot_tx_usrp%tdd_period==first_tx_slot)
- flags=2;
- else if (slot_tx_usrp%tdd_period==first_tx_slot+num_UL_slots-1)
- flags = 3;
- else if (slot_tx_usrp%tdd_period>first_tx_slot)
+
+ if (openair0_cfg[0].duplex_mode == duplex_mode_TDD) {
+
+ uint8_t tdd_period = mac->phy_config.config_req.tdd_table.tdd_period_in_slots;
+ int nrofUplinkSlots = mac->scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots;
+ uint8_t num_UL_slots = nrofUplinkSlots + (nrofUplinkSlots != 0);
+ uint8_t first_tx_slot = tdd_period - num_UL_slots;
+
+ if (slot_tx_usrp % tdd_period == first_tx_slot)
+ flags = 2;
+ else if (slot_tx_usrp % tdd_period == first_tx_slot + num_UL_slots - 1)
+ flags = 3;
+ else if (slot_tx_usrp % tdd_period > first_tx_slot)
+ flags = 1;
+ } else {
flags = 1;
+ }
if (flags || IS_SOFTMODEM_RFSIM)
AssertFatal( writeBlockSize ==
diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c
index 87cd157948..451dcd3d29 100644
--- a/executables/nr-uesoftmodem.c
+++ b/executables/nr-uesoftmodem.c
@@ -531,7 +531,8 @@ int main( int argc, char **argv ) {
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]);
- init_symbol_rotation(&UE[CC_id]->frame_parms, UE[CC_id]->frame_parms.dl_CarrierFreq);
+
+ init_symbol_rotation(&UE[CC_id]->frame_parms);
init_nr_ue_vars(UE[CC_id], 0, abstraction_flag);
#ifdef FR2_TEST
@@ -557,11 +558,14 @@ int main( int argc, char **argv ) {
init_NR_UE_threads(1);
- config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS);
printf("UE threads created by %ld\n", gettid());
// wait for end of program
printf("TYPE TO TERMINATE\n");
+ // Sleep a while before checking all parameters have been used
+ // Some are used directly in external threads, asynchronously
+ sleep(20);
+ config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS);
while(true)
sleep(3600);
diff --git a/executables/softmodem-common.c b/executables/softmodem-common.c
index 04a58413b5..1077c0e1ac 100644
--- a/executables/softmodem-common.c
+++ b/executables/softmodem-common.c
@@ -39,11 +39,14 @@
#include "executables/thread-common.h"
#include "common/utils/LOG/log.h"
#include "softmodem-common.h"
+#include "nfapi/oai_integration/vendor_ext.h"
+
static softmodem_params_t softmodem_params;
char *parallel_config=NULL;
char *worker_config=NULL;
+uint8_t nfapi_mode=0;
static mapping softmodem_funcs[] = MAPPING_SOFTMODEM_FUNCTIONS;
static struct timespec start;
@@ -143,6 +146,7 @@ void get_common_options(uint32_t execmask) {
if(parallel_config != NULL) set_parallel_conf(parallel_config);
if(worker_config != NULL) set_worker_conf(worker_config);
+ nfapi_setmode(nfapi_mode);
}
void softmodem_printresources(int sig, telnet_printfunc_t pf) {
struct rusage usage;
diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h
index a6035122c0..7a7be1de96 100644
--- a/executables/softmodem-common.h
+++ b/executables/softmodem-common.h
@@ -91,6 +91,7 @@ extern "C"
#define CONFIG_HLP_RFSIM "Run in rf simulator mode (also known as basic simulator)\n"
#define CONFIG_HLP_NOKRNMOD "(noS1 only): Use tun instead of namesh module \n"
#define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n"
+#define CONFIG_HLP_NFAPI "Change the nFAPI mode for NR\n"
/*-----------------------------------------------------------------------------------------------------------------------------------------------------*/
/* command line parameters common to eNodeB and UE */
@@ -112,6 +113,7 @@ extern "C"
#define SEND_DMRSSYNC softmodem_params.send_dmrs_sync
#define USIM_TEST softmodem_params.usim_test
#define USE_256QAM_TABLE softmodem_params.use_256qam_table
+#define NFAPI softmodem_params.nfapi
#define DEFAULT_RFCONFIG_FILE "/usr/local/etc/syriq/ue.band7.tm1.PRB100.NR40.dat";
@@ -142,6 +144,7 @@ extern "C"
{"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}, \
+ {"nfapi", CONFIG_HLP_NFAPI, 0, u8ptr:&nfapi_mode, defintval:0, TYPE_UINT8, 0}, \
}
@@ -229,6 +232,7 @@ typedef struct {
int hw_timing_advance;
uint32_t send_dmrs_sync;
int use_256qam_table;
+ uint8_t nfapi;
} softmodem_params_t;
extern uint64_t get_softmodem_optmask(void);
@@ -240,6 +244,14 @@ extern char *get_softmodem_function(uint64_t *sofmodemfunc_mask_ptr);
extern void set_softmodem_sighandler(void);
extern uint64_t downlink_frequency[MAX_NUM_CCs][4];
extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
+extern uint16_t sl_ahead;
+extern uint16_t sf_ahead;
+extern volatile int oai_exit;
+
+void tx_func(void *param);
+void rx_func(void *param);
+void ru_tx_func(void *param);
+extern uint8_t nfapi_mode;
#ifdef __cplusplus
}
#endif
diff --git a/nfapi/CHANGES.md b/nfapi/CHANGES.md
new file mode 100644
index 0000000000..4dc68c6ff8
--- /dev/null
+++ b/nfapi/CHANGES.md
@@ -0,0 +1,2 @@
+# Changelog
+
diff --git a/nfapi/nrNFAPI.md b/nfapi/nrNFAPI.md
new file mode 100644
index 0000000000..299a43fd93
--- /dev/null
+++ b/nfapi/nrNFAPI.md
@@ -0,0 +1,35 @@
+# Procedure to run nFAPI in 5G NR
+
+## Conributed by 5G Testbed IISC
+### Developers: Sudhakar B,Mahesh K,Gokul S,Aniq U.R
+
+## Procedure to Build gNB and UE
+
+The regular commands to build gNB and UE can be used
+```
+sudo ./build_oai --gNB --UE
+
+```
+## Procedure to run NR nFAPI using RF-Simulator
+
+### VNF command
+```
+sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf --nfapi 2 --noS1 --phy-test
+
+```
+### PNF command
+```
+sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpx300.conf --nfapi 1 --rfsim --phy-test --rfsimulator.serveraddr server
+
+```
+### UE command
+```
+sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem --rfsim --phy-test --rrc_config_path . -d
+
+```
+## Procedure to run NR nFAPI using Hardware
+Will be updated as we have not yet currently tested on hardware
+
+## Notes
+* In order to acheive the synchronization between VNF and PNF and receive the P7 messages within the timing window the order in which we should run the modules on different terminals is UE->VNF->PNF
+* Currently only downlink is functional and working as we are still working on uplink functionality
diff --git a/nfapi/oai_integration/nfapi_pnf.c b/nfapi/oai_integration/nfapi_pnf.c
index 3dfbc2811d..4ca02ed929 100644
--- a/nfapi/oai_integration/nfapi_pnf.c
+++ b/nfapi/oai_integration/nfapi_pnf.c
@@ -30,6 +30,9 @@
#include "debug.h"
#include "nfapi/oai_integration/vendor_ext.h"
#include "nfapi_pnf_interface.h"
+#include "nfapi_nr_interface.h"
+#include "nfapi_nr_interface_scf.h"
+
#include "nfapi.h"
#include "nfapi_pnf.h"
#include "common/ran_context.h"
@@ -52,6 +55,11 @@ extern RAN_CONTEXT_t RC;
#include "PHY/INIT/phy_init.h"
#include "PHY/LTE_TRANSPORT/transport_proto.h"
+#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
+#include "openair1/SCHED_NR/fapi_nr_l1.h"
+#include "openair1/PHY/NR_TRANSPORT/nr_dlsch.h"
+#include "openair1/PHY/defs_gNB.h"
+
#define NUM_P5_PHY 2
@@ -75,17 +83,46 @@ extern void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame, int subframe, L1
extern 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);
extern 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);
extern 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);
+extern void handle_nfapi_nr_ul_dci_pdu(PHY_VARS_gNB *gNB,
+ int frame, int slot,
+ nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu);
+extern void handle_nfapi_nr_pdcch_pdu(PHY_VARS_gNB *gNB,
+ int frame, int slot,
+ nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu);
+extern void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
+ nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu,
+ uint8_t *sdu);
+extern void handle_nr_nfapi_ssb_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
+ nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu);
+extern void nr_fill_ulsch(PHY_VARS_gNB *gNB,
+ int frame,
+ int slot,
+ nfapi_nr_pusch_pdu_t *ulsch_pdu);
+extern void nr_fill_pucch(PHY_VARS_gNB *gNB,
+ int frame,
+ int slot,
+ nfapi_nr_pucch_pdu_t *pucch_pdu);
+extern void nr_fill_prach(PHY_VARS_gNB *gNB,
+ int SFN,
+ int Slot,
+ nfapi_nr_prach_pdu_t *prach_pdu);
+extern void nr_fill_prach_ru(RU_t *ru,
+ int SFN,
+ int Slot,
+ nfapi_nr_prach_pdu_t *prach_pdu);
+
nfapi_tx_request_pdu_t *tx_request_pdu[1023][10][10]; // [frame][subframe][max_num_pdus]
-
+uint8_t nr_tx_pdus[32][16][4096];
+nfapi_nr_pdu_t *tx_data_request[1023][20][10]; //[frame][slot][max_num_pdus]
uint8_t tx_pdus[32][8][4096];
nfapi_ue_release_request_body_t release_rntis;
uint16_t phy_antenna_capability_values[] = { 1, 2, 4, 8, 16 };
-nfapi_pnf_param_response_t g_pnf_param_resp;
+nfapi_nr_pnf_param_response_t g_pnf_param_resp;
nfapi_pnf_p7_config_t *p7_config_g = NULL;
@@ -248,6 +285,63 @@ void *pnf_p7_thread_start(void *ptr) {
return 0;
}
+void *pnf_nr_p7_thread_start(void *ptr) {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] 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);
+ return 0;
+}
+
+int pnf_nr_param_request(nfapi_pnf_config_t *config, nfapi_nr_pnf_param_request_t *req) {
+ printf("[PNF] pnf param request\n");
+ nfapi_nr_pnf_param_response_t resp;
+ memset(&resp, 0, sizeof(resp));
+ resp.header.message_id = NFAPI_PNF_PARAM_RESPONSE;
+ resp.error_code = NFAPI_MSG_OK;
+ pnf_info *pnf = (pnf_info *)(config->user_data);
+ resp.pnf_param_general.tl.tag = NFAPI_PNF_PARAM_GENERAL_TAG;
+ resp.pnf_param_general.nfapi_sync_mode = pnf->sync_mode;
+ resp.pnf_param_general.location_mode = pnf->location_mode;
+ resp.pnf_param_general.dl_config_timing = pnf->dl_config_timing;
+ resp.pnf_param_general.tx_timing = pnf->tx_timing;
+ resp.pnf_param_general.ul_config_timing = pnf->ul_config_timing;
+ resp.pnf_param_general.hi_dci0_timing = pnf->hi_dci0_timing;
+ resp.pnf_param_general.maximum_number_phys = pnf->max_phys;
+ resp.pnf_param_general.maximum_total_bandwidth = pnf->max_total_bw;
+ resp.pnf_param_general.maximum_total_number_dl_layers = pnf->max_total_dl_layers;
+ resp.pnf_param_general.maximum_total_number_ul_layers = pnf->max_total_ul_layers;
+ resp.pnf_param_general.shared_bands = pnf->shared_bands;
+ resp.pnf_param_general.shared_pa = pnf->shared_pa;
+ resp.pnf_param_general.maximum_total_power = pnf->max_total_power;
+ resp.pnf_phy.tl.tag = NFAPI_PNF_PHY_TAG;
+ resp.pnf_phy.number_of_phys = 1;
+
+ for(int i = 0; i < 1; ++i) {
+ resp.pnf_phy.phy[i].phy_config_index = pnf->phys[i].index;
+ resp.pnf_phy.phy[i].downlink_channel_bandwidth_supported = pnf->phys[i].dl_channel_bw_support;
+ resp.pnf_phy.phy[i].uplink_channel_bandwidth_supported = pnf->phys[i].ul_channel_bw_support;
+ resp.pnf_phy.phy[i].number_of_dl_layers_supported = pnf->phys[i].num_dl_layers_supported;
+ resp.pnf_phy.phy[i].number_of_ul_layers_supported = pnf->phys[i].num_ul_layers_supported;
+ resp.pnf_phy.phy[i].maximum_3gpp_release_supported = pnf->phys[i].release_supported;
+ resp.pnf_phy.phy[i].nmm_modes_supported = pnf->phys[i].nmm_modes_supported;
+ resp.pnf_phy.phy[i].number_of_rfs = 2;
+
+ for(int j = 0; j < 1; ++j) {
+ resp.pnf_phy.phy[i].rf_config[j].rf_config_index = pnf->phys[i].rfs[j];
+ }
+
+ resp.pnf_phy.phy[i].number_of_rf_exclusions = 0;
+
+ for(int j = 0; j < 0; ++j) {
+ resp.pnf_phy.phy[i].excluded_rf_config[j].rf_config_index = pnf->phys[i].excluded_rfs[j];
+ }
+ }
+ nfapi_nr_pnf_pnf_param_resp(config, &resp);
+ return 0;
+}
+
+
int pnf_param_request(nfapi_pnf_config_t *config, nfapi_pnf_param_request_t *req) {
printf("[PNF] pnf param request\n");
nfapi_pnf_param_response_t resp;
@@ -413,6 +507,21 @@ int pnf_config_request(nfapi_pnf_config_t *config, nfapi_pnf_config_request_t *r
return 0;
}
+int pnf_nr_config_request(nfapi_pnf_config_t *config, nfapi_nr_pnf_config_request_t *req) {
+ printf("[PNF] pnf config request\n");
+ pnf_info *pnf = (pnf_info *)(config->user_data);
+ phy_info *phy = pnf->phys;
+ phy->id = req->pnf_phy_rf_config.phy_rf_config[0].phy_id;
+ printf("[PNF] pnf config request assigned phy_id %d to phy_config_index %d\n", phy->id, req->pnf_phy_rf_config.phy_rf_config[0].phy_config_index);
+ nfapi_nr_pnf_config_response_t resp;
+ memset(&resp, 0, sizeof(resp));
+ resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_RESPONSE;
+ resp.error_code = NFAPI_MSG_OK;
+ nfapi_nr_pnf_pnf_config_resp(config, &resp);
+ printf("[PNF] Sent pnf_config_resp\n");
+ return 0;
+}
+
void nfapi_send_pnf_start_resp(nfapi_pnf_config_t *config, uint16_t phy_id) {
printf("Sending NFAPI_START_RESPONSE config:%p phy_id:%d\n", config, phy_id);
nfapi_start_response_t start_resp;
@@ -423,6 +532,16 @@ void nfapi_send_pnf_start_resp(nfapi_pnf_config_t *config, uint16_t phy_id) {
nfapi_pnf_start_resp(config, &start_resp);
}
+void nfapi_nr_send_pnf_start_resp(nfapi_pnf_config_t *config, uint16_t phy_id) {
+ printf("Sending NFAPI_START_RESPONSE config:%p phy_id:%d\n", config, phy_id);
+ nfapi_nr_start_response_scf_t start_resp;
+ memset(&start_resp, 0, sizeof(start_resp));
+ start_resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE;
+ start_resp.header.phy_id = phy_id;
+ start_resp.error_code = NFAPI_MSG_OK;
+ nfapi_nr_pnf_start_resp(config, &start_resp);
+}
+
int pnf_start_request(nfapi_pnf_config_t *config, nfapi_pnf_start_request_t *req) {
printf("Received NFAPI_PNF_START_REQUEST\n");
pnf_info *pnf = (pnf_info *)(config->user_data);
@@ -441,6 +560,24 @@ int pnf_start_request(nfapi_pnf_config_t *config, nfapi_pnf_start_request_t *req
return 0;
}
+int pnf_nr_start_request(nfapi_pnf_config_t *config, nfapi_nr_pnf_start_request_t *req) {
+ printf("Received NFAPI_PNF_START_REQUEST\n");
+ pnf_info *pnf = (pnf_info *)(config->user_data);
+ // start all phys that have been configured
+ phy_info *phy = pnf->phys;
+
+ if(phy->id != 0) {
+ nfapi_nr_pnf_start_response_t resp;
+ memset(&resp, 0, sizeof(resp));
+ resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PNF_START_RESPONSE;
+ resp.error_code = NFAPI_MSG_OK;
+ nfapi_nr_pnf_pnf_start_resp(config, &resp);
+ printf("[PNF] Sent NFAPI_PNF_START_RESP\n");
+ }
+
+ return 0;
+}
+
int pnf_stop_request(nfapi_pnf_config_t *config, nfapi_pnf_stop_request_t *req) {
printf("[PNF] Received NFAPI_PNF_STOP_REQ\n");
nfapi_pnf_stop_response_t resp;
@@ -476,7 +613,228 @@ int param_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi
return 0;
}
-int config_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi_config_request_t *req) {
+int nr_param_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi_nr_param_request_scf_t *req) {
+ printf("[PNF] Received NFAPI_PARAM_REQUEST phy_id:%d\n", req->header.phy_id);
+ //pnf_info* pnf = (pnf_info*)(config->user_data);
+ nfapi_nr_param_response_scf_t nfapi_resp;
+ pnf_info *pnf = (pnf_info *)(config->user_data);
+ memset(&nfapi_resp, 0, sizeof(nfapi_resp));
+ nfapi_resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE;
+ nfapi_resp.header.phy_id = req->header.phy_id;
+ nfapi_resp.error_code = 0; // DJP - what value???
+ struct sockaddr_in pnf_p7_sockaddr;
+
+ // ASSIGN TAGS
+ {
+ nfapi_resp.cell_param.release_capability.tl.tag = NFAPI_NR_PARAM_TLV_RELEASE_CAPABILITY_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.cell_param.phy_state.tl.tag = NFAPI_NR_PARAM_TLV_PHY_STATE_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.cell_param.skip_blank_dl_config.tl.tag = NFAPI_NR_PARAM_TLV_SKIP_BLANK_DL_CONFIG_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.cell_param.skip_blank_ul_config.tl.tag = NFAPI_NR_PARAM_TLV_SKIP_BLANK_UL_CONFIG_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.cell_param.num_config_tlvs_to_report .tl.tag = NFAPI_NR_PARAM_TLV_NUM_CONFIG_TLVS_TO_REPORT_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.carrier_param.cyclic_prefix.tl.tag = NFAPI_NR_PARAM_TLV_CYCLIC_PREFIX_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.carrier_param.supported_subcarrier_spacings_dl.tl.tag = NFAPI_NR_PARAM_TLV_SUPPORTED_SUBCARRIER_SPACINGS_DL_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.carrier_param.supported_bandwidth_dl.tl.tag = NFAPI_NR_PARAM_TLV_SUPPORTED_BANDWIDTH_DL_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.carrier_param.supported_subcarrier_spacings_ul.tl.tag = NFAPI_NR_PARAM_TLV_SUPPORTED_SUBCARRIER_SPACINGS_UL_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.carrier_param.supported_bandwidth_ul.tl.tag = NFAPI_NR_PARAM_TLV_SUPPORTED_BANDWIDTH_UL_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pdcch_param.cce_mapping_type.tl.tag = NFAPI_NR_PARAM_TLV_CCE_MAPPING_TYPE_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pdcch_param.coreset_outside_first_3_of_ofdm_syms_of_slot.tl.tag = NFAPI_NR_PARAM_TLV_CORESET_OUTSIDE_FIRST_3_OFDM_SYMS_OF_SLOT_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pdcch_param.coreset_precoder_granularity_coreset.tl.tag = NFAPI_NR_PARAM_TLV_PRECODER_GRANULARITY_CORESET_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pdcch_param.pdcch_mu_mimo.tl.tag = NFAPI_NR_PARAM_TLV_PDCCH_MU_MIMO_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pdcch_param.pdcch_precoder_cycling.tl.tag = NFAPI_NR_PARAM_TLV_PDCCH_PRECODER_CYCLING_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pdcch_param.max_pdcch_per_slot.tl.tag = NFAPI_NR_PARAM_TLV_MAX_PDCCHS_PER_SLOT_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pucch_param.pucch_formats.tl.tag = NFAPI_NR_PARAM_TLV_PUCCH_FORMATS_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pucch_param.max_pucchs_per_slot.tl.tag = NFAPI_NR_PARAM_TLV_MAX_PUCCHS_PER_SLOT_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pdsch_param.pdsch_mapping_type.tl.tag = NFAPI_NR_PARAM_TLV_PDSCH_MAPPING_TYPE_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pdsch_param.pdsch_dmrs_additional_pos.tl.tag = NFAPI_NR_PARAM_TLV_PDSCH_DMRS_ADDITIONAL_POS_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pdsch_param.pdsch_allocation_types.tl.tag = NFAPI_NR_PARAM_TLV_PDSCH_ALLOCATION_TYPES_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pdsch_param.pdsch_vrb_to_prb_mapping.tl.tag = NFAPI_NR_PARAM_TLV_PDSCH_VRB_TO_PRB_MAPPING_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pdsch_param.pdsch_cbg.tl.tag = NFAPI_NR_PARAM_TLV_PDSCH_CBG_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pdsch_param.pdsch_dmrs_config_types.tl.tag = NFAPI_NR_PARAM_TLV_PDSCH_DMRS_CONFIG_TYPES_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pdsch_param.max_number_mimo_layers_pdsch.tl.tag = NFAPI_NR_PARAM_TLV_MAX_NUMBER_MIMO_LAYERS_PDSCH_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pdsch_param.max_mu_mimo_users_dl.tl.tag = NFAPI_NR_PARAM_TLV_MAX_MU_MIMO_USERS_DL_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pdsch_param.pdsch_data_in_dmrs_symbols.tl.tag = NFAPI_NR_PARAM_TLV_PDSCH_DATA_IN_DMRS_SYMBOLS_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pdsch_param.premption_support.tl.tag = NFAPI_NR_PARAM_TLV_PREMPTION_SUPPORT_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pdsch_param.pdsch_non_slot_support.tl.tag = NFAPI_NR_PARAM_TLV_PDSCH_NON_SLOT_SUPPORT_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pusch_param.uci_mux_ulsch_in_pusch.tl.tag = NFAPI_NR_PARAM_TLV_UCI_MUX_ULSCH_IN_PUSCH_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pusch_param.uci_only_pusch.tl.tag = NFAPI_NR_PARAM_TLV_UCI_ONLY_PUSCH_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pusch_param.pusch_frequency_hopping.tl.tag = NFAPI_NR_PARAM_TLV_PUSCH_FREQUENCY_HOPPING_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pusch_param.pusch_dmrs_config_types.tl.tag = NFAPI_NR_PARAM_TLV_PUSCH_DMRS_CONFIG_TYPES_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pusch_param.pusch_dmrs_max_len.tl.tag = NFAPI_NR_PARAM_TLV_PUSCH_DMRS_MAX_LEN_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pusch_param.pusch_dmrs_additional_pos.tl.tag = NFAPI_NR_PARAM_TLV_PUSCH_DMRS_ADDITIONAL_POS_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pusch_param.pusch_cbg.tl.tag = NFAPI_NR_PARAM_TLV_PUSCH_CBG_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pusch_param.pusch_mapping_type.tl.tag = NFAPI_NR_PARAM_TLV_PUSCH_MAPPING_TYPE_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pusch_param.pusch_allocation_types.tl.tag = NFAPI_NR_PARAM_TLV_PUSCH_ALLOCATION_TYPES_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pusch_param.pusch_vrb_to_prb_mapping.tl.tag = NFAPI_NR_PARAM_TLV_PUSCH_VRB_TO_PRB_MAPPING_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pusch_param.pusch_max_ptrs_ports.tl.tag = NFAPI_NR_PARAM_TLV_PUSCH_MAX_PTRS_PORTS_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pusch_param.max_pduschs_tbs_per_slot.tl.tag = NFAPI_NR_PARAM_TLV_MAX_PDUSCHS_TBS_PER_SLOT_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pusch_param.max_number_mimo_layers_non_cb_pusch.tl.tag = NFAPI_NR_PARAM_TLV_MAX_NUMBER_MIMO_LAYERS_NON_CB_PUSCH_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pusch_param.supported_modulation_order_ul.tl.tag = NFAPI_NR_PARAM_TLV_SUPPORTED_MODULATION_ORDER_UL_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pusch_param.max_mu_mimo_users_ul.tl.tag = NFAPI_NR_PARAM_TLV_MAX_MU_MIMO_USERS_UL_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pusch_param.dfts_ofdm_support.tl.tag = NFAPI_NR_PARAM_TLV_DFTS_OFDM_SUPPORT_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.pusch_param.pusch_aggregation_factor.tl.tag = NFAPI_NR_PARAM_TLV_PUSCH_AGGREGATION_FACTOR_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.prach_param.prach_long_formats.tl.tag = NFAPI_NR_PARAM_TLV_PRACH_LONG_FORMATS_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.prach_param.prach_short_formats.tl.tag = NFAPI_NR_PARAM_TLV_PRACH_SHORT_FORMATS_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.prach_param.prach_restricted_sets.tl.tag = NFAPI_NR_PARAM_TLV_PRACH_RESTRICTED_SETS_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.prach_param.max_prach_fd_occasions_in_a_slot.tl.tag = NFAPI_NR_PARAM_TLV_MAX_PRACH_FD_OCCASIONS_IN_A_SLOT_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.measurement_param.rssi_measurement_support.tl.tag = NFAPI_NR_PARAM_TLV_RSSI_MEASUREMENT_SUPPORT_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.nfapi_config.p7_vnf_address_ipv4.tl.tag = NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.nfapi_config.p7_vnf_address_ipv6.tl.tag = NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.nfapi_config.p7_vnf_port.tl.tag = NFAPI_NR_NFAPI_P7_VNF_PORT_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.nfapi_config.p7_pnf_address_ipv4.tl.tag = NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV4_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.nfapi_config.p7_pnf_address_ipv6.tl.tag = NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV6_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.nfapi_config.p7_pnf_port.tl.tag = NFAPI_NR_NFAPI_P7_PNF_PORT_TAG;
+ nfapi_resp.num_tlv++;
+/*
+ nfapi_resp.nfapi_config.dl_ue_per_sf.tl.tag = NFAPI_NR_NFAPI_DOWNLINK_UES_PER_SUBFRAME_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.nfapi_config.ul_ue_per_sf.tl.tag = NFAPI_NR_NFAPI_UPLINK_UES_PER_SUBFRAME_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.nfapi_config.rf_bands.tl.tag = NFAPI_NR_NFAPI_RF_BANDS_TAG;
+ nfapi_resp.num_tlv++;
+ nfapi_resp.nfapi_config.max_transmit_power.tl.tag = NFAPI_NR_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG;
+ nfapi_resp.num_tlv++;
+*/
+ nfapi_resp.nfapi_config.timing_window.tl.tag = NFAPI_NR_NFAPI_TIMING_WINDOW_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.nfapi_config.timing_info_mode.tl.tag = NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG;
+ nfapi_resp.num_tlv++;
+
+ nfapi_resp.nfapi_config.timing_info_period.tl.tag = NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG;
+ nfapi_resp.num_tlv++;
+ }
+
+ nfapi_resp.nfapi_config.p7_pnf_port.value = 32123; //pnf->phys[0].local_port; DJP - hard code alert!!!! FIXME TODO
+ nfapi_resp.num_tlv++;
+ pnf_p7_sockaddr.sin_addr.s_addr = inet_addr(pnf->phys[0].local_addr);
+
+ memcpy(nfapi_resp.nfapi_config.p7_pnf_address_ipv4.address, &pnf_p7_sockaddr.sin_addr.s_addr, 4);
+ nfapi_resp.num_tlv++;
+ // P7 PNF Port
+ printf("TAG value :%d",nfapi_resp.cell_param.phy_state.tl.tag);
+ nfapi_nr_pnf_param_resp(config, &nfapi_resp);
+
+ printf("[PNF] Sent NFAPI_PNF_PARAM_RESPONSE phy_id:%d number_of_tlvs:%u\n", req->header.phy_id, nfapi_resp.num_tlv);
+ printf("[PNF] param request .. exit\n");
+ return 0;
+}
+
+int config_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi_config_request_t *req)
+{
printf("[PNF] Received NFAPI_CONFIG_REQ phy_id:%d\n", req->header.phy_id);
pnf_info *pnf = (pnf_info *)(config->user_data);
uint8_t num_tlv = 0;
@@ -657,8 +1015,7 @@ int config_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfap
phy_config_request(&phy_config);
dump_frame_parms(fp);
}
-
- phy_info->remote_port = req->nfapi_config.p7_vnf_port.value;
+ phy_info->remote_port = req->nfapi_config.p7_vnf_port.value;
struct sockaddr_in vnf_p7_sockaddr;
memcpy(&vnf_p7_sockaddr.sin_addr.s_addr, &(req->nfapi_config.p7_vnf_address_ipv4.address[0]), 4);
phy_info->remote_addr = inet_ntoa(vnf_p7_sockaddr.sin_addr);
@@ -678,6 +1035,100 @@ int config_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfap
return 0;
}
+int nr_config_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi_nr_config_request_scf_t *req)
+{
+ printf("[PNF] Received NFAPI_CONFIG_REQ phy_id:%d\n", req->header.phy_id);
+ pnf_info *pnf = (pnf_info *)(config->user_data);
+ uint8_t num_tlv = 0;
+ //struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0];
+ // In the case of nfapi_mode = 3 (UE = PNF) we should not have dependency on any eNB var. So we aim
+ // to keep only the necessary just to keep the nfapi FSM rolling by sending a dummy response.
+ NR_DL_FRAME_PARMS *fp;
+
+ if (NFAPI_MODE!=NFAPI_UE_STUB_PNF) {
+ struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
+ fp = &gNB->frame_parms;
+ } else {
+ fp = (NR_DL_FRAME_PARMS *) malloc(sizeof(NR_DL_FRAME_PARMS));
+ }
+
+ phy_info *phy_info = pnf->phys;
+
+ printf("\nTiming window tag: %d\n",NFAPI_NR_NFAPI_TIMING_WINDOW_TAG);
+ if(req->nfapi_config.timing_window.tl.tag == NFAPI_NR_NFAPI_TIMING_WINDOW_TAG) {
+ phy_info->timing_window = req->nfapi_config.timing_window.value;
+ printf("Phy_info:Timing window:%u NFAPI_CONFIG:timing_window:%u\n", phy_info->timing_window, req->nfapi_config.timing_window.value);
+ num_tlv++;
+ }
+
+ if(req->nfapi_config.timing_info_mode.tl.tag == NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG) {
+ printf("timing info mode:%d\n", req->nfapi_config.timing_info_mode.value);
+ phy_info->timing_info_mode = req->nfapi_config.timing_info_mode.value;
+ num_tlv++;
+ } else {
+ phy_info->timing_info_mode = 0;
+ printf("NO timing info mode provided\n");
+ }
+ //TODO: Read the P7 message offset values
+ if(req->nfapi_config.timing_info_period.tl.tag == NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG) {
+ printf("timing info period provided value:%d\n", req->nfapi_config.timing_info_period.value);
+ phy_info->timing_info_period = req->nfapi_config.timing_info_period.value;
+ num_tlv++;
+ } else {
+ phy_info->timing_info_period = 0;
+ }
+
+ if(req->carrier_config.dl_bandwidth.tl.tag == NFAPI_NR_CONFIG_DL_BANDWIDTH_TAG) {
+ phy_info->dl_channel_bw_support = req->carrier_config.dl_bandwidth.value; //rf_config.dl_channel_bandwidth.value;
+ fp->N_RB_DL = req->carrier_config.dl_bandwidth.value; //rf_config.dl_channel_bandwidth.value;
+ num_tlv++;
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() NFAPI_NR_CONFIG_DL_BANDWIDTH_TAG N_RB_DL:%u\n", __FUNCTION__, fp->N_RB_DL);
+ } else {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() Missing NFAPI_NR_CONFIG_DL_BANDWIDTH_TAG\n", __FUNCTION__);
+ }
+
+ if(req->carrier_config.uplink_bandwidth.tl.tag == NFAPI_NR_CONFIG_UPLINK_BANDWIDTH_TAG) {
+ phy_info->ul_channel_bw_support = req->carrier_config.uplink_bandwidth.value; //req->rf_config.ul_channel_bandwidth.value;
+ fp->N_RB_UL = req->carrier_config.uplink_bandwidth.value; //req->rf_config.ul_channel_bandwidth.value;
+ num_tlv++;
+ }
+
+ if (req->cell_config.phy_cell_id.tl.tag == NFAPI_NR_CONFIG_PHY_CELL_ID_TAG) {
+ fp->Nid_cell = req->cell_config.phy_cell_id.value; //sch_config.physical_cell_id.value;
+ fp->nushift = fp->Nid_cell%6;
+ num_tlv++;
+ }
+
+ if(NFAPI_MODE!=NFAPI_UE_STUB_PNF) {
+ printf("[PNF] CONFIG_REQUEST[num_tlv:%d] TLVs processed:%d\n", req->num_tlv, num_tlv);
+ printf("[PNF] Simulating PHY CONFIG - DJP\n");
+ NR_PHY_Config_t nr_phy_config;
+ nr_phy_config.Mod_id = 0;
+ nr_phy_config.CC_id=0;
+ nr_phy_config.cfg = req;
+ nr_phy_config_request(&nr_phy_config);
+ nr_dump_frame_parms(fp);
+ }
+ phy_info->remote_port = req->nfapi_config.p7_vnf_port.value;
+ struct sockaddr_in vnf_p7_sockaddr;
+ memcpy(&vnf_p7_sockaddr.sin_addr.s_addr, &(req->nfapi_config.p7_vnf_address_ipv4.address[0]), 4);
+ phy_info->remote_addr = inet_ntoa(vnf_p7_sockaddr.sin_addr);
+ printf("[PNF] %d vnf p7 %s:%d timing %d %d %d\n", phy_info->id, phy_info->remote_addr, phy_info->remote_port,
+ phy_info->timing_window, phy_info->timing_info_mode, phy_info->timing_info_period);
+ nfapi_nr_config_response_scf_t nfapi_resp;
+ memset(&nfapi_resp, 0, sizeof(nfapi_resp));
+ nfapi_resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE;
+ nfapi_resp.header.phy_id = phy_info->id;
+ nfapi_resp.error_code = 0; // DJP - some value resp->error_code;
+ nfapi_nr_pnf_config_resp(config, &nfapi_resp);
+ printf("[PNF] Sent NFAPI_PNF_CONFIG_RESPONSE phy_id:%d\n", phy_info->id);
+
+ if(NFAPI_MODE==NFAPI_UE_STUB_PNF)
+ free(fp);
+
+ return 0;
+}
+
nfapi_p7_message_header_t *pnf_phy_allocate_p7_vendor_ext(uint16_t message_id, uint16_t *msg_size) {
if(message_id == P7_VENDOR_EXT_REQ) {
(*msg_size) = sizeof(vendor_ext_p7_req);
@@ -691,6 +1142,33 @@ void pnf_phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t *header) {
free(header);
}
+
+int pnf_phy_ul_dci_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_nr_ul_dci_request_t *req) {
+
+ // LOG_D(PHY,"[PNF] HI_DCI0_REQUEST SFN/SF:%05d dci:%d hi:%d\n", NFAPI_SFNSF2DEC(req->sfn_sf), req->hi_dci0_request_body.number_of_dci, req->hi_dci0_request_body.number_of_hi);
+
+ //phy_info* phy = (phy_info*)(pnf_p7->user_data);
+ struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
+ if (proc ==NULL)
+ proc = &gNB->proc.L1_proc;
+
+ for (int i=0; inumPdus; i++) {
+ //LOG_D(PHY,"[PNF] HI_DCI0_REQ sfn_sf:%d PDU[%d]\n", NFAPI_SFNSF2DEC(req->sfn_sf), i);
+ if (req->ul_dci_pdu_list[i].PDUType == 0) {
+ //LOG_D(PHY,"[PNF] HI_DCI0_REQ sfn_sf:%d PDU[%d] - NFAPI_HI_DCI0_DCI_PDU_TYPE\n", NFAPI_SFNSF2DEC(req->sfn_sf), i);
+ nfapi_nr_ul_dci_request_pdus_t *ul_dci_req_pdu = &req->ul_dci_pdu_list[i];
+ int SFN=req->SFN+2;
+ handle_nfapi_nr_ul_dci_pdu(gNB, SFN, req->Slot, ul_dci_req_pdu);
+ }
+ else {
+ LOG_E(PHY,"[PNF] UL_DCI_REQ sfn_slot:%d PDU[%d] - unknown pdu type:%d\n", NFAPI_SFNSLOT2DEC(req->SFN, req->Slot), i, req->ul_dci_pdu_list[i].PDUType);
+ }
+ }
+
+ return 0;
+}
+
+
int pnf_phy_hi_dci0_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_hi_dci0_request_t *req) {
if (req->hi_dci0_request_body.number_of_dci == 0 && req->hi_dci0_request_body.number_of_hi == 0)
LOG_D(PHY,"[PNF] HI_DCI0_REQUEST SFN/SF:%05d dci:%d hi:%d\n", NFAPI_SFNSF2DEC(req->sfn_sf), req->hi_dci0_request_body.number_of_dci, req->hi_dci0_request_body.number_of_hi);
@@ -719,6 +1197,97 @@ int pnf_phy_hi_dci0_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfa
return 0;
}
+
+int pnf_phy_dl_tti_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_nr_dl_tti_request_t *req) {
+ if (RC.ru == 0) {
+ return -1;
+ }
+
+ if (RC.gNB == 0) {
+ return -2;
+ }
+
+ if (RC.gNB[0] == 0) {
+ return -3;
+ }
+
+ if (sync_var != 0) {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() Main system not up - is this a dummy subframe?\n", __FUNCTION__);
+ return -4;
+ }
+
+ int sfn = req->SFN;
+ int slot = req->Slot;
+
+ struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
+ if (proc==NULL)
+ 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);
+
+ for (int i=0; idl_tti_request_body.nPDUs; i++) {
+ // TODO: enable after adding gNB PDCCH:
+ // 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);
+
+ if (dl_tti_pdu_list[i].PDUType == NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE) {
+ nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu=&dl_tti_pdu_list[i];
+ memcpy(dl_tti_pdu,&dl_tti_pdu_list[i],sizeof(nfapi_nr_dl_tti_request_pdu_t));
+ int SFN=sfn+2;
+ handle_nfapi_nr_pdcch_pdu(gNB, SFN, slot, &dl_tti_pdu->pdcch_pdu);
+ //dl_tti_pdu_list[i].pdcch_pdu.pdcch_pdu_rel15.numDlDci++; // ?
+ // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() pdcch_vars->num_dci:%d\n", __FUNCTION__, pdcch_vars->num_dci);
+ } else if (dl_tti_pdu_list[i].PDUType == NFAPI_NR_DL_TTI_SSB_PDU_TYPE) {
+ //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(gNB, sfn, slot, &dl_tti_pdu_list[i]);
+ gNB->pbch_configured=1;
+ //} else {
+ // NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() BCH NULL TX PDU SFN/SF:%d PDU_INDEX:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), pdu_index);
+ //}
+ } 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_tx_data_request_t *tx_data = tx_data_request[sfn][slot][rel15_pdu->pduIndex];
+ nfapi_nr_pdu_t *tx_data = tx_data_request[sfn][slot][0];
+
+ if (tx_data != NULL) {
+ int UE_id = find_nr_dlsch(rel15_pdu->rnti,gNB,SEARCH_EXIST_OR_FREE);
+ AssertFatal(UE_id!=-1,"no free or exiting dlsch_context\n");
+ AssertFatal(UE_id= %d(NUMBER_OF_UE_MAX)\n",UE_id,NUMBER_OF_UE_MAX);
+ NR_gNB_DLSCH_t *dlsch0 = gNB->dlsch[UE_id][0];
+ int harq_pid = dlsch0->harq_ids[sfn%2][slot];
+
+ if(harq_pid >= dlsch0->Mdlharq) {
+ LOG_E(PHY,"pnf_phy_dl_config_req illegal harq_pid %d\n", harq_pid);
+ return(-1);
+ }
+ //uint8_t *dlsch_sdu = (uint8_t *)tx_data->TLVs[0].value.direct;
+ uint8_t *dlsch_sdu = nr_tx_pdus[UE_id][harq_pid];
+ memcpy(dlsch_sdu, tx_data->TLVs[0].value.direct,tx_data->PDU_length);//TODO: Check if required
+ //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() DLSCH:pdu_index:%d handle_nfapi_dlsch_pdu(eNB, proc_rxtx, dlsch_pdu, transport_blocks:%d sdu:%p) eNB->pdcch_vars[proc->subframe_tx & 1].num_pdcch_symbols:%d\n", __FUNCTION__, rel8_pdu->pdu_index, rel8_pdu->transport_blocks, dlsch_sdu, eNB->pdcch_vars[proc->subframe_tx & 1].num_pdcch_symbols);
+ handle_nr_nfapi_pdsch_pdu(gNB, sfn, slot,pdsch_pdu, dlsch_sdu);
+ } else {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() DLSCH NULL TX PDU SFN/SF:%d PDU_INDEX:%d\n", __FUNCTION__, NFAPI_SFNSLOT2DEC(sfn,slot), rel15_pdu->pduIndex); }
+ } else {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() UNKNOWN:%d\n", __FUNCTION__, dl_tti_pdu_list[i].PDUType);
+ }
+ }
+
+ if(req->vendor_extension)
+ free(req->vendor_extension);
+
+ return 0;
+}
+
+
int pnf_phy_dl_config_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_dl_config_request_t *req) {
if (RC.eNB == 0) {
@@ -810,6 +1379,35 @@ int pnf_phy_dl_config_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, n
return 0;
}
+
+
+int pnf_phy_tx_data_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_nr_tx_data_request_t *req) {
+ uint16_t sfn = req->SFN;
+ uint16_t slot = req->Slot;
+
+ if (req->Number_of_PDUs == 0)
+ LOG_D(PHY,"%s() SFN/SLOT:%d%d PDUs:%d\n", __FUNCTION__, sfn, slot, req->Number_of_PDUs);
+
+ //if (req->pdu_list[0].TLVs->tag == NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST) {
+ for (int i=0; iNumber_of_PDUs; i++) {
+ // LOG_D(PHY,"%s() SFN/SF:%d%d number_of_pdus:%d [PDU:%d] pdu_length:%d pdu_index:%d num_segments:%d\n",
+ // __FUNCTION__,
+ // sfn, sf,
+ // req->tx_request_body.number_of_pdus,
+ // i,
+ // req->tx_request_body.tx_pdu_list[i].pdu_length,
+ // req->tx_request_body.tx_pdu_list[i].pdu_index,
+ // req->tx_request_body.tx_pdu_list[i].num_segments
+ // );
+ // tx_request_pdu[sfn][sf][i] = &req->tx_request_body.tx_pdu_list[i];
+ tx_data_request[sfn][slot][i] = &req->pdu_list[i];
+ }
+ //}
+
+ return 0;
+}
+
+
int pnf_phy_tx_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_tx_request_t *req) {
uint16_t sfn = NFAPI_SFNSF2SFN(req->sfn_sf);
uint16_t sf = NFAPI_SFNSF2SF(req->sfn_sf);
@@ -835,6 +1433,82 @@ int pnf_phy_tx_req(nfapi_pnf_p7_config_t *pnf_p7, nfapi_tx_request_t *req) {
return 0;
}
+
+
+int pnf_phy_ul_tti_req(gNB_L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_nr_ul_tti_request_t *req) {
+ // if (0)LOG_D(PHY,"[PNF] UL_CONFIG_REQ %s() sfn_sf:%d pdu:%d rach_prach_frequency_resources:%d srs_present:%u\n",
+ // __FUNCTION__,
+ // NFAPI_SFNSF2DEC(req->sfn_sf),
+ // req->ul_config_request_body.number_of_pdus,
+ // req->ul_config_request_body.rach_prach_frequency_resources,
+ // req->ul_config_request_body.srs_present
+ // );
+
+ if (RC.ru == 0) {
+ return -1;
+ }
+
+ if (RC.gNB == 0) {
+ return -2;
+ }
+
+ if (RC.gNB[0] == 0) {
+ return -3;
+ }
+
+ if (sync_var != 0) {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() Main system not up - is this a dummy slot?\n", __FUNCTION__);
+ return -4;
+ }
+ uint16_t curr_sfn = req->SFN;
+ uint16_t curr_slot = req->Slot;
+ struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
+
+ if (proc==NULL)
+ proc = &gNB->proc.L1_proc;
+
+ nfapi_nr_ul_tti_request_number_of_pdus_t *ul_tti_pdu_list = req->pdus_list;
+
+ for (int i=0; i< req->n_pdus; i++) {
+ 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);
+ nr_fill_ulsch(gNB,curr_sfn, curr_slot, &ul_tti_pdu_list[i].pusch_pdu);
+ break;
+ case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE:
+ //LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PUCCH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot);
+ nr_fill_pucch(gNB,curr_sfn, curr_slot, &ul_tti_pdu_list[i].pucch_pdu);
+ break;
+ case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE:
+ //LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PRACH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot);
+ nr_fill_prach(gNB, curr_sfn, curr_slot, &ul_tti_pdu_list[i].prach_pdu);
+ if (gNB->RU_list[0]->if_south == LOCAL_RF) nr_fill_prach_ru(gNB->RU_list[0], curr_sfn, curr_slot, &ul_tti_pdu_list[i].prach_pdu);
+ break;
+ default:
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() PDU:%i UNKNOWN type :%d\n", __FUNCTION__, i, ul_tti_pdu_list[i].pdu_type);
+ break;
+
+ }
+ // //LOG_D(PHY, "%s() sfn/sf:%d PDU[%d] size:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), i, ul_config_pdu_list[i].pdu_size);
+ // if (
+ // ul_tti_pdu_list[i].pdu_type == NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE ||
+ // ul_tti_pdu_list[i].pdu_type == NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE ||
+ // ul_tti_pdu_list[i].pdu_type == NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE ||
+ // ul_tti_pdu_list[i].pdu_type == NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE
+ // ) {
+ // //LOG_D(PHY, "%s() handle_nfapi_ul_pdu() for PDU:%d\n", __FUNCTION__, i);
+ // // handle_nfapi_ul_pdu(eNB,proc,&ul_config_pdu_list[i],curr_sfn,curr_sf,req->ul_config_request_body.srs_present);
+
+ // // TODO: dont have an NR function for this, also srs_present flag not there
+
+ // } else {
+ // NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s() PDU:%i UNKNOWN type :%d\n", __FUNCTION__, i, ul_tti_pdu_list[i].pdu_type);
+ // }
+ }
+
+ return 0;
+}
+
int pnf_phy_ul_config_req(L1_rxtx_proc_t *proc, nfapi_pnf_p7_config_t *pnf_p7, nfapi_ul_config_request_t *req) {
if (0)LOG_D(PHY,"[PNF] UL_CONFIG_REQ %s() sfn_sf:%d pdu:%d rach_prach_frequency_resources:%d srs_present:%u\n",
__FUNCTION__,
@@ -983,6 +1657,7 @@ int pnf_sim_pack_vendor_extention_tlv(void *ve, uint8_t **ppWritePackedMsg, uint
//printf("%s\n", __FUNCTION__);
(void)ve;
(void)ppWritePackedMsg;
+
return -1;
}
@@ -1000,7 +1675,7 @@ int start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi
p7_config->phy_id = phy->phy_id;
p7_config->remote_p7_port = phy_info->remote_port;
p7_config->remote_p7_addr = phy_info->remote_addr;
- p7_config->local_p7_port = 32123; // DJP - good grief cannot seem to get the right answer phy_info->local_port;
+ p7_config->local_p7_port = 32123;//phy_info->local_port;//50010; // DJP - good grief cannot seem to get the right answer phy_info->local_port;
//DJP p7_config->local_p7_addr = (char*)phy_info->local_addr.c_str();
p7_config->local_p7_addr = phy_info->local_addr;
printf("[PNF] P7 remote:%s:%d local:%s:%d\n", p7_config->remote_p7_addr, p7_config->remote_p7_port, p7_config->local_p7_addr, p7_config->local_p7_port);
@@ -1111,6 +1786,142 @@ int start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi
return 0;
}
+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();
+ p7_config->phy_id = phy->phy_id;
+ p7_config->remote_p7_port = phy_info->remote_port;
+ p7_config->remote_p7_addr = phy_info->remote_addr;
+ // TODO: remove this hardcoded port
+ p7_config->local_p7_port = 32123; // DJP - good grief cannot seem to get the right answer phy_info->local_port;
+ //DJP p7_config->local_p7_addr = (char*)phy_info->local_addr.c_str();
+ p7_config->local_p7_addr = phy_info->local_addr;
+ printf("[PNF] P7 remote:%s:%d local:%s:%d\n", p7_config->remote_p7_addr, p7_config->remote_p7_port, p7_config->local_p7_addr, p7_config->local_p7_port);
+ p7_config->user_data = phy_info;
+ p7_config->malloc = &pnf_allocate;
+ p7_config->free = &pnf_deallocate;
+ p7_config->codec_config.allocate = &pnf_allocate;
+ p7_config->codec_config.deallocate = &pnf_deallocate;
+ p7_config->trace = &pnf_nfapi_trace;
+ phy->user_data = p7_config;
+ p7_config->subframe_buffer_size = phy_info->timing_window;
+ p7_config->slot_buffer_size = phy_info->timing_window; // TODO: check if correct for NR
+ printf("subframe_buffer_size configured using phy_info->timing_window:%d\n", phy_info->timing_window);
+
+ if(phy_info->timing_info_mode & 0x1) {
+ p7_config->timing_info_mode_periodic = 1;
+ p7_config->timing_info_period = phy_info->timing_info_period;
+ }
+
+ if(phy_info->timing_info_mode & 0x2) {
+ p7_config->timing_info_mode_aperiodic = 1;
+ }
+
+ // NR
+ p7_config->dl_tti_req_fn = &pnf_phy_dl_tti_req;
+ p7_config->ul_tti_req_fn = &pnf_phy_ul_tti_req;
+ p7_config->ul_dci_req_fn = &pnf_phy_ul_dci_req;
+ p7_config->tx_data_req_fn = &pnf_phy_tx_data_req;
+
+ // LTE
+ p7_config->dl_config_req = &pnf_phy_dl_config_req;
+ p7_config->ul_config_req = &pnf_phy_ul_config_req;
+ p7_config->hi_dci0_req = &pnf_phy_hi_dci0_req;
+ 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;
+ } else {
+ p7_config->dl_config_req = &pnf_phy_dl_config_req;
+ p7_config->ul_config_req = &pnf_phy_ul_config_req;
+ p7_config->hi_dci0_req = &pnf_phy_hi_dci0_req;
+ p7_config->tx_req = &pnf_phy_tx_req;
+ }
+
+ p7_config->lbt_dl_config_req = &pnf_phy_lbt_dl_config_req;
+ memset(&dummy_dl_config_req, 0, sizeof(dummy_dl_config_req));
+ dummy_dl_config_req.dl_config_request_body.tl.tag=NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
+ dummy_dl_config_req.dl_config_request_body.number_pdcch_ofdm_symbols=1;
+ dummy_dl_config_req.dl_config_request_body.number_dci=0;
+ dummy_dl_config_req.dl_config_request_body.number_pdu=0;
+ dummy_dl_config_req.dl_config_request_body.number_pdsch_rnti=0;
+ dummy_dl_config_req.dl_config_request_body.transmission_power_pcfich=6000;
+ dummy_dl_config_req.dl_config_request_body.dl_config_pdu_list=0;
+ memset(&dummy_tx_req, 0, sizeof(dummy_tx_req));
+ dummy_tx_req.tx_request_body.number_of_pdus=0;
+ dummy_tx_req.tx_request_body.tl.tag=NFAPI_TX_REQUEST_BODY_TAG;
+ dummy_subframe.dl_config_req = &dummy_dl_config_req;
+ dummy_subframe.tx_req = 0;//&dummy_tx_req;
+ dummy_subframe.ul_config_req=0;
+ dummy_subframe.hi_dci0_req=0;
+ dummy_subframe.lbt_dl_config_req=0;
+ p7_config->dummy_subframe = dummy_subframe;
+ p7_config->vendor_ext = &pnf_phy_vendor_ext;
+ p7_config->allocate_p7_vendor_ext = &pnf_phy_allocate_p7_vendor_ext;
+ p7_config->deallocate_p7_vendor_ext = &pnf_phy_deallocate_p7_vendor_ext;
+ p7_config->codec_config.unpack_p7_vendor_extension = &pnf_phy_unpack_p7_vendor_extension;
+ p7_config->codec_config.pack_p7_vendor_extension = &pnf_phy_pack_p7_vendor_extension;
+ p7_config->codec_config.unpack_vendor_extension_tlv = &pnf_phy_unpack_vendor_extension_tlv;
+ p7_config->codec_config.pack_vendor_extension_tlv = &pnf_phy_pack_vendor_extention_tlv;
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] Creating P7 thread %s\n", __FUNCTION__);
+ pthread_t p7_thread;
+ pthread_create(&p7_thread, NULL, &pnf_nr_p7_thread_start, p7_config);
+ //((pnf_phy_user_data_t*)(phy_info->fapi->user_data))->p7_config = p7_config;
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] Calling l1_north_init_eNB() %s\n", __FUNCTION__);
+ l1_north_init_gNB();
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] DJP - HACK - Set p7_config global ready for subframe ind%s\n", __FUNCTION__);
+ p7_config_g = p7_config;
+
+ // Need to wait for main thread to create RU structures
+ while(config_sync_var<0) {
+ usleep(5000000);
+ printf("[PNF] waiting for OAI to be configured (eNB/RU)\n");
+ }
+
+ printf("[PNF] OAI eNB/RU configured\n");
+ //printf("[PNF] About to call phy_init_RU() for RC.ru[0]:%p\n", RC.ru[0]);
+ //phy_init_RU(RC.ru[0]);
+ printf("[PNF] About to call init_eNB_afterRU()\n");
+
+ if (NFAPI_MODE!=NFAPI_UE_STUB_PNF) {
+ init_eNB_afterRU();
+ }
+
+ // Signal to main thread that it can carry on - otherwise RU will startup too quickly and it is not initialised
+ {
+ pthread_mutex_lock(&nfapi_sync_mutex);
+ nfapi_sync_var=0;
+ pthread_cond_broadcast(&nfapi_sync_cond);
+ pthread_mutex_unlock(&nfapi_sync_mutex);
+ }
+
+ while(sync_var<0) {
+ usleep(5000000);
+ printf("[PNF] waiting for OAI to be started\n");
+ }
+
+ printf("[PNF] Sending PNF_START_RESP\n");
+ nfapi_nr_send_pnf_start_resp(config, p7_config->phy_id);
+ printf("[PNF] Sending first P7 slot indication\n");
+#if 1
+ nfapi_pnf_p7_slot_ind(p7_config, p7_config->phy_id, 0, 0);
+ printf("[PNF] Sent first P7 slot ind\n");
+#else
+ nfapi_pnf_p7_subframe_ind(p7_config, p7_config->phy_id, 0); // DJP - SFN_SF set to zero - correct???
+ printf("[PNF] Sent first P7 subframe ind\n");
+#endif
+
+
+ return 0;
+}
+
int measurement_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi_measurement_request_t *req) {
nfapi_measurement_response_t resp;
memset(&resp, 0, sizeof(resp));
@@ -1356,7 +2167,6 @@ int pnf_sim_unpack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t *header,
}
/*------------------------------------------------------------------------------*/
-
void *pnf_start_thread(void *ptr) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] IN PNF NFAPI start thread %s\n", __FUNCTION__);
nfapi_pnf_config_t *config = (nfapi_pnf_config_t *)ptr;
@@ -1367,18 +2177,76 @@ void *pnf_start_thread(void *ptr) {
return (void *)0;
}
+void *pnf_nr_start_thread(void *ptr) {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] IN PNF NFAPI start thread %s\n", __FUNCTION__);
+ nfapi_pnf_config_t *config = (nfapi_pnf_config_t *)ptr;
+ struct sched_param sp;
+ sp.sched_priority = 20;
+ pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp);
+ nfapi_nr_pnf_start(config);
+ return (void *)0;
+}
+
+void configure_nr_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__);
+ nfapi_setmode(NFAPI_MODE_PNF); // PNF!
+
+ nfapi_pnf_config_t *config = nfapi_pnf_config_create();
+ config->vnf_ip_addr = vnf_ip_addr;
+ config->vnf_p5_port = vnf_p5_port;
+ pnf.phys[0].udp.enabled = 1;
+ pnf.phys[0].udp.rx_port = 32123;//pnf_p7_port;
+ pnf.phys[0].udp.tx_port = vnf_p7_port;
+ strcpy(pnf.phys[0].udp.tx_addr, vnf_ip_addr);
+ strcpy(pnf.phys[0].local_addr, pnf_ip_addr);
+ printf("%s() VNF:%s:%d PNF_PHY[addr:%s UDP:tx_addr:%s:%d rx:%d]\n",
+ __FUNCTION__,config->vnf_ip_addr, config->vnf_p5_port,
+ pnf.phys[0].local_addr,
+ pnf.phys[0].udp.tx_addr, pnf.phys[0].udp.tx_port,
+ pnf.phys[0].udp.rx_port);
+ config->cell_search_req = &cell_search_request;
+
+
+ //config->pnf_nr_param_req = &pnf_nr_param_request;
+ config->pnf_nr_param_req = &pnf_nr_param_request;
+ config->pnf_nr_config_req = &pnf_nr_config_request;
+ config->pnf_nr_start_req = &pnf_nr_start_request;
+ config->pnf_stop_req = &pnf_stop_request;
+ config->nr_param_req = &nr_param_request;
+ config->nr_config_req = &nr_config_request;
+ config->nr_start_req = &nr_start_request;
+ config->measurement_req = &measurement_request;
+ config->rssi_req = &rssi_request;
+ config->broadcast_detect_req = &broadcast_detect_request;
+ config->system_information_schedule_req = &system_information_schedule_request;
+ config->system_information_req = &system_information_request;
+ config->nmm_stop_req = &nmm_stop_request;
+ config->vendor_ext = &vendor_ext;
+ config->trace = &pnf_nfapi_trace;
+ config->user_data = &pnf;
+ // To allow custom vendor extentions to be added to nfapi
+ config->codec_config.unpack_vendor_extension_tlv = &pnf_sim_unpack_vendor_extension_tlv;
+ config->codec_config.pack_vendor_extension_tlv = &pnf_sim_pack_vendor_extention_tlv;
+ config->allocate_p4_p5_vendor_ext = &pnf_sim_allocate_p4_p5_vendor_ext;
+ config->deallocate_p4_p5_vendor_ext = &pnf_sim_deallocate_p4_p5_vendor_ext;
+ config->codec_config.unpack_p4_p5_vendor_extension = &pnf_sim_unpack_p4_p5_vendor_extension;
+ config->codec_config.pack_p4_p5_vendor_extension = &pnf_sim_pack_p4_p5_vendor_extension;
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] Creating PNF NFAPI start thread %s\n", __FUNCTION__);
+ pthread_create(&pnf_start_pthread, NULL, &pnf_nr_start_thread, config);
+ pthread_setname_np(pnf_start_pthread, "NFAPI_PNF");
+}
+
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) {
nfapi_setmode(NFAPI_MODE_PNF); // PNF!
}
-
nfapi_pnf_config_t *config = nfapi_pnf_config_create();
config->vnf_ip_addr = vnf_ip_addr;
config->vnf_p5_port = vnf_p5_port;
pnf.phys[0].udp.enabled = 1;
- pnf.phys[0].udp.rx_port = pnf_p7_port;
+ pnf.phys[0].udp.rx_port = 32123;//pnf_p7_port;
pnf.phys[0].udp.tx_port = vnf_p7_port;
strcpy(pnf.phys[0].udp.tx_addr, vnf_ip_addr);
strcpy(pnf.phys[0].local_addr, pnf_ip_addr);
@@ -1422,7 +2290,7 @@ void oai_subframe_ind(uint16_t sfn, uint16_t sf) {
//TODO FIXME - HACK - DJP - using a global to bodge it in
if (p7_config_g != NULL && sync_var==0) {
- uint16_t sfn_sf_tx = sfn<<4 | sf;
+ uint16_t sfn_sf_tx = sfn<<4 | sf;
if ((sfn % 100 == 0) && sf==0) {
struct timespec ts;
@@ -1441,6 +2309,52 @@ void oai_subframe_ind(uint16_t sfn, uint16_t sf) {
}
}
+
+long shift_ns,prev_ts_nsec,shift_us;
+void oai_slot_ind(uint16_t sfn, uint16_t slot) {
+
+ //slow down PNF
+
+ LOG_D(PHY,"%s(sfn:%d, slot:%d)\n", __FUNCTION__, sfn, slot);
+ struct timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+
+ // if (!(sfn == 0 && slot == 0) && ts.tv_nsec > prev_ts_nsec){
+ // shift_ns = ts.tv_nsec - prev_ts_nsec;
+ // shift_us = shift_ns/1000;
+ // printf("previous: %d, current: %d, shift: %d", prev_ts_nsec, ts.tv_nsec, shift_us);
+ // if(500-shift_us > 0)
+ // usleep(500-shift_us);
+ // // usleep(50);
+ // }
+ prev_ts_nsec = ts.tv_nsec;
+
+
+//NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] %s %d.%d (sfn:%u slot:%u) SFN/SLOT(TX):%u\n", __FUNCTION__, ts.tv_sec, ts.tv_nsec, sfn, slot, NFAPI_SFNSLOT2DEC(sfn, slot));
+ //TODO FIXME - HACK - DJP - using a global to bodge it in
+ if (p7_config_g != NULL && sync_var==0) {
+ // DONE: changed for NR x x x x x x x x x x x x x x - - - - - - : x (Frame), - (Slot) (max_numer =2)
+ uint16_t sfn_slot_tx = sfn<<6 | slot;
+ // if ((sfn % 100 == 0) && slot==0) { // DOUBT: Why 100?
+ // struct timespec ts;
+ // clock_gettime(CLOCK_MONOTONIC, &ts);
+ // NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] %s %d.%d (sfn:%u slot:%u) SFN/SLOT(TX):%u\n", __FUNCTION__, ts.tv_sec, ts.tv_nsec, sfn, slot, NFAPI_SFNSLOT2DEC(sfn, slot));
+ // }
+
+ //TODO: send p7_config instead of p7_config_g
+ int slot_ret = nfapi_pnf_p7_slot_ind(p7_config_g, p7_config_g->phy_id, sfn, slot);
+
+ // if (subframe_ret) {
+ if (slot_ret) {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] %s(frame:%u slot:%u) SFN/SLOT(TX):%u - PROBLEM with pnf_p7_slot_ind()\n", __FUNCTION__, sfn, slot, sfn_slot_tx, NFAPI_SFNSLOT2DEC(sfn, slot));
+ // printing anything causes error: probably because there isn't enough time to accomodate a print statement
+ } else {
+ //NFAPI_TRACE(NFAPI_TRACE_INFO, "***NFAPI subframe handler finished *** \n");
+ }
+ } else {
+ }
+}
+
int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind) {
rach_ind->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
LOG_D(PHY, "%s() sfn_sf:%d preambles:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(rach_ind->sfn_sf), rach_ind->rach_indication_body.number_of_preambles);
diff --git a/nfapi/oai_integration/nfapi_pnf.h b/nfapi/oai_integration/nfapi_pnf.h
index 2c8201737c..b3ab7cbdbc 100644
--- a/nfapi/oai_integration/nfapi_pnf.h
+++ b/nfapi/oai_integration/nfapi_pnf.h
@@ -23,5 +23,8 @@
#define NFAPI_PNF_H__
int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind);
void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port);
+void configure_nr_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port);
+
void oai_subframe_ind(uint16_t sfn, uint16_t sf);
+void oai_slot_ind(uint16_t sfn, uint16_t slot);
#endif
diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c
index f76cad87f7..485f17922f 100644
--- a/nfapi/oai_integration/nfapi_vnf.c
+++ b/nfapi/oai_integration/nfapi_vnf.c
@@ -39,8 +39,12 @@
#include "nfapi_vnf.h"
#include "PHY/defs_eNB.h"
#include "PHY/LTE_TRANSPORT/transport_proto.h"
+#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
#include "common/ran_context.h"
+
+#define TEST
+
extern RAN_CONTEXT_t RC;
extern UL_RCC_IND_t UL_RCC_INFO;
@@ -189,11 +193,12 @@ int vnf_pack_vendor_extension_tlv(void *ve, uint8_t **ppWritePackedMsg, uint8_t
int vnf_unpack_vendor_extension_tlv(nfapi_tl_t *tl, uint8_t **ppReadPackedMessage, uint8_t *end, void **ve, nfapi_p4_p5_codec_config_t *codec) {
return -1;
}
-
+void install_nr_schedule_handlers(NR_IF_Module_t *if_inst);
void install_schedule_handlers(IF_Module_t *if_inst);
extern int single_thread_flag;
extern void init_eNB_afterRU(void);
extern uint16_t sf_ahead;
+extern uint16_t slot_ahead;
void oai_create_enb(void) {
int bodge_counter=0;
@@ -231,6 +236,39 @@ void oai_enb_init(void) {
init_eNB_afterRU();
}
+
+void oai_create_gnb(void) {
+ int bodge_counter=0;
+ 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;
+ gNB->single_thread_flag = 0;//single_thread_flag;
+ RC.nb_nr_CC[bodge_counter] = 1;
+
+ 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");
+ 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__);
+ usleep(50000);
+ } while(gNB->configured != 1);
+
+ printf("%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);
oai_create_enb();
@@ -241,6 +279,16 @@ int pnf_connection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) {
return 0;
}
+int pnf_nr_connection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) {
+ printf("[VNF] pnf connection indication idx:%d\n", p5_idx);
+ oai_create_gnb();
+ nfapi_nr_pnf_param_request_t req;
+ memset(&req, 0, sizeof(req));
+ req.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_REQUEST;
+ nfapi_nr_vnf_pnf_param_req(config, p5_idx, &req);
+ return 0;
+}
+
int pnf_disconnection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) {
printf("[VNF] pnf disconnection indication idx:%d\n", p5_idx);
vnf_info *vnf = (vnf_info *)(config->user_data);
@@ -251,6 +299,42 @@ int pnf_disconnection_indication_cb(nfapi_vnf_config_t *config, int p5_idx) {
return 0;
}
+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);
+ vnf_info *vnf = (vnf_info *)(config->user_data);
+ pnf_info *pnf = vnf->pnfs;
+
+ for(int i = 0; i < resp->pnf_phy.number_of_phys; ++i) {
+ 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_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);
+ phy.rfs[0] = resp->pnf_phy.phy[i].rf_config[j].rf_config_index;
+ }
+
+ pnf->phys[0] = phy;
+ }
+ nfapi_nr_pnf_config_request_t req;
+ memset(&req, 0, sizeof(req));
+ 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");
+
+ for(unsigned i = 0; i < 2; ++i) {
+ req.pnf_phy_rf_config.phy_rf_config[i].phy_id = pnf->phys[i].id;
+ req.pnf_phy_rf_config.phy_rf_config[i].phy_config_index = pnf->phys[i].index;
+ req.pnf_phy_rf_config.phy_rf_config[i].rf_config_index = pnf->phys[i].rfs[0];
+ }
+
+ nfapi_nr_vnf_pnf_config_req(config, p5_idx, &req);
+ return 0;
+}
+
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);
vnf_info *vnf = (vnf_info *)(config->user_data);
@@ -270,7 +354,6 @@ int pnf_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_param_re
pnf->phys[0] = phy;
}
-
for(int i = 0; i < resp->pnf_rf.number_of_rfs; ++i) {
rf_info rf;
memset(&rf,0,sizeof(rf));
@@ -278,7 +361,6 @@ int pnf_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_param_re
printf("[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;
memset(&req, 0, sizeof(req));
req.header.message_id = NFAPI_PNF_CONFIG_REQUEST;
@@ -296,6 +378,31 @@ int pnf_param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_param_re
return 0;
}
+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);
+
+ if(1) {
+ nfapi_nr_pnf_start_request_t req;
+ memset(&req, 0, sizeof(req));
+ req.header.phy_id = resp->header.phy_id;
+ req.header.message_id = NFAPI_PNF_START_REQUEST;
+ nfapi_nr_vnf_pnf_start_req(config, p5_idx, &req);
+ } else {
+ // Rather than send the pnf_start_request we will demonstrate
+ // sending a vendor extention message. The start request will be
+ // send when the vendor extension response is received
+ //vnf_info* vnf = (vnf_info*)(config->user_data);
+ vendor_ext_p5_req req;
+ memset(&req, 0, sizeof(req));
+ req.header.message_id = P5_VENDOR_EXT_REQ;
+ req.dummy1 = 45;
+ req.dummy2 = 1977;
+ nfapi_vnf_vendor_extension(config, p5_idx, &req.header);
+ }
+
+ return 0;
+}
+
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);
@@ -321,6 +428,70 @@ int pnf_config_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_config_
return 0;
}
+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);
+ 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);
+ //int i;
+ struct timespec wait;
+ clock_gettime(CLOCK_REALTIME, &wait);
+ wait.tv_sec = 0;
+ wait.tv_nsec +=5000L;
+ //wait.tv_nsec = 0;
+ // wake up TX for subframe n+sf_ahead
+ // lock the TX mutex and make sure the thread is ready
+ if (pthread_mutex_timedlock(&L1_proc->mutex,&wait) != 0) {
+ LOG_E( PHY, "[gNB] ERROR pthread_mutex_lock for gNB RXTX thread %d (IC %d)\n", L1_proc->slot_rx&1,L1_proc->instance_cnt );
+ exit_fun( "error locking mutex_rxtx" );
+ return(-1);
+ }
+
+ {
+ static uint16_t old_slot = 0;
+ static uint16_t old_sfn = 0;
+ proc->slot_rx = old_slot;
+ proc->frame_rx = old_sfn;
+ // 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);
+ 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);
+ }
+
+ ++L1_proc->instance_cnt;
+ //LOG_D( PHY,"[VNF-subframe_ind] sfn/sf:%d:%d proc[frame_rx:%d subframe_rx:%d] L1_proc->instance_cnt_rxtx:%d \n", sfn, sf, proc->frame_rx, proc->subframe_rx, L1_proc->instance_cnt_rxtx);
+ // We have just received and processed the common part of a subframe, say n.
+ // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired
+ // transmitted timestamp of the next TX slot (first).
+ // The last (TS_rx mod samples_per_frame) was n*samples_per_tti,
+ // we want to generate subframe (n+N), so TS_tx = TX_rx+N*samples_per_tti,
+ // and proc->subframe_tx = proc->subframe_rx+sf_ahead
+ L1_proc->timestamp_tx = proc->timestamp_rx + (slot_ahead *fp->samples_per_subframe);
+ L1_proc->frame_rx = proc->frame_rx;
+ L1_proc->slot_rx = proc->slot_rx;
+ L1_proc->frame_tx = (L1_proc->slot_rx > (19-slot_ahead)) ? (L1_proc->frame_rx+1)&1023 : L1_proc->frame_rx;
+ 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);
+ // 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");
+ exit_fun( "ERROR pthread_clond_signal" );
+ return(-1);
+ }
+
+ //LOG_D(PHY,"%s() About to attempt pthread_mutex_unlock\n", __FUNCTION__);
+ pthread_mutex_unlock( &L1_proc->mutex );
+ //LOG_D(PHY,"%s() UNLOCKED pthread_mutex_unlock\n", __FUNCTION__);
+ return(0);
+}
+
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;
@@ -416,6 +587,7 @@ int phy_sync_indication(struct nfapi_vnf_p7_config *config, uint8_t sync) {
printf("[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");
pthread_mutex_lock(&nfapi_sync_mutex);
nfapi_sync_var=0;
@@ -426,6 +598,29 @@ int phy_sync_indication(struct nfapi_vnf_p7_config *config, uint8_t sync) {
return(0);
}
+
+int phy_slot_indication(struct nfapi_vnf_p7_config *config, uint16_t phy_id, uint16_t sfn, uint16_t slot) {
+ static uint8_t first_time = 1;
+
+ if (first_time) {
+ printf("[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);
+ wake_gNB_rxtx(RC.gNB[0], sfn, slot); // DONE: find NR equivalent
+ } else {
+ printf("[VNF] %s() RC.gNB:%p\n", __FUNCTION__, RC.gNB);
+
+ if (RC.gNB) printf("RC.gNB[0]->configured:%d\n", RC.gNB[0]->configured);
+ }
+
+ return 0;
+}
+
int phy_subframe_indication(struct nfapi_vnf_p7_config *config, uint16_t phy_id, uint16_t sfn_sf) {
static uint8_t first_time = 1;
@@ -937,6 +1132,14 @@ int vnf_pack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t *header, uint8_
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__);
+ 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);
+ return config;
+}
+
void *vnf_p7_start_thread(void *ptr) {
printf("%s()\n", __FUNCTION__);
pthread_setname_np(pthread_self(), "VNF_P7");
@@ -947,12 +1150,13 @@ void *vnf_p7_start_thread(void *ptr) {
void set_thread_priority(int priority);
-void *vnf_p7_thread_start(void *ptr) {
+void *vnf_nr_p7_thread_start(void *ptr) {
set_thread_priority(79);
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->subframe_indication = &phy_subframe_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;
@@ -977,11 +1181,72 @@ void *vnf_p7_thread_start(void *ptr) {
p7_vnf->config->codec_config.deallocate = &vnf_deallocate;
p7_vnf->config->allocate_p7_vendor_ext = &phy_allocate_p7_vendor_ext;
p7_vnf->config->deallocate_p7_vendor_ext = &phy_deallocate_p7_vendor_ext;
- NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI start thread %s\n", __FUNCTION__);
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI P7 start thread %s\n", __FUNCTION__);
+ pthread_create(&vnf_p7_start_pthread, NULL, &vnf_nr_p7_start_thread, p7_vnf->config);
+ return 0;
+}
+
+void *vnf_p7_thread_start(void *ptr) {
+ set_thread_priority(79);
+ 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->subframe_indication = &phy_subframe_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->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->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;
+ p7_vnf->config->codec_config.unpack_p7_vendor_extension = &phy_unpack_p7_vendor_extension;
+ p7_vnf->config->codec_config.pack_p7_vendor_extension = &phy_pack_p7_vendor_extension;
+ p7_vnf->config->codec_config.unpack_vendor_extension_tlv = &phy_unpack_vendor_extension_tlv;
+ p7_vnf->config->codec_config.pack_vendor_extension_tlv = &phy_pack_vendor_extension_tlv;
+ p7_vnf->config->codec_config.allocate = &vnf_allocate;
+ p7_vnf->config->codec_config.deallocate = &vnf_deallocate;
+ p7_vnf->config->allocate_p7_vendor_ext = &phy_allocate_p7_vendor_ext;
+ p7_vnf->config->deallocate_p7_vendor_ext = &phy_deallocate_p7_vendor_ext;
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI P7 start thread %s\n", __FUNCTION__);
pthread_create(&vnf_p7_start_pthread, NULL, &vnf_p7_start_thread, p7_vnf->config);
return 0;
}
+int pnf_nr_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_pnf_start_response_t *resp) {
+ vnf_info *vnf = (vnf_info *)(config->user_data);
+ 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);
+
+ if(p7_vnf->thread_started == 0) {
+ pthread_t vnf_p7_thread;
+ pthread_create(&vnf_p7_thread, NULL, &vnf_nr_p7_thread_start, p7_vnf);
+ p7_vnf->thread_started = 1;
+ } else {
+ // P7 thread already running.
+ }
+
+ // start all the phys in the pnf.
+ printf("[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;
+ nfapi_nr_vnf_param_req(config, p5_idx, &req);
+ return 0;
+}
+
int pnf_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_start_response_t *resp) {
vnf_info *vnf = (vnf_info *)(config->user_data);
vnf_p7_info *p7_vnf = vnf->p7_vnfs;
@@ -998,7 +1263,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_PARAM_REQUEST phy_id:%d\n", pnf->phys[0].id);
+ printf("[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;
@@ -1008,6 +1273,69 @@ int pnf_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_pnf_start_re
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);
+ 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;
+ 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,
+ 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]);
+
+ 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);
+ 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);
+ 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);
+ req->num_tlv++;
+
+ if(p7_vnf->periodic_timing_enabled || p7_vnf->aperiodic_timing_enabled) {
+ req->nfapi_config.timing_info_mode.tl.tag = NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG;
+ req->nfapi_config.timing_info_mode.value = (p7_vnf->aperiodic_timing_enabled << 1) | (p7_vnf->periodic_timing_enabled);
+ req->num_tlv++;
+
+ if(p7_vnf->periodic_timing_enabled) {
+ req->nfapi_config.timing_info_period.tl.tag = NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG;
+ req->nfapi_config.timing_info_period.value = p7_vnf->periodic_timing_period;
+ req->num_tlv++;
+ }
+ }
+//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;
+req->nfapi_config.tx_data_timing_offset.tl.tag = NFAPI_NR_NFAPI_TX_DATA_TIMING_OFFSET;
+
+ vendor_ext_tlv_2 ve2;
+ memset(&ve2, 0, sizeof(ve2));
+ ve2.tl.tag = VENDOR_EXT_TLV_2_TAG;
+ ve2.dummy = 2016;
+ req->vendor_extension = &ve2.tl;
+ nfapi_nr_vnf_config_req(config, p5_idx, req);
+ printf("[VNF] Sent NFAPI_VNF_CONFIG_REQ num_tlv:%u\n",req->num_tlv);
+ return 0;
+}
+
+
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);
vnf_info *vnf = (vnf_info *)(config->user_data);
@@ -1016,7 +1344,7 @@ int param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_param_response_t
phy_info *phy = pnf->phys;
struct sockaddr_in pnf_p7_sockaddr;
nfapi_config_request_t *req = &RC.mac[0]->config[0];
- phy->remote_port = 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
@@ -1062,6 +1390,19 @@ int param_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_param_response_t
return 0;
}
+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");
+ 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);
@@ -1085,6 +1426,17 @@ int start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_start_response_t
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);
+ 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);
+ return 0;
+}
+
int vendor_ext_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_p4_p5_message_header_t *msg) {
printf("[VNF] %s\n", __FUNCTION__);
@@ -1129,6 +1481,13 @@ void vnf_deallocate_p4_p5_vendor_ext(nfapi_p4_p5_message_header_t *header) {
nfapi_vnf_config_t *config = 0;
+void vnf_nr_start_thread(void *ptr) {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] VNF NFAPI thread - nfapi_vnf_start()%s\n", __FUNCTION__);
+ pthread_setname_np(pthread_self(), "VNF");
+ config = (nfapi_vnf_config_t *)ptr;
+ nfapi_nr_vnf_start(config);
+}
+
void vnf_start_thread(void *ptr) {
NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] VNF NFAPI thread - nfapi_vnf_start()%s\n", __FUNCTION__);
pthread_setname_np(pthread_self(), "VNF");
@@ -1138,7 +1497,57 @@ void vnf_start_thread(void *ptr) {
static vnf_info vnf;
-/*------------------------------------------------------------------------------*/
+void configure_nr_nfapi_vnf(char *vnf_addr, int vnf_p5_port) {
+ nfapi_setmode(NFAPI_MODE_VNF);
+ memset(&vnf, 0, sizeof(vnf));
+ memset(vnf.p7_vnfs, 0, sizeof(vnf.p7_vnfs));
+ vnf.p7_vnfs[0].timing_window = 32;
+ vnf.p7_vnfs[0].periodic_timing_enabled = 1;
+ vnf.p7_vnfs[0].aperiodic_timing_enabled = 0;
+ vnf.p7_vnfs[0].periodic_timing_period = 10;
+ vnf.p7_vnfs[0].config = nfapi_vnf_p7_config_create();
+ 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].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;
+
+ config->pnf_nr_param_resp = &pnf_nr_param_resp_cb;
+ config->pnf_nr_config_resp = &pnf_nr_config_resp_cb;
+ config->pnf_nr_start_resp = &pnf_nr_start_resp_cb;
+ config->nr_param_resp = &nr_param_resp_cb;
+ config->nr_config_resp = &nr_config_resp_cb;
+ config->nr_start_resp = &nr_start_resp_cb;
+ config->vendor_ext = &vendor_ext_cb;
+ config->user_data = &vnf;
+ // To allow custom vendor extentions to be added to nfapi
+ config->codec_config.unpack_vendor_extension_tlv = &vnf_unpack_vendor_extension_tlv;
+ config->codec_config.pack_vendor_extension_tlv = &vnf_pack_vendor_extension_tlv;
+ config->codec_config.unpack_p4_p5_vendor_extension = &vnf_unpack_p4_p5_vendor_extension;
+ config->codec_config.pack_p4_p5_vendor_extension = &vnf_pack_p4_p5_vendor_extension;
+ config->allocate_p4_p5_vendor_ext = &vnf_allocate_p4_p5_vendor_ext;
+ config->deallocate_p4_p5_vendor_ext = &vnf_deallocate_p4_p5_vendor_ext;
+ config->codec_config.allocate = &vnf_allocate;
+ config->codec_config.deallocate = &vnf_deallocate;
+ memset(&UL_RCC_INFO,0,sizeof(UL_RCC_IND_t));
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI start thread %s\n", __FUNCTION__);
+ pthread_create(&vnf_start_pthread, NULL, (void *)&vnf_nr_start_thread, config);
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Created VNF NFAPI start thread %s\n", __FUNCTION__);
+}
+
+
void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port) {
nfapi_setmode(NFAPI_MODE_VNF);
memset(&vnf, 0, sizeof(vnf));
@@ -1150,7 +1559,8 @@ void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port) {
vnf.p7_vnfs[0].config = nfapi_vnf_p7_config_create();
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 = 50001;
+ //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].mac = (mac_t *)malloc(sizeof(mac_t));
nfapi_vnf_config_t *config = nfapi_vnf_config_create();
config->malloc = malloc;
@@ -1161,8 +1571,10 @@ void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port) {
config->vnf_ipv6 = 0;
config->pnf_list = 0;
config->phy_list = 0;
+
config->pnf_connection_indication = &pnf_connection_indication_cb;
config->pnf_disconnect_indication = &pnf_disconnection_indication_cb;
+
config->pnf_param_resp = &pnf_param_resp_cb;
config->pnf_config_resp = &pnf_config_resp_cb;
config->pnf_start_resp = &pnf_start_resp_cb;
@@ -1203,15 +1615,17 @@ int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) {
return retval;
}
-int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_tti_request_t *dl_config_req)
+int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req)
{
+ //LOG_I(PHY, "sfn:%d,slot:%d\n",dl_config_req->SFN,dl_config_req->Slot);
+ //printf("\nEntering oai_nfapi_nr_dl_config_req sfn:%d,slot:%d\n",dl_config_req->SFN,dl_config_req->Slot);
nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
-
+ dl_config_req->header.message_id= NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST;
dl_config_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
int retval = nfapi_vnf_p7_nr_dl_config_req(p7_config, dl_config_req);
- dl_config_req->dl_tti_request_body.nPDUs = 0;
+ dl_config_req->dl_tti_request_body.nPDUs = 0;
dl_config_req->dl_tti_request_body.nGroup = 0;
@@ -1221,6 +1635,23 @@ int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_tti_request_t *dl_config_req)
return retval;
}
+int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req)
+{
+ nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
+ tx_data_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
+ tx_data_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST;
+ //LOG_D(PHY, "[VNF] %s() TX_REQ sfn_sf:%d number_of_pdus:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(tx_req->sfn_sf), tx_req->tx_request_body.number_of_pdus);
+ int retval = nfapi_vnf_p7_tx_data_req(p7_config, tx_data_req);
+
+ if (retval!=0) {
+ LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
+ } else {
+ tx_data_req->Number_of_PDUs = 0;
+ }
+
+ return retval;
+}
+
int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req)
{
nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
@@ -1238,6 +1669,22 @@ int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req)
return retval;
}
+int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req) {
+ nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
+ ul_dci_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
+ ul_dci_req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST;
+ //LOG_D(PHY, "[VNF] %s() HI_DCI0_REQ sfn_sf:%d dci:%d hi:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(hi_dci0_req->sfn_sf), hi_dci0_req->hi_dci0_request_body.number_of_dci, hi_dci0_req->hi_dci0_request_body.number_of_hi);
+ int retval = nfapi_vnf_p7_ul_dci_req(p7_config, ul_dci_req);
+
+ if (retval!=0) {
+ LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
+ } else {
+ ul_dci_req->numPdus = 0;
+ }
+
+ return retval;
+}
+
int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) {
nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
hi_dci0_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
@@ -1255,6 +1702,26 @@ int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) {
return retval;
}
+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) {
+ LOG_E(PHY, "%s() Problem sending retval:%d\n", __FUNCTION__, retval);
+ } else {
+ // Reset number of PDUs so that it is not resent
+ ul_tti_req->n_pdus = 0;
+ ul_tti_req->n_group = 0;
+ ul_tti_req->n_ulcch = 0;
+ ul_tti_req->n_ulsch = 0;
+ }
+ return retval;
+}
+
int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) {
nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config;
ul_config_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!!
diff --git a/nfapi/oai_integration/nfapi_vnf.h b/nfapi/oai_integration/nfapi_vnf.h
index 4ea26eda12..f4fd6a2bf9 100644
--- a/nfapi/oai_integration/nfapi_vnf.h
+++ b/nfapi/oai_integration/nfapi_vnf.h
@@ -23,5 +23,5 @@
#define NFAPI_VNF_H__
void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port);
-
+void configure_nr_nfapi_vnf(char *vnf_addr, int vnf_p5_port);
#endif
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h
index 32a31a99f6..0eb77a9d26 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h
@@ -120,6 +120,17 @@ typedef struct {
} nfapi_tl_t;
#define NFAPI_TAG_LENGTH_PACKED_LEN 4
+// 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_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_MAX_SFNSLOTDEC 1024*20 // 20 is for numerology 1
+
// Convenience methods to convert between SFN/SFN formats
#define NFAPI_SFNSF2DEC(_sfnsf) ((((_sfnsf) >> 4) * 10) + ((_sfnsf) & 0xF))
#define NFAPI_SFNSFDEC2SFNSF(_sfnsf_dec) ((((_sfnsf_dec) / 10) << 4) | (((_sfnsf_dec) - (((_sfnsf_dec) / 10) * 10)) & 0xF))
@@ -176,7 +187,6 @@ typedef enum {
NFAPI_DL_NODE_SYNC,
NFAPI_TIMING_INFO,
-
NFAPI_RSSI_REQUEST = 0x0200,
NFAPI_RSSI_RESPONSE,
NFAPI_RSSI_INDICATION,
@@ -587,6 +597,26 @@ typedef struct {
#define NFAPI_PNF_PHY_RF_TAG 0x1003
// Generic strucutre for single tlv value.
+typedef struct {
+ nfapi_tl_t tl;
+ int32_t value;
+} nfapi_int32_tlv_t;
+
+typedef struct {
+ nfapi_tl_t tl;
+ uint32_t value;
+} nfapi_uint32_tlv_t;
+
+typedef struct {
+ nfapi_tl_t tl;
+ int64_t value;
+} nfapi_int64_tlv_t;
+
+typedef struct {
+ nfapi_tl_t tl;
+ uint64_t value;
+} nfapi_uint64_tlv_t;
+
typedef struct {
nfapi_tl_t tl;
uint16_t value;
@@ -1106,6 +1136,7 @@ typedef struct {
typedef struct {
nfapi_p4_p5_message_header_t header;
+ uint8_t num_tlvs;
nfapi_pnf_phy_rf_config_t pnf_phy_rf_config;
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_pnf_config_request_t;
@@ -2466,7 +2497,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;
@@ -2481,22 +2512,50 @@ typedef struct {
typedef struct {
nfapi_p7_message_header_t header;
uint32_t last_sfn_sf;
+
uint32_t time_since_last_timing_info;
uint32_t dl_config_jitter;
uint32_t tx_request_jitter;
uint32_t ul_config_jitter;
uint32_t hi_dci0_jitter;
+
int32_t dl_config_latest_delay;
int32_t tx_request_latest_delay;
int32_t ul_config_latest_delay;
int32_t hi_dci0_latest_delay;
+
int32_t dl_config_earliest_arrival;
int32_t tx_request_earliest_arrival;
int32_t ul_config_earliest_arrival;
int32_t hi_dci0_earliest_arrival;
+
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_timing_info_t;
+typedef struct {
+ nfapi_p7_message_header_t header;
+
+ uint32_t last_sfn;
+ uint32_t last_slot;
+ uint32_t time_since_last_timing_info;
+
+ uint32_t dl_tti_jitter;
+ uint32_t tx_data_request_jitter;
+ uint32_t ul_tti_jitter;
+ uint32_t ul_dci_jitter;
+
+ int32_t dl_tti_latest_delay;
+ int32_t tx_data_request_latest_delay;
+ int32_t ul_tti_latest_delay;
+ int32_t ul_dci_latest_delay;
+
+ int32_t dl_tti_earliest_arrival;
+ int32_t tx_data_request_earliest_arrival;
+ int32_t ul_tti_earliest_arrival;
+ int32_t ul_dci_earliest_arrival;
+ nfapi_vendor_extension_tlv_t vendor_extension;
+} nfapi_nr_timing_info_t;
+
typedef struct {
nfapi_tl_t tl;
uint32_t handle;
@@ -3653,6 +3712,50 @@ typedef struct {
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nmm_stop_response_t;
+typedef struct
+{
+ // TODO: see if this needs to be uncommented
+
+ // These TLVs are used to setup the transport connection between VNF and PNF
+ nfapi_ipv4_address_t p7_vnf_address_ipv4;
+ nfapi_ipv6_address_t p7_vnf_address_ipv6;
+ nfapi_uint16_tlv_t p7_vnf_port;
+
+ nfapi_ipv4_address_t p7_pnf_address_ipv4;
+ nfapi_ipv6_address_t p7_pnf_address_ipv6;
+ nfapi_uint16_tlv_t p7_pnf_port;
+
+ nfapi_uint8_tlv_t timing_window; //Value: 0 → 30,000 microseconds
+ nfapi_uint8_tlv_t timing_info_mode;
+ nfapi_uint8_tlv_t timing_info_period;
+
+ nfapi_uint32_tlv_t dl_tti_timing_offset;
+ nfapi_uint32_tlv_t ul_tti_timing_offset;
+ nfapi_uint32_tlv_t ul_dci_timing_offset;
+ nfapi_uint32_tlv_t tx_data_timing_offset;
+
+ // These TLVs are used to setup the transport connection between VNF and PNF
+ /*
+ nfapi_uint8_tlv_t dl_ue_per_sf;
+ nfapi_uint8_tlv_t ul_ue_per_sf;
+
+ // These TLVs are used by PNF to report its RF capabilities to the VNF software
+ nfapi_rf_bands_t rf_bands;
+*/
+ // These TLVs are used by the VNF to configure the synchronization with the PNF.
+
+
+ // These TLVs are used by the VNF to configure the RF in the PNF
+ //nfapi_uint16_tlv_t max_transmit_power;
+ //nfapi_uint32_tlv_t nrarfcn;
+
+ // nfapi_nmm_frequency_bands_t nmm_gsm_frequency_bands;
+ // nfapi_nmm_frequency_bands_t nmm_umts_frequency_bands;
+ // nfapi_nmm_frequency_bands_t nmm_lte_frequency_bands;
+ // nfapi_uint8_tlv_t nmm_uplink_rssi_supported;
+
+} nfapi_nr_nfapi_t;
+
//
// Configuration options for the encode decode functions
//
@@ -3864,6 +3967,7 @@ int nfapi_p4_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
*
*/
int nfapi_p5_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPackedBuf, uint32_t packedBufLen, nfapi_p4_p5_codec_config_t* config);
+int nfapi_nr_p5_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPackedBuf, uint32_t packedBufLen, nfapi_p4_p5_codec_config_t* config);
/*! \brief Decodes an NFAPI P5 message header
* \param pMessageBuf A pointer to an encoded P5 message header
@@ -3887,6 +3991,7 @@ int nfapi_p5_message_header_unpack(void *pMessageBuf, uint32_t messageBufLen, vo
*
* The function will decode a byte stream pointed to by pMessageBuf into a nfapi p5 message structure pointer to by pUnpackedBuf
*/
+int nfapi_nr_p5_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p4_p5_codec_config_t* config);
int nfapi_p5_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p4_p5_codec_config_t* config);
/*! \brief Encodes an NFAPI P7 message to a buffer
@@ -3900,6 +4005,7 @@ int nfapi_p5_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
*
*/
int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t* config);
+int nfapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t* config);
/*! \brief Decodes an NFAPI P7 message header
* \param pMessageBuf A pointer to an encoded P7 message header
@@ -3925,6 +4031,7 @@ int nfapi_p7_message_header_unpack(void *pMessageBuf, uint32_t messageBufLen, vo
* The function will decode a byte stream pointed to by pMessageBuf into a nfapi p7 message structure pointer to by pUnpackedBuf
*/
int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p7_codec_config_t* config);
+int nfapi_nr_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p7_codec_config_t* config);
/*! \brief Calculates the checksum of a message
*
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h
index 650bda4f78..fbe7a0e170 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h
@@ -10,7 +10,7 @@
#define _NFAPI_NR_INTERFACE_H_
#include "nfapi_interface.h"
-#include
+#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h"
#define NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS 5
#define NFAPI_NR_MAX_NB_TCI_STATES_PDCCH 64
@@ -22,62 +22,32 @@
// nFAPI enums
-
//These TLVs are used exclusively by nFAPI
-typedef struct
-{
- // These TLVs are used to setup the transport connection between VNF and PNF
- // nfapi_ipv4_address_t p7_vnf_address_ipv4;
- // nfapi_ipv6_address_t p7_vnf_address_ipv6;
- // nfapi_uint16_tlv_t p7_vnf_port;
-
- // nfapi_ipv4_address_t p7_pnf_address_ipv4;
- // nfapi_ipv6_address_t p7_pnf_address_ipv6;
- // nfapi_uint16_tlv_t p7_pnf_port;
-
- // // These TLVs are used to setup the transport connection between VNF and PNF
- // nfapi_uint8_tlv_t dl_ue_per_sf;
- // nfapi_uint8_tlv_t ul_ue_per_sf;
-
- // These TLVs are used by PNF to report its RF capabilities to the VNF software
- nfapi_rf_bands_t rf_bands;
-
- // These TLVs are used by the VNF to configure the synchronization with the PNF.
- // nfapi_uint8_tlv_t timing_window;
- // nfapi_uint8_tlv_t timing_info_mode;
- // nfapi_uint8_tlv_t timing_info_period;
-
- // These TLVs are used by the VNF to configure the RF in the PNF
- // nfapi_uint16_tlv_t max_transmit_power;
- nfapi_uint32_tlv_t nrarfcn;
-
- // nfapi_nmm_frequency_bands_t nmm_gsm_frequency_bands;
- // nfapi_nmm_frequency_bands_t nmm_umts_frequency_bands;
- // nfapi_nmm_frequency_bands_t nmm_lte_frequency_bands;
- // nfapi_uint8_tlv_t nmm_uplink_rssi_supported;
-
-} nfapi_nr_nfapi_t;
-
-#define NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG 0x5100
-#define NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG 0x5101
-#define NFAPI_NR_NFAPI_P7_VNF_PORT_TAG 0x5102
-#define NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV4_TAG 0x5103
-#define NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV6_TAG 0x5104
-#define NFAPI_NR_NFAPI_P7_PNF_PORT_TAG 0x5105
+#define NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG 0x0100
+#define NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG 0x0101
+#define NFAPI_NR_NFAPI_P7_VNF_PORT_TAG 0x0102
+#define NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV4_TAG 0x0103
+#define NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV6_TAG 0x0104
+#define NFAPI_NR_NFAPI_P7_PNF_PORT_TAG 0x0105
+#define NFAPI_NR_NFAPI_DL_TTI_TIMING_OFFSET 0x0106
+#define NFAPI_NR_NFAPI_UL_TTI_TIMING_OFFSET 0x0107
+#define NFAPI_NR_NFAPI_UL_DCI_TIMING_OFFSET 0x0108
+#define NFAPI_NR_NFAPI_TX_DATA_TIMING_OFFSET 0x0109
+#define NFAPI_NR_NFAPI_TIMING_WINDOW_TAG 0x011E
+#define NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG 0x011F
+#define NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG 0x0120
+/*
#define NFAPI_NR_NFAPI_DOWNLINK_UES_PER_SUBFRAME_TAG 0x510A
#define NFAPI_NR_NFAPI_UPLINK_UES_PER_SUBFRAME_TAG 0x510B
#define NFAPI_NR_NFAPI_RF_BANDS_TAG 0x5114
-#define NFAPI_NR_NFAPI_TIMING_WINDOW_TAG 0x511E
-#define NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG 0x511F
-#define NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG 0x5120
#define NFAPI_NR_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG 0x5128
#define NFAPI_NR_NFAPI_NRARFCN_TAG 0x5129
#define NFAPI_NR_NFAPI_NMM_GSM_FREQUENCY_BANDS_TAG 0x5130
#define NFAPI_NR_NFAPI_NMM_UMTS_FREQUENCY_BANDS_TAG 0x5131
#define NFAPI_NR_NFAPI_NMM_LTE_FREQUENCY_BANDS_TAG 0x5132
#define NFAPI_NR_NFAPI_NMM_UPLINK_RSSI_SUPPORTED_TAG 0x5133
-
+*/
// P5 Message Structures
typedef struct {
@@ -323,7 +293,7 @@ typedef enum {
typedef enum {
NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED=0,
- NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED
+ NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED=1
} nfapi_nr_cce_reg_mapping_type_e;
typedef enum {
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf
new file mode 100644
index 0000000000..6ee4ec8404
Binary files /dev/null and b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf differ
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 12748b7a9e..bc5e7af45f 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
@@ -11,6 +11,7 @@
#include "stddef.h"
#include "nfapi_interface.h"
+#include "nfapi_nr_interface.h"
#define NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS 5
#define NFAPI_NR_MAX_NB_TCI_STATES_PDCCH 64
@@ -24,25 +25,7 @@
#define NFAPI_MAX_NUM_CB 8
// Extension to the generic structures for single tlv values
-typedef struct {
- nfapi_tl_t tl;
- int32_t value;
-} nfapi_int32_tlv_t;
-typedef struct {
- nfapi_tl_t tl;
- uint32_t value;
-} nfapi_uint32_tlv_t;
-
-typedef struct {
- nfapi_tl_t tl;
- int64_t value;
-} nfapi_int64_tlv_t;
-
-typedef struct {
- nfapi_tl_t tl;
- uint64_t value;
-} nfapi_uint64_tlv_t;
typedef enum {
NFAPI_NR_DMRS_TYPE1=0,
@@ -76,35 +59,42 @@ typedef enum {
NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST= 0X05,
NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION=0X06,
NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION=0X07,
+ NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE=0X010D,
+ NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE=0X010F,
//RESERVED 0X08 ~ 0X7F
NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST= 0X80,
NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST= 0X81,
NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION=0X82,
NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST= 0X83,
- NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST=0X54,
+ NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST=0X84, // CHANGED TO 0X84
NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION=0X85,
NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION= 0X86,
NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION= 0X87,
NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION= 0X88,
- NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION= 0X89
+ NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION= 0X89,
//RESERVED 0X8a ~ 0xff
+ NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_REQUEST = 0x0100,
+ NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_RESPONSE = 0x0101,
+ NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_REQUEST= 0x0102,
+ NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_RESPONSE= 0x0103,
+ NFAPI_NR_PHY_MSG_TYPE_PNF_START_REQUEST= 0x0104,
+ NFAPI_NR_PHY_MSG_TYPE_PNF_START_RESPONSE= 0x0105,
+ NFAPI_NR_PHY_MSG_TYPE_PNF_STOP_REQUEST= 0x0106,
+ NFAPI_NR_PHY_MSG_TYPE_PNF_STOP_RESPONSE= 0x0107,
+
+ NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC = 0x0180,
+ NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC,
+ NFAPI_NR_PHY_MSG_TYPE_TIMING_INFO
} nfapi_nr_phy_msg_type_e;
// SCF222_5G-FAPI_PHY_SPI_Specificayion.pdf Section 3.3
//3.3.1 PARAM
+
+
//same with nfapi_param_request_t
-typedef struct {
- nfapi_p4_p5_message_header_t header;
- nfapi_vendor_extension_tlv_t vendor_extension;
-} nfapi_nr_param_request_t;
-typedef enum {
- NFAPI_NR_PARAM_MSG_OK = 0,
- NFAPI_NR_PARAM_MSG_INVALID_STATE
-
-} nfapi_nr_param_errors_e;
/*typedef struct {
nfapi_nr_param_errors_e error_code;
@@ -278,12 +268,6 @@ typedef struct
//-------------------------------------------//
//3.3.2 CONFIG
-
-typedef enum {
- NFAPI_NR_CONFIG_MSG_OK = 0,
- NFAPI_NR_CONFIG_MSG_INVALID_CONFIG //The configuration provided has missing mandatory TLVs, or TLVs that are invalid or unsupported in this state.
-} nfapi_nr_config_errors_e;
-
/*typedef struct {
nfapi_nr_config_errors_e error_code;
uint8_t number_of_invalid_tlvs_that_can_only_be_configured_in_idle;
@@ -465,9 +449,108 @@ typedef struct
} nfapi_nr_measurement_config_t;
+// ERROR enums
+typedef enum { // Table 2-22
+ NFAPI_NR_PARAM_MSG_OK = 0,
+ NFAPI_NR_PARAM_MSG_INVALID_STATE
+} nfapi_nr_param_errors_e;
+
+typedef enum { // Table 2-25
+ NFAPI_NR_CONFIG_MSG_OK = 0,
+ NFAPI_NR_CONFIG_MSG_INVALID_STATE, //The CONFIG.request was received when the PHY was not in the IDLE state or the CONFIGURED state.
+ NFAPI_NR_CONFIG_MSG_INVALID_CONFIG //The configuration provided has missing mandatory TLVs, or TLVs that are invalid or unsupported in this state.
+} nfapi_nr_config_errors_e;
+
+typedef enum { // Table 2-27
+ NFAPI_NR_START_MSG_OK = 0,
+ NFAPI_NR_START_MSG_INVALID_STATE
+} nfapi_nr_start_errors_e;
+
+//PNF P5 NR
+typedef struct {
+ nfapi_p4_p5_message_header_t header;
+ nfapi_vendor_extension_tlv_t vendor_extension;
+} nfapi_nr_pnf_param_request_t;
typedef struct {
- uint8_t num_tlv;
+ nfapi_p4_p5_message_header_t header;
+ uint32_t error_code;
+ nfapi_pnf_param_general_t pnf_param_general;
+ nfapi_pnf_phy_t pnf_phy;
+ nfapi_vendor_extension_tlv_t vendor_extension;
+} nfapi_nr_pnf_param_response_t;
+
+typedef struct {
+ nfapi_p4_p5_message_header_t header;
+ uint8_t num_tlvs;
+ nfapi_pnf_phy_rf_config_t pnf_phy_rf_config;
+ nfapi_vendor_extension_tlv_t vendor_extension;
+} nfapi_nr_pnf_config_request_t;
+
+typedef struct {
+ nfapi_p4_p5_message_header_t header;
+ uint32_t error_code;
+ nfapi_vendor_extension_tlv_t vendor_extension;
+} nfapi_nr_pnf_config_response_t;
+
+typedef struct {
+ nfapi_p4_p5_message_header_t header;
+ nfapi_vendor_extension_tlv_t vendor_extension;
+} nfapi_nr_pnf_start_request_t;
+
+typedef struct {
+ nfapi_p4_p5_message_header_t header;
+ uint32_t error_code;
+ nfapi_vendor_extension_tlv_t vendor_extension;
+} nfapi_nr_pnf_start_response_t;
+
+typedef struct {
+ nfapi_p4_p5_message_header_t header;
+ nfapi_vendor_extension_tlv_t vendor_extension;
+} nfapi_nr_pnf_stop_request_t;
+
+typedef struct {
+ nfapi_p4_p5_message_header_t header;
+ uint32_t error_code;
+ nfapi_vendor_extension_tlv_t vendor_extension;
+} nfapi_nr_pnf_stop_response_t;
+
+
+/* PARAM.REQUEST */
+typedef struct {
+ nfapi_p4_p5_message_header_t header;
+ nfapi_vendor_extension_tlv_t vendor_extension;
+} nfapi_nr_param_request_scf_t;
+
+/* PARAM.RESPONSE */
+typedef struct {
+ nfapi_p4_p5_message_header_t header;
+ uint8_t error_code;
+
+ uint8_t num_tlv;
+ nfapi_vendor_extension_tlv_t vendor_extension;
+
+ nfapi_nr_cell_param_t cell_param;
+ nfapi_nr_carrier_param_t carrier_param;
+ nfapi_nr_pdcch_param_t pdcch_param;
+ nfapi_nr_pucch_param_t pucch_param;
+ nfapi_nr_pdsch_param_t pdsch_param;
+ nfapi_nr_pusch_param_t pusch_param;
+ nfapi_nr_prach_param_t prach_param;
+ nfapi_nr_measurement_param_t measurement_param;
+ nfapi_nr_nfapi_t nfapi_config;
+} nfapi_nr_param_response_scf_t;
+
+//------------------------------//
+//3.3.2 CONFIG
+
+/* CONFIG.REQUEST */
+typedef struct {
+ nfapi_p4_p5_message_header_t header;
+
+ uint8_t num_tlv;
+ nfapi_vendor_extension_tlv_t vendor_extension;
+
nfapi_nr_carrier_config_t carrier_config;
nfapi_nr_cell_config_t cell_config;
nfapi_nr_ssb_config_t ssb_config;
@@ -475,20 +558,32 @@ typedef struct {
nfapi_nr_ssb_table_t ssb_table;
nfapi_nr_tdd_table_t tdd_table;
nfapi_nr_measurement_config_t measurement_config;
+ nfapi_nr_nfapi_t nfapi_config;
} nfapi_nr_config_request_scf_t;
+/* CONFIG.RESPONSE */
+typedef struct {
+ nfapi_p4_p5_message_header_t header;
+ uint8_t error_code;
+ //uint8_t num_invalid_tlvs;
+ // TODO: add list of invalid/unsupported TLVs (see Table 3.18)
+ nfapi_vendor_extension_tlv_t vendor_extension;
+} nfapi_nr_config_response_scf_t;
+
//------------------------------//
//3.3.3 START
typedef struct {
nfapi_p4_p5_message_header_t header;
nfapi_vendor_extension_tlv_t vendor_extension;
-} nfapi_nr_start_request_t;
+} nfapi_nr_start_request_scf_t;
-typedef enum {
- NFAPI_NR_START_MSG_INVALID_STATE
-} nfapi_nr_start_errors_e;
+typedef struct {
+ nfapi_p4_p5_message_header_t header;
+ nfapi_nr_start_errors_e error_code;
+ nfapi_vendor_extension_tlv_t vendor_extension;
+} nfapi_nr_start_response_scf_t;
//3.3.4 STOP
@@ -497,6 +592,7 @@ typedef struct {
nfapi_vendor_extension_tlv_t vendor_extension;
} nfapi_nr_stop_request_t;
+
typedef struct {
nfapi_p4_p5_message_header_t header;
nfapi_vendor_extension_tlv_t vendor_extension;
@@ -580,7 +676,7 @@ typedef struct {
uint16_t sfn; //0->1023
uint16_t slot;//0->319
-} nfapi_nr_slot_indication_t;
+} nfapi_nr_slot_indication_scf_t;
// 3.4.2
@@ -619,8 +715,10 @@ typedef struct {
uint16_t prgSize;
/// Number of STD ant ports (parallel streams) feeding into the digBF Value: 0->255
uint8_t digBFInterfaces;
+ // Depends on numPRGs
uint16_t PMIdx[275];
- uint16_t *beamIdx[275];
+ // Depends on digBFInterfaces
+ uint16_t beamIdx[256];
} nfapi_nr_tx_precoding_and_beamforming_t;
//table 3-37
@@ -941,6 +1039,7 @@ typedef struct {
} nfapi_nr_dl_tti_request_pdu_t;
#define NFAPI_NR_MAX_DL_TTI_PDUS 32
+
typedef struct {
/// Number of PDUs that are included in this message. All PDUs in the message are numbered in order. Value 0 -> 255
uint8_t nPDUs;
@@ -954,11 +1053,28 @@ typedef struct {
uint8_t PduIdx[256][12];
} nfapi_nr_dl_tti_request_body_t;
+
+typedef struct {
+ nfapi_p7_message_header_t header;
+ uint32_t t1;
+ int32_t delta_sfn_slot;
+ nfapi_vendor_extension_tlv_t vendor_extension;
+} nfapi_nr_dl_node_sync_t;
+
+typedef struct {
+ nfapi_p7_message_header_t header;
+ uint32_t t1;
+ uint32_t t2;
+ uint32_t t3;
+ nfapi_vendor_extension_tlv_t vendor_extension;
+} nfapi_nr_ul_node_sync_t;
+
+
typedef struct {
nfapi_p7_message_header_t header;
/// System Frame Number (0-1023)
uint16_t SFN;
- /// Slot number (0-319)
+ /// Slot number (0-19)
uint16_t Slot;
nfapi_nr_dl_tti_request_body_t dl_tti_request_body;
nfapi_vendor_extension_tlv_t vendor_extension;
@@ -973,7 +1089,7 @@ typedef struct
nfapi_nr_dl_tti_ssb_pdu_t* ssb_pdu;
} nfapi_nr_dl_pdu_configuration_t;
*/
- /*
+ /*
typedef struct
{
uint16_t pdu_type;//0: PDCCH PDU 1: PDSCH PDU 2: CSI-RS PDU 3: SSB PDU,
@@ -1272,6 +1388,7 @@ typedef struct
} nfapi_nr_ul_tti_request_number_of_groups_t;
typedef struct {
+ nfapi_p7_message_header_t header;
uint16_t SFN; //0->1023
uint16_t Slot;//0->319
uint8_t n_pdus;//Number of PDUs that are included in this message. All PDUs in the message are numbered in order. Value 0 -> 255
@@ -1318,6 +1435,7 @@ typedef struct {
} nfapi_nr_ul_dci_request_pdus_t;
typedef struct {
+ nfapi_p7_message_header_t header;
uint16_t SFN;
uint16_t Slot;
uint8_t numPdus;
@@ -1363,6 +1481,7 @@ typedef struct
#define NFAPI_NR_MAX_TX_REQUEST_PDUS 16
typedef struct
{
+ nfapi_p7_message_header_t header;
uint16_t SFN;
uint16_t Slot;
uint16_t Number_of_PDUs;
diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi.c b/nfapi/open-nFAPI/nfapi/src/nfapi.c
index 61c6875bc6..ba800c3634 100644
--- a/nfapi/open-nFAPI/nfapi/src/nfapi.c
+++ b/nfapi/open-nFAPI/nfapi/src/nfapi.c
@@ -712,7 +712,7 @@ int unpack_tlv_list(unpack_tlv_t unpack_fns[], uint16_t size, uint8_t **ppReadPa
for(idx = 0; idx < size; ++idx)
{
- if(unpack_fns[idx].tag == generic_tl.tag)
+ 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);
diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c
index a8ac0f0a65..8aea9f590c 100644
--- a/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c
+++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c
@@ -33,10 +33,18 @@
#include
#include
+#include "nfapi_nr_interface.h"
+#include "nfapi_nr_interface_scf.h"
#include
// Pack routines
+//TODO: Add pacl/unpack fns for uint32 and uint64
+static uint8_t pack_nr_pnf_param_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config)
+{
+ nfapi_nr_pnf_param_request_t* request = (nfapi_nr_pnf_param_request_t*)msg;
+ return pack_vendor_extension_tlv(request->vendor_extension, ppWritePackedMsg, end, config);
+}
static uint8_t pack_pnf_param_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config)
{
@@ -233,6 +241,26 @@ static uint8_t pack_pnf_phy_rel13_nb_iot_value(void* tlv, uint8_t **ppWritePacke
return (push16(value->number_of_phys, ppWritePackedMsg, end) &&
packarray(value->phy, sizeof(nfapi_pnf_phy_rel13_nb_iot_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, ppWritePackedMsg, end, &pack_pnf_phy_rel13_nb_iot_info));
}
+/*
+static uint8_t pack_nr_pnf_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
+{
+ nfapi_nr_pnf_param_response_t *pNfapiMsg = (nfapi_nr_pnf_param_response_t*)msg;
+
+ return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+ pack_tlv(NFAPI_PNF_PARAM_GENERAL_TAG, &pNfapiMsg->pnf_param_general, ppWritePackedMsg, end, &pack_pnf_param_general_value) &&
+ pack_tlv(NFAPI_PNF_PHY_TAG, &pNfapiMsg->pnf_phy, ppWritePackedMsg, end, &pack_pnf_phy_value) &&
+ pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+*/
+static uint8_t pack_nr_pnf_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
+{
+ nfapi_nr_pnf_param_response_t *pNfapiMsg = (nfapi_nr_pnf_param_response_t*)msg;
+
+ return (push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+ pack_tlv(NFAPI_PNF_PARAM_GENERAL_TAG, &pNfapiMsg->pnf_param_general, ppWritePackedMsg, end, &pack_pnf_param_general_value) &&
+ pack_tlv(NFAPI_PNF_PHY_TAG, &pNfapiMsg->pnf_phy, ppWritePackedMsg, end, &pack_pnf_phy_value) &&
+ pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
static uint8_t pack_pnf_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
@@ -251,6 +279,7 @@ static uint8_t pack_pnf_param_response(void *msg, uint8_t **ppWritePackedMsg, ui
pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
}
+
static uint8_t pack_phy_rf_config_info(void* elem, uint8_t **ppWritePackedMsg, uint8_t *end)
{
nfapi_phy_rf_config_info_t* rf = (nfapi_phy_rf_config_info_t*)elem;
@@ -270,11 +299,29 @@ static uint8_t pack_pnf_phy_rf_config_value(void *tlv, uint8_t **ppWritePackedMs
}
+static uint8_t pack_nr_pnf_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
+{
+ nfapi_nr_pnf_config_request_t *pNfapiMsg = (nfapi_nr_pnf_config_request_t*)msg;
+ return (pack_tlv(NFAPI_PNF_PHY_RF_TAG, &pNfapiMsg->pnf_phy_rf_config, ppWritePackedMsg, end, &pack_pnf_phy_rf_config_value) &&
+ //push8(pNfapiMsg->num_tlvs,ppWritePackedMsg,end) &&
+ pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end , config));
+}
+
static uint8_t pack_pnf_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
{
nfapi_pnf_config_request_t *pNfapiMsg = (nfapi_pnf_config_request_t*)msg;
- return ( pack_tlv(NFAPI_PNF_PHY_RF_TAG, &pNfapiMsg->pnf_phy_rf_config, ppWritePackedMsg, end, &pack_pnf_phy_rf_config_value) &&
- pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end , config));
+ return (pack_tlv(NFAPI_PNF_PHY_RF_TAG, &pNfapiMsg->pnf_phy_rf_config, ppWritePackedMsg, end, &pack_pnf_phy_rf_config_value) &&
+ push8(pNfapiMsg->num_tlvs,ppWritePackedMsg,end) &&
+ pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end , config));
+}
+
+
+static uint8_t pack_nr_pnf_config_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config)
+{
+ nfapi_nr_pnf_config_response_t *pNfapiMsg = (nfapi_nr_pnf_config_response_t*)msg;
+
+ return ( push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+ pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
}
@@ -286,12 +333,28 @@ static uint8_t pack_pnf_config_response(void *msg, uint8_t **ppWritePackedMsg, u
pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
}
+static uint8_t pack_nr_pnf_start_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config)
+{
+ nfapi_nr_pnf_start_request_t *pNfapiMsg = (nfapi_nr_pnf_start_request_t*)msg;
+ return ( pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
static uint8_t pack_pnf_start_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config)
{
nfapi_pnf_start_request_t *pNfapiMsg = (nfapi_pnf_start_request_t*)msg;
return ( pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
}
+
+static uint8_t pack_nr_pnf_start_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config)
+{
+ nfapi_nr_pnf_start_response_t *pNfapiMsg = (nfapi_nr_pnf_start_response_t*)msg;
+
+ return( push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+ pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+
static uint8_t pack_pnf_start_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config)
{
nfapi_pnf_start_response_t *pNfapiMsg = (nfapi_pnf_start_response_t*)msg;
@@ -300,12 +363,31 @@ static uint8_t pack_pnf_start_response(void *msg, uint8_t **ppWritePackedMsg, ui
pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
}
+
+static uint8_t pack_nr_pnf_stop_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config)
+{
+ nfapi_nr_pnf_stop_request_t *pNfapiMsg = (nfapi_nr_pnf_stop_request_t*)msg;
+ return ( pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) );
+}
+
+
+
static uint8_t pack_pnf_stop_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config)
{
nfapi_pnf_stop_request_t *pNfapiMsg = (nfapi_pnf_stop_request_t*)msg;
return ( pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) );
}
+
+static uint8_t pack_nr_pnf_stop_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config)
+{
+ nfapi_nr_pnf_stop_response_t *pNfapiMsg = (nfapi_nr_pnf_stop_response_t*)msg;
+
+ return ( push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+ pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+
static uint8_t pack_pnf_stop_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config)
{
nfapi_pnf_stop_response_t *pNfapiMsg = (nfapi_pnf_stop_response_t*)msg;
@@ -314,12 +396,31 @@ static uint8_t pack_pnf_stop_response(void *msg, uint8_t **ppWritePackedMsg, uin
pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
}
+static uint8_t pack_nr_param_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config)
+{
+ nfapi_nr_param_request_scf_t *pNfapiMsg = (nfapi_nr_param_request_scf_t*)msg;
+ return (pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
static uint8_t pack_param_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t* end, nfapi_p4_p5_codec_config_t* config)
-{
+{
nfapi_param_request_t *pNfapiMsg = (nfapi_param_request_t*)msg;
return (pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
}
+static uint8_t pack_uint32_tlv_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+ nfapi_uint32_tlv_t* value = (nfapi_uint32_tlv_t*)tlv;
+ return push32(value->value, ppWritePackedMsg, end);
+}
+
+static uint8_t unpack_uint32_tlv_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
+{
+ nfapi_uint32_tlv_t* value = (nfapi_uint32_tlv_t*)tlv;
+ return pull32(ppReadPackedMsg, &value->value, end);
+}
+
+
static uint8_t pack_uint16_tlv_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
{
nfapi_uint16_tlv_t* value = (nfapi_uint16_tlv_t*)tlv;
@@ -331,6 +432,7 @@ static uint8_t unpack_uint16_tlv_value(void* tlv, uint8_t **ppReadPackedMsg, uin
nfapi_uint16_tlv_t* value = (nfapi_uint16_tlv_t*)tlv;
return pull16(ppReadPackedMsg, &value->value, end);
}
+
static uint8_t pack_int16_tlv_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
{
nfapi_int16_tlv_t* value = (nfapi_int16_tlv_t*)tlv;
@@ -414,18 +516,19 @@ 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)
-//{
+// 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)
-{
+// }
+
+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;
return( push8(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
@@ -536,6 +639,92 @@ static uint8_t pack_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_
}
+static uint8_t pack_nr_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
+{
+ printf("\nRUNNING pack_param_response\n");
+ nfapi_nr_param_response_scf_t *pNfapiMsg = (nfapi_nr_param_response_scf_t*)msg;
+
+ return (push8(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+ push8(pNfapiMsg->num_tlv, ppWritePackedMsg, end) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_RELEASE_CAPABILITY_TAG, &(pNfapiMsg->cell_param.release_capability), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_PHY_STATE_TAG, &(pNfapiMsg->cell_param.phy_state), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_SKIP_BLANK_DL_CONFIG_TAG, &(pNfapiMsg->cell_param.skip_blank_dl_config), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_SKIP_BLANK_UL_CONFIG_TAG, &(pNfapiMsg->cell_param.skip_blank_ul_config), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_NUM_CONFIG_TLVS_TO_REPORT_TAG, &(pNfapiMsg->cell_param.num_config_tlvs_to_report ), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+
+ pack_tlv(NFAPI_NR_PARAM_TLV_CYCLIC_PREFIX_TAG, &(pNfapiMsg->carrier_param.cyclic_prefix), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_SUPPORTED_SUBCARRIER_SPACINGS_DL_TAG, &(pNfapiMsg->carrier_param.supported_subcarrier_spacings_dl), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_SUPPORTED_BANDWIDTH_DL_TAG, &(pNfapiMsg->carrier_param.supported_bandwidth_dl), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_SUPPORTED_SUBCARRIER_SPACINGS_UL_TAG, &(pNfapiMsg->carrier_param.supported_subcarrier_spacings_ul), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_SUPPORTED_BANDWIDTH_UL_TAG, &(pNfapiMsg->carrier_param.supported_bandwidth_ul), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+
+ pack_tlv(NFAPI_NR_PARAM_TLV_CCE_MAPPING_TYPE_TAG, &(pNfapiMsg->pdcch_param.cce_mapping_type), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_CORESET_OUTSIDE_FIRST_3_OFDM_SYMS_OF_SLOT_TAG, &(pNfapiMsg->pdcch_param.coreset_outside_first_3_of_ofdm_syms_of_slot), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_PRECODER_GRANULARITY_CORESET_TAG, &(pNfapiMsg->pdcch_param.coreset_precoder_granularity_coreset), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_PDCCH_MU_MIMO_TAG, &(pNfapiMsg->pdcch_param.pdcch_mu_mimo), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_PDCCH_PRECODER_CYCLING_TAG, &(pNfapiMsg->pdcch_param.pdcch_precoder_cycling), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_MAX_PDCCHS_PER_SLOT_TAG, &(pNfapiMsg->pdcch_param.max_pdcch_per_slot), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+
+ pack_tlv(NFAPI_NR_PARAM_TLV_PUCCH_FORMATS_TAG, &(pNfapiMsg->pucch_param.pucch_formats), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_MAX_PUCCHS_PER_SLOT_TAG, &(pNfapiMsg->pucch_param.max_pucchs_per_slot), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+
+ pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_MAPPING_TYPE_TAG, &(pNfapiMsg->pdsch_param.pdsch_mapping_type), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_ALLOCATION_TYPES_TAG, &(pNfapiMsg->pdsch_param.pdsch_allocation_types), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_VRB_TO_PRB_MAPPING_TAG, &(pNfapiMsg->pdsch_param.pdsch_vrb_to_prb_mapping), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_CBG_TAG, &(pNfapiMsg->pdsch_param.pdsch_cbg), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_DMRS_CONFIG_TYPES_TAG, &(pNfapiMsg->pdsch_param.pdsch_dmrs_config_types), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_DMRS_MAX_LENGTH_TAG, &(pNfapiMsg->pdsch_param.pdsch_dmrs_max_length), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_DMRS_ADDITIONAL_POS_TAG, &(pNfapiMsg->pdsch_param.pdsch_dmrs_additional_pos), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_MAX_PDSCH_S_YBS_PER_SLOT_TAG, &(pNfapiMsg->pdsch_param.max_pdsch_tbs_per_slot), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_MAX_NUMBER_MIMO_LAYERS_PDSCH_TAG, &(pNfapiMsg->pdsch_param.max_number_mimo_layers_pdsch), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_MAX_MU_MIMO_USERS_DL_TAG, &(pNfapiMsg->pdsch_param.max_mu_mimo_users_dl), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_DATA_IN_DMRS_SYMBOLS_TAG, &(pNfapiMsg->pdsch_param.pdsch_data_in_dmrs_symbols), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_PREMPTION_SUPPORT_TAG, &(pNfapiMsg->pdsch_param.premption_support), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_PDSCH_NON_SLOT_SUPPORT_TAG, &(pNfapiMsg->pdsch_param.pdsch_non_slot_support), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+
+ pack_tlv(NFAPI_NR_PARAM_TLV_UCI_MUX_ULSCH_IN_PUSCH_TAG, &(pNfapiMsg->pusch_param.uci_mux_ulsch_in_pusch), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_UCI_ONLY_PUSCH_TAG, &(pNfapiMsg->pusch_param.uci_only_pusch), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_FREQUENCY_HOPPING_TAG, &(pNfapiMsg->pusch_param.pusch_frequency_hopping), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_DMRS_CONFIG_TYPES_TAG, &(pNfapiMsg->pusch_param.pusch_dmrs_config_types), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_DMRS_MAX_LEN_TAG, &(pNfapiMsg->pusch_param.pusch_dmrs_max_len), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_DMRS_ADDITIONAL_POS_TAG, &(pNfapiMsg->pusch_param.pusch_dmrs_additional_pos), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_CBG_TAG, &(pNfapiMsg->pusch_param.pusch_cbg), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_MAPPING_TYPE_TAG, &(pNfapiMsg->pusch_param.pusch_mapping_type), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_ALLOCATION_TYPES_TAG, &(pNfapiMsg->pusch_param.pusch_allocation_types), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_VRB_TO_PRB_MAPPING_TAG, &(pNfapiMsg->pusch_param.pusch_vrb_to_prb_mapping), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_MAX_PTRS_PORTS_TAG, &(pNfapiMsg->pusch_param.pusch_max_ptrs_ports), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_MAX_PDUSCHS_TBS_PER_SLOT_TAG, &(pNfapiMsg->pusch_param.max_pduschs_tbs_per_slot), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_MAX_NUMBER_MIMO_LAYERS_NON_CB_PUSCH_TAG, &(pNfapiMsg->pusch_param.max_number_mimo_layers_non_cb_pusch), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_SUPPORTED_MODULATION_ORDER_UL_TAG, &(pNfapiMsg->pusch_param.supported_modulation_order_ul), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_MAX_MU_MIMO_USERS_UL_TAG, &(pNfapiMsg->pusch_param.max_mu_mimo_users_ul), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_DFTS_OFDM_SUPPORT_TAG, &(pNfapiMsg->pusch_param.dfts_ofdm_support), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_PUSCH_AGGREGATION_FACTOR_TAG, &(pNfapiMsg->pusch_param.pusch_aggregation_factor), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+
+ pack_tlv(NFAPI_NR_PARAM_TLV_PRACH_LONG_FORMATS_TAG, &(pNfapiMsg->prach_param.prach_long_formats), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_PRACH_SHORT_FORMATS_TAG, &(pNfapiMsg->prach_param.prach_short_formats), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_PRACH_RESTRICTED_SETS_TAG, &(pNfapiMsg->prach_param.prach_restricted_sets), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_PARAM_TLV_MAX_PRACH_FD_OCCASIONS_IN_A_SLOT_TAG, &(pNfapiMsg->prach_param.max_prach_fd_occasions_in_a_slot), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+
+ pack_tlv(NFAPI_NR_PARAM_TLV_RSSI_MEASUREMENT_SUPPORT_TAG, &(pNfapiMsg->measurement_param.rssi_measurement_support), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+
+ // config:
+
+ pack_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4), ppWritePackedMsg, end, &pack_ipv4_address_value) &&
+ pack_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv6), ppWritePackedMsg, end, &pack_ipv6_address_value) &&
+
+ pack_tlv(NFAPI_NR_NFAPI_P7_VNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_port), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+
+ pack_tlv(NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv4), ppWritePackedMsg, end, &pack_ipv4_address_value) &&
+ pack_tlv(NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv6), ppWritePackedMsg, end, &pack_ipv6_address_value) &&
+
+ pack_tlv(NFAPI_NR_NFAPI_P7_PNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_port), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+ pack_tlv(NFAPI_NR_NFAPI_TIMING_WINDOW_TAG, &(pNfapiMsg->nfapi_config.timing_window), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG, &(pNfapiMsg->nfapi_config.timing_info_mode), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG, &(pNfapiMsg->nfapi_config.timing_info_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+
+}
+
static uint8_t pack_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
{
nfapi_config_request_t *pNfapiMsg = (nfapi_config_request_t*)msg;
@@ -668,20 +857,108 @@ static uint8_t pack_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_
pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) );
}
+
+static uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
+{
+ printf("\n\nEntering pack_config_request\n");
+ nfapi_nr_config_request_scf_t *pNfapiMsg = (nfapi_nr_config_request_scf_t*)msg;
+
+
+ return (push8(pNfapiMsg->num_tlv, ppWritePackedMsg, end) &&
+ pack_tlv(NFAPI_NR_CONFIG_DL_BANDWIDTH_TAG, &(pNfapiMsg->carrier_config.dl_bandwidth), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+ pack_tlv(NFAPI_NR_CONFIG_DL_FREQUENCY_TAG, &(pNfapiMsg->carrier_config.dl_frequency), ppWritePackedMsg, end, &pack_uint32_tlv_value) &&
+ pack_tlv(NFAPI_NR_CONFIG_DL_GRID_SIZE_TAG, &(pNfapiMsg->carrier_config.dl_grid_size[1]), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+ pack_tlv(NFAPI_NR_CONFIG_DL_K0_TAG, &(pNfapiMsg->carrier_config.dl_k0[1]), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+ pack_tlv(NFAPI_NR_CONFIG_NUM_RX_ANT_TAG, &(pNfapiMsg->carrier_config.num_rx_ant), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+ pack_tlv(NFAPI_NR_CONFIG_NUM_TX_ANT_TAG, &(pNfapiMsg->carrier_config.num_tx_ant), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+ pack_tlv(NFAPI_NR_CONFIG_UL_GRID_SIZE_TAG, &(pNfapiMsg->carrier_config.ul_grid_size[1]), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+ 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) &&
+ pack_tlv(NFAPI_NR_CONFIG_SSB_PER_RACH_TAG, &(pNfapiMsg->prach_config.ssb_per_rach), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_CONFIG_PRACH_SUB_C_SPACING_TAG, &(pNfapiMsg->prach_config.prach_sub_c_spacing), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_CONFIG_PRACH_ROOT_SEQUENCE_INDEX_TAG, &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].prach_root_sequence_index), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+ pack_tlv(NFAPI_NR_CONFIG_K1_TAG, &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].k1), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+ pack_tlv(NFAPI_NR_CONFIG_PRACH_ZERO_CORR_CONF_TAG, &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].prach_zero_corr_conf), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_CONFIG_NUM_ROOT_SEQUENCES_TAG, &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].num_root_sequences), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+
+
+ pack_tlv(NFAPI_NR_CONFIG_SCS_COMMON_TAG, &(pNfapiMsg->ssb_config.scs_common), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_CONFIG_SS_PBCH_POWER_TAG, &(pNfapiMsg->ssb_config.ss_pbch_power), ppWritePackedMsg, end, &pack_uint32_tlv_value) &&
+
+ pack_tlv(NFAPI_NR_CONFIG_BETA_PSS_TAG, &(pNfapiMsg->ssb_table.beta_pss), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_CONFIG_MIB_TAG, &(pNfapiMsg->ssb_table.MIB), ppWritePackedMsg, end, &pack_uint32_tlv_value) &&
+ pack_tlv(NFAPI_NR_CONFIG_SSB_MASK_TAG, &(pNfapiMsg->ssb_table.ssb_mask_list[0].ssb_mask), ppWritePackedMsg, end, &pack_uint32_tlv_value) &&
+ pack_tlv(NFAPI_NR_CONFIG_SSB_MASK_TAG, &(pNfapiMsg->ssb_table.ssb_mask_list[1].ssb_mask), ppWritePackedMsg, end, &pack_uint32_tlv_value) &&
+
+ pack_tlv(NFAPI_NR_CONFIG_SSB_OFFSET_POINT_A_TAG, &(pNfapiMsg->ssb_table.ssb_offset_point_a), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+ pack_tlv(NFAPI_NR_CONFIG_SSB_PERIOD_TAG, &(pNfapiMsg->ssb_table.ssb_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG, &(pNfapiMsg->ssb_table.ssb_subcarrier_offset), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+
+ pack_tlv(NFAPI_NR_CONFIG_TDD_PERIOD_TAG, &(pNfapiMsg->tdd_table.tdd_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_CONFIG_SLOT_CONFIG_TAG, &(pNfapiMsg->tdd_table.max_tdd_periodicity_list[0].max_num_of_symbol_per_slot_list[0].slot_config), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+
+ //pack_tlv(NFAPI_NR_NFAPI_DOWNLINK_UES_PER_SUBFRAME_TAG, &(pNfapiMsg->nfapi_config.dl_ue_per_sf), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ //pack_tlv(NFAPI_NR_NFAPI_MAXIMUM_TRANSMIT_POWER_TAG, &(pNfapiMsg->nfapi_config.max_transmit_power), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+ //pack_tlv(NFAPI_NR_NFAPI_NRARFCN_TAG, &(pNfapiMsg->nfapi_config.nrarfcn), ppWritePackedMsg, end, &pack_uint32_tlv_value) &&
+ pack_tlv(NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv4), ppWritePackedMsg, end, &pack_ipv4_address_value) &&
+ pack_tlv(NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv6), ppWritePackedMsg, end, &pack_ipv6_address_value) &&
+ pack_tlv(NFAPI_NR_NFAPI_P7_PNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_port), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+ pack_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4), ppWritePackedMsg, end, &pack_ipv4_address_value) &&
+ pack_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv6), ppWritePackedMsg, end, &pack_ipv6_address_value) &&
+ pack_tlv(NFAPI_NR_NFAPI_P7_VNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_port), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
+ //pack_tlv(NFAPI_NR_NFAPI_RF_BANDS_TAG, &(pNfapiMsg->nfapi_config.rf_bands), ppWritePackedMsg, end, &pack_rf_bands_value) &&
+ pack_tlv(NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG, &(pNfapiMsg->nfapi_config.timing_info_mode), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG, &(pNfapiMsg->nfapi_config.timing_info_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ pack_tlv(NFAPI_NR_NFAPI_TIMING_WINDOW_TAG, &(pNfapiMsg->nfapi_config.timing_window), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+ //pack_tlv(NFAPI_NR_NFAPI_UPLINK_UES_PER_SUBFRAME_TAG, &(pNfapiMsg->nfapi_config.ul_ue_per_sf), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+
+ pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) );
+}
+
+static uint8_t pack_nr_config_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
+{
+ nfapi_nr_config_response_scf_t *pNfapiMsg = (nfapi_nr_config_response_scf_t*)msg;
+
+ return ( push8(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+ pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) );
+}
+
static uint8_t pack_config_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
{
nfapi_config_response_t *pNfapiMsg = (nfapi_config_response_t*)msg;
- return ( push32(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
+ return ( push8(pNfapiMsg->error_code, ppWritePackedMsg, end) &&
pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) );
}
+static uint8_t pack_nr_start_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
+{
+ nfapi_nr_start_request_scf_t *pNfapiMsg = (nfapi_nr_start_request_scf_t*)msg;
+ return pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config);
+}
+
static uint8_t pack_start_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
{
nfapi_start_request_t *pNfapiMsg = (nfapi_start_request_t*)msg;
return pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config);
}
+static uint8_t pack_nr_start_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
+{
+ nfapi_nr_start_response_scf_t *pNfapiMsg = (nfapi_nr_start_response_scf_t*)msg;
+
+ return ( push32(pNfapiMsg->error_code, ppWritePackedMsg, end ) &&
+ pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) );
+}
+
static uint8_t pack_start_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
{
nfapi_start_response_t *pNfapiMsg = (nfapi_start_response_t*)msg;
@@ -690,6 +967,7 @@ static uint8_t pack_start_response(void *msg, uint8_t **ppWritePackedMsg, uint8_
pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config) );
}
+
static uint8_t pack_stop_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
{
nfapi_stop_request_t *pNfapiMsg = (nfapi_stop_request_t*)msg;
@@ -733,6 +1011,101 @@ static uint8_t pack_measurement_response(void *msg, uint8_t **ppWritePackedMsg,
pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
}
+static uint8_t pack_nr_p5_message_body(nfapi_p4_p5_message_header_t *header, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
+{
+ uint8_t result = 0;
+ // look for the specific message
+ switch (header->message_id)
+ {
+ case NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_REQUEST:
+ result = pack_nr_pnf_param_request(header, ppWritePackedMsg, end, config);
+ break;
+
+ case NFAPI_PNF_PARAM_RESPONSE:
+ result = pack_nr_pnf_param_response(header, ppWritePackedMsg, end, config);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_REQUEST:
+ result = pack_nr_pnf_config_request(header, ppWritePackedMsg, end, config);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_RESPONSE:
+ result = pack_nr_pnf_config_response(header, ppWritePackedMsg, end, config);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_PNF_START_REQUEST:
+ result = pack_nr_pnf_start_request(header, ppWritePackedMsg, end, config);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_PNF_START_RESPONSE:
+ result = pack_nr_pnf_start_response(header, ppWritePackedMsg, end, config);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_PNF_STOP_REQUEST:
+ result = pack_nr_pnf_stop_request(header, ppWritePackedMsg, end, config);
+ break;
+
+ case NFAPI_PNF_STOP_RESPONSE:
+ result = pack_nr_pnf_stop_response(header, ppWritePackedMsg, end, config);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST:
+ result = pack_nr_param_request(header, ppWritePackedMsg, end, config);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE:
+ result = pack_nr_param_response(header, ppWritePackedMsg, end, config);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST:
+ result = pack_nr_config_request(header, ppWritePackedMsg, end, config);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE:
+ result = pack_nr_config_response(header, ppWritePackedMsg, end, config);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_START_REQUEST:
+ result = pack_nr_start_request(header, ppWritePackedMsg, end, config);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE:
+ result = pack_nr_start_response(header, ppWritePackedMsg, end, config);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST:
+ result = pack_stop_request(header, ppWritePackedMsg, end, config);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE:
+ result = pack_stop_response(header, ppWritePackedMsg, end, config);
+ break;
+ default:
+ {
+ if(header->message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
+ header->message_id <= NFAPI_VENDOR_EXT_MSG_MAX)
+ {
+ if(config && config->pack_p4_p5_vendor_extension)
+ {
+ result = (config->pack_p4_p5_vendor_extension)(header, ppWritePackedMsg, end, config);
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve ecoder provided\n", __FUNCTION__, header->message_id);
+ }
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, header->message_id);
+ }
+ }
+ break;
+ }
+
+ return result;
+}
+
+
static uint8_t pack_p5_message_body(nfapi_p4_p5_message_header_t *header, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
{
uint8_t result = 0;
@@ -852,6 +1225,55 @@ static uint32_t get_packed_msg_len(uintptr_t msgHead, uintptr_t msgEnd)
}
// Main pack function - public
+int nfapi_nr_p5_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPackedBuf, uint32_t packedBufLen, nfapi_p4_p5_codec_config_t* config)
+{
+ nfapi_p4_p5_message_header_t *pMessageHeader = pMessageBuf;
+ uint8_t *pWritePackedMessage = pPackedBuf;
+ uint8_t *pPackMessageEnd = pPackedBuf + packedBufLen;
+ uint8_t *pPackedLengthField = &pWritePackedMessage[4];
+ uint32_t packedMsgLen;
+ uint16_t packedMsgLen16;
+
+ if (pMessageBuf == NULL || pPackedBuf == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 Pack supplied pointers are null\n");
+ return -1;
+ }
+
+ // pack the message
+ if(push16(pMessageHeader->phy_id, &pWritePackedMessage, pPackMessageEnd) &&
+ push16(pMessageHeader->message_id, &pWritePackedMessage, pPackMessageEnd) &&
+ push16(0, &pWritePackedMessage, pPackMessageEnd) &&
+ push16(pMessageHeader->spare, &pWritePackedMessage, pPackMessageEnd) &&
+ pack_nr_p5_message_body(pMessageHeader, &pWritePackedMessage, pPackMessageEnd, config))
+ {
+ // check for a valid message length
+ packedMsgLen = get_packed_msg_len((uintptr_t)pPackedBuf, (uintptr_t)pWritePackedMessage);
+ if (packedMsgLen > 0xFFFF || packedMsgLen > packedBufLen)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message length error %d, buffer supplied %d\n", packedMsgLen, packedBufLen);
+ return -1;
+ }
+ else
+ {
+ packedMsgLen16 = (uint16_t)packedMsgLen;
+ }
+
+ // Update the message length in the header
+ if(!push16(packedMsgLen16, &pPackedLengthField, pPackMessageEnd))
+ return -1;
+
+ // return the packed length
+ return (packedMsgLen);
+ }
+ else
+ {
+ // Failed to pack the meassage
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 Failed to pack message\n");
+ return -1;
+ }
+
+}
int nfapi_p5_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPackedBuf, uint32_t packedBufLen, nfapi_p4_p5_codec_config_t* config)
{
@@ -906,6 +1328,20 @@ int nfapi_p5_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPack
// Unpack routines
+
+
+static uint8_t unpack_nr_pnf_param_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
+{
+ nfapi_nr_pnf_param_request_t *pNfapiMsg = (nfapi_nr_pnf_param_request_t*)msg;
+
+ unpack_tlv_t unpack_fns[] =
+ {
+ };
+
+ return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension));
+}
+
+
static uint8_t unpack_pnf_param_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
{
nfapi_pnf_param_request_t *pNfapiMsg = (nfapi_pnf_param_request_t*)msg;
@@ -1108,6 +1544,20 @@ static uint8_t unpack_pnf_phy_rel13_nb_iot_value(void* tlv, uint8_t **ppReadPack
unpackarray(ppReadPackedMsg, value->phy, sizeof(nfapi_pnf_phy_rel13_nb_iot_info_t), NFAPI_MAX_PNF_PHY, value->number_of_phys, end, &unpack_pnf_phy_rel13_nb_info_info));
}
+static uint8_t unpack_nr_pnf_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
+{
+ nfapi_nr_pnf_param_response_t *pNfapiMsg = (nfapi_nr_pnf_param_response_t*)msg;
+
+ unpack_tlv_t unpack_fns[] =
+ {
+ { NFAPI_PNF_PARAM_GENERAL_TAG, &pNfapiMsg->pnf_param_general, &unpack_pnf_param_general_value},
+ { NFAPI_PNF_PHY_TAG, &pNfapiMsg->pnf_phy, &unpack_pnf_phy_value},
+ };
+
+ return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
+ unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
static uint8_t unpack_pnf_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
@@ -1124,12 +1574,14 @@ static uint8_t unpack_pnf_param_response(uint8_t **ppReadPackedMsg, uint8_t *end
{ NFAPI_PNF_PHY_REL12_TAG, &pNfapiMsg->pnf_phy_rel12, &unpack_pnf_phy_rel12_value},
{ NFAPI_PNF_PHY_REL13_TAG, &pNfapiMsg->pnf_phy_rel13, &unpack_pnf_phy_rel13_value},
{ NFAPI_PNF_PHY_REL13_NB_IOT_TAG, &pNfapiMsg->pnf_phy_rel13_nb_iot, &unpack_pnf_phy_rel13_nb_iot_value},
+
};
return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
}
+
static uint8_t unpack_phy_rf_config_info(void* elem, uint8_t **ppReadPackedMsg, uint8_t *end)
{
nfapi_phy_rf_config_info_t* rf = (nfapi_phy_rf_config_info_t*)elem;
@@ -1148,6 +1600,20 @@ static uint8_t unpack_pnf_phy_rf_config_value(void* tlv, uint8_t **ppReadPackedM
unpackarray(ppReadPackedMsg, value->phy_rf_config, sizeof(nfapi_phy_rf_config_info_t), NFAPI_MAX_PHY_RF_INSTANCES, value->number_phy_rf_config_info, end, &unpack_phy_rf_config_info));
}
+static uint8_t unpack_nr_pnf_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
+{
+ nfapi_nr_pnf_config_request_t *pNfapiMsg = (nfapi_nr_pnf_config_request_t*)msg;
+
+ unpack_tlv_t unpack_fns[] =
+ {
+ { NFAPI_PNF_PHY_RF_TAG, &pNfapiMsg->pnf_phy_rf_config, &unpack_pnf_phy_rf_config_value},
+ };
+
+ return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension);
+}
+
+
+
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;
@@ -1160,6 +1626,20 @@ static uint8_t unpack_pnf_config_request(uint8_t **ppReadPackedMsg, uint8_t *end
return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension);
}
+
+static uint8_t unpack_nr_pnf_config_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
+{
+ nfapi_nr_pnf_config_response_t *pNfapiMsg = (nfapi_nr_pnf_config_response_t*)msg;
+
+ unpack_tlv_t unpack_fns[] =
+ {
+ };
+
+ return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
+ unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)));
+
+}
+
static uint8_t unpack_pnf_config_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
{
nfapi_pnf_config_response_t *pNfapiMsg = (nfapi_pnf_config_response_t*)msg;
@@ -1173,6 +1653,18 @@ static uint8_t unpack_pnf_config_response(uint8_t **ppReadPackedMsg, uint8_t *en
}
+static uint8_t unpack_nr_pnf_start_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
+{
+ nfapi_nr_pnf_start_request_t *pNfapiMsg = (nfapi_nr_pnf_start_request_t*)msg;
+
+ unpack_tlv_t unpack_fns[] =
+ {
+ };
+
+ return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension));
+}
+
+
static uint8_t unpack_pnf_start_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
{
nfapi_pnf_start_request_t *pNfapiMsg = (nfapi_pnf_start_request_t*)msg;
@@ -1184,6 +1676,7 @@ static uint8_t unpack_pnf_start_request(uint8_t **ppReadPackedMsg, uint8_t *end,
return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension));
}
+
static uint8_t unpack_pnf_start_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
{
nfapi_pnf_start_response_t *pNfapiMsg = (nfapi_pnf_start_response_t*)msg;
@@ -1196,6 +1689,19 @@ static uint8_t unpack_pnf_start_response(uint8_t **ppReadPackedMsg, uint8_t *end
unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)));
}
+static uint8_t unpack_nr_pnf_start_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
+{
+ nfapi_nr_pnf_start_response_t *pNfapiMsg = (nfapi_nr_pnf_start_response_t*)msg;
+
+ unpack_tlv_t unpack_fns[] =
+ {
+ };
+
+ return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end ) &&
+ unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)));
+}
+
+
static uint8_t unpack_pnf_stop_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
{
nfapi_pnf_stop_request_t *pNfapiMsg = (nfapi_pnf_stop_request_t*)msg;
@@ -1231,6 +1737,17 @@ static uint8_t unpack_param_request(uint8_t **ppReadPackedMsg, uint8_t *end, voi
return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension));
}
+static uint8_t unpack_nr_param_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
+{
+ nfapi_nr_param_request_scf_t *pNfapiMsg = (nfapi_nr_param_request_scf_t*)msg;
+
+ unpack_tlv_t unpack_fns[] =
+ {
+ };
+
+ return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension));
+}
+
static uint8_t unpack_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
{
nfapi_param_response_t *pNfapiMsg = (nfapi_param_response_t*)msg;
@@ -1329,6 +1846,100 @@ static uint8_t unpack_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, vo
}
+static uint8_t unpack_nr_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
+{
+ nfapi_nr_param_response_scf_t *pNfapiMsg = (nfapi_nr_param_response_scf_t*)msg;
+
+ unpack_tlv_t unpack_fns[] =
+ {
+ { NFAPI_NR_PARAM_TLV_RELEASE_CAPABILITY_TAG, &(pNfapiMsg->cell_param.release_capability), &unpack_uint16_tlv_value},
+ { NFAPI_NR_PARAM_TLV_PHY_STATE_TAG, &(pNfapiMsg->cell_param.phy_state),&unpack_uint16_tlv_value},
+ { NFAPI_NR_PARAM_TLV_SKIP_BLANK_DL_CONFIG_TAG, &(pNfapiMsg->cell_param.skip_blank_dl_config), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_SKIP_BLANK_UL_CONFIG_TAG, &(pNfapiMsg->cell_param.skip_blank_ul_config), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_NUM_CONFIG_TLVS_TO_REPORT_TAG, &(pNfapiMsg->cell_param.num_config_tlvs_to_report ), &unpack_uint16_tlv_value},
+
+ { NFAPI_NR_PARAM_TLV_CYCLIC_PREFIX_TAG, &(pNfapiMsg->carrier_param.cyclic_prefix), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_SUPPORTED_SUBCARRIER_SPACINGS_DL_TAG, &(pNfapiMsg->carrier_param.supported_subcarrier_spacings_dl), &unpack_uint16_tlv_value},
+ { NFAPI_NR_PARAM_TLV_SUPPORTED_BANDWIDTH_DL_TAG, &(pNfapiMsg->carrier_param.supported_bandwidth_dl), &unpack_uint16_tlv_value},
+ { NFAPI_NR_PARAM_TLV_SUPPORTED_SUBCARRIER_SPACINGS_UL_TAG, &(pNfapiMsg->carrier_param.supported_subcarrier_spacings_ul), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_SUPPORTED_BANDWIDTH_UL_TAG, &(pNfapiMsg->carrier_param.supported_bandwidth_ul), &unpack_uint16_tlv_value},
+
+
+ { NFAPI_NR_PARAM_TLV_CCE_MAPPING_TYPE_TAG, &(pNfapiMsg->pdcch_param.cce_mapping_type), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_CORESET_OUTSIDE_FIRST_3_OFDM_SYMS_OF_SLOT_TAG, &(pNfapiMsg->pdcch_param.coreset_outside_first_3_of_ofdm_syms_of_slot), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_PRECODER_GRANULARITY_CORESET_TAG, &(pNfapiMsg->pdcch_param.coreset_precoder_granularity_coreset), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_PDCCH_MU_MIMO_TAG, &(pNfapiMsg->pdcch_param.pdcch_mu_mimo), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_PDCCH_PRECODER_CYCLING_TAG, &(pNfapiMsg->pdcch_param.pdcch_precoder_cycling), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_MAX_PDCCHS_PER_SLOT_TAG, &(pNfapiMsg->pdcch_param.max_pdcch_per_slot), &unpack_uint8_tlv_value},
+
+ { NFAPI_NR_PARAM_TLV_PUCCH_FORMATS_TAG, &(pNfapiMsg->pucch_param.pucch_formats), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_MAX_PUCCHS_PER_SLOT_TAG, &(pNfapiMsg->pucch_param.max_pucchs_per_slot), &unpack_uint8_tlv_value},
+
+ { NFAPI_NR_PARAM_TLV_PDSCH_MAPPING_TYPE_TAG, &(pNfapiMsg->pdsch_param.pdsch_mapping_type), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_PDSCH_ALLOCATION_TYPES_TAG, &(pNfapiMsg->pdsch_param.pdsch_allocation_types), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_PDSCH_VRB_TO_PRB_MAPPING_TAG, &(pNfapiMsg->pdsch_param.pdsch_vrb_to_prb_mapping), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_PDSCH_CBG_TAG, &(pNfapiMsg->pdsch_param.pdsch_cbg), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_PDSCH_DMRS_CONFIG_TYPES_TAG, &(pNfapiMsg->pdsch_param.pdsch_dmrs_config_types), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_PDSCH_DMRS_MAX_LENGTH_TAG, &(pNfapiMsg->pdsch_param.pdsch_dmrs_max_length), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_PDSCH_DMRS_ADDITIONAL_POS_TAG, &(pNfapiMsg->pdsch_param.pdsch_dmrs_additional_pos), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_MAX_PDSCH_S_YBS_PER_SLOT_TAG, &(pNfapiMsg->pdsch_param.max_pdsch_tbs_per_slot), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_MAX_NUMBER_MIMO_LAYERS_PDSCH_TAG, &(pNfapiMsg->pdsch_param.max_number_mimo_layers_pdsch), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_MAX_MU_MIMO_USERS_DL_TAG, &(pNfapiMsg->pdsch_param.max_mu_mimo_users_dl), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_PDSCH_DATA_IN_DMRS_SYMBOLS_TAG, &(pNfapiMsg->pdsch_param.pdsch_data_in_dmrs_symbols), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_PREMPTION_SUPPORT_TAG, &(pNfapiMsg->pdsch_param.premption_support), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_PDSCH_NON_SLOT_SUPPORT_TAG, &(pNfapiMsg->pdsch_param.pdsch_non_slot_support), &unpack_uint8_tlv_value},
+
+ { NFAPI_NR_PARAM_TLV_UCI_MUX_ULSCH_IN_PUSCH_TAG, &(pNfapiMsg->pusch_param.uci_mux_ulsch_in_pusch), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_UCI_ONLY_PUSCH_TAG, &(pNfapiMsg->pusch_param.uci_only_pusch), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_PUSCH_FREQUENCY_HOPPING_TAG, &(pNfapiMsg->pusch_param.pusch_frequency_hopping), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_PUSCH_DMRS_CONFIG_TYPES_TAG, &(pNfapiMsg->pusch_param.pusch_dmrs_config_types), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_PUSCH_DMRS_MAX_LEN_TAG, &(pNfapiMsg->pusch_param.pusch_dmrs_max_len), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_PUSCH_DMRS_ADDITIONAL_POS_TAG, &(pNfapiMsg->pusch_param.pusch_dmrs_additional_pos), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_PUSCH_CBG_TAG, &(pNfapiMsg->pusch_param.pusch_cbg), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_PUSCH_MAPPING_TYPE_TAG, &(pNfapiMsg->pusch_param.pusch_mapping_type), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_PUSCH_ALLOCATION_TYPES_TAG, &(pNfapiMsg->pusch_param.pusch_allocation_types), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_PUSCH_VRB_TO_PRB_MAPPING_TAG, &(pNfapiMsg->pusch_param.pusch_vrb_to_prb_mapping), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_PUSCH_MAX_PTRS_PORTS_TAG, &(pNfapiMsg->pusch_param.pusch_max_ptrs_ports), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_MAX_PDUSCHS_TBS_PER_SLOT_TAG, &(pNfapiMsg->pusch_param.max_pduschs_tbs_per_slot), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_MAX_NUMBER_MIMO_LAYERS_NON_CB_PUSCH_TAG, &(pNfapiMsg->pusch_param.max_number_mimo_layers_non_cb_pusch), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_SUPPORTED_MODULATION_ORDER_UL_TAG, &(pNfapiMsg->pusch_param.supported_modulation_order_ul), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_MAX_MU_MIMO_USERS_UL_TAG, &(pNfapiMsg->pusch_param.max_mu_mimo_users_ul), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_DFTS_OFDM_SUPPORT_TAG, &(pNfapiMsg->pusch_param.dfts_ofdm_support), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_PUSCH_AGGREGATION_FACTOR_TAG, &(pNfapiMsg->pusch_param.pusch_aggregation_factor), &unpack_uint8_tlv_value},
+
+ { NFAPI_NR_PARAM_TLV_PRACH_LONG_FORMATS_TAG, &(pNfapiMsg->prach_param.prach_long_formats), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_PRACH_SHORT_FORMATS_TAG, &(pNfapiMsg->prach_param.prach_short_formats), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_PRACH_RESTRICTED_SETS_TAG, &(pNfapiMsg->prach_param.prach_restricted_sets), &unpack_uint8_tlv_value},
+ { NFAPI_NR_PARAM_TLV_MAX_PRACH_FD_OCCASIONS_IN_A_SLOT_TAG, &(pNfapiMsg->prach_param.max_prach_fd_occasions_in_a_slot), &unpack_uint8_tlv_value},
+
+ { NFAPI_NR_PARAM_TLV_RSSI_MEASUREMENT_SUPPORT_TAG, &(pNfapiMsg->measurement_param.rssi_measurement_support), &unpack_uint8_tlv_value},
+ //config
+ { NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, &pNfapiMsg->nfapi_config.p7_vnf_address_ipv4, &unpack_ipv4_address_value},
+ { NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, &pNfapiMsg->nfapi_config.p7_vnf_address_ipv6, &unpack_ipv6_address_value},
+ { NFAPI_NR_NFAPI_P7_VNF_PORT_TAG, &pNfapiMsg->nfapi_config.p7_vnf_port, &unpack_uint16_tlv_value},
+ { NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV4_TAG, &pNfapiMsg->nfapi_config.p7_pnf_address_ipv4, &unpack_ipv4_address_value},
+ { NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV6_TAG, &pNfapiMsg->nfapi_config.p7_pnf_address_ipv6, &unpack_ipv6_address_value},
+ { NFAPI_NR_NFAPI_P7_PNF_PORT_TAG, &pNfapiMsg->nfapi_config.p7_pnf_port, &unpack_uint16_tlv_value},
+ { NFAPI_NR_NFAPI_TIMING_WINDOW_TAG, &pNfapiMsg->nfapi_config.timing_window, &unpack_uint8_tlv_value},
+ { NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG, &pNfapiMsg->nfapi_config.timing_info_mode, &unpack_uint8_tlv_value},
+ { NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG, &pNfapiMsg->nfapi_config.timing_info_period, &unpack_uint8_tlv_value},
+ };
+ // print ppReadPackedMsg
+ uint8_t *ptr = *ppReadPackedMsg;
+ printf("\n Read message unpack_param_response: ");
+ while(ptr < end){
+ printf(" %d ", *ptr);
+ ptr++;
+ }
+ printf("\n");
+
+
+ return ( pull8(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
+ 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_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
{
nfapi_config_request_t *pNfapiMsg = (nfapi_config_request_t*)msg;
@@ -1454,6 +2065,66 @@ 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;
+
+ pNfapiMsg->tdd_table.max_tdd_periodicity_list = (nfapi_nr_max_tdd_periodicity_t*) malloc(20*sizeof(nfapi_nr_max_tdd_periodicity_t));
+ for(int i=0;i<40;i++)
+ pNfapiMsg->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list = (nfapi_nr_max_num_of_symbol_per_slot_t*) malloc(14*sizeof(nfapi_nr_max_num_of_symbol_per_slot_t));
+
+ pNfapiMsg->prach_config.num_prach_fd_occasions_list=(nfapi_nr_num_prach_fd_occasions_t *) malloc(sizeof(nfapi_nr_num_prach_fd_occasions_t));
+
+ unpack_tlv_t unpack_fns[] =
+ {
+ { NFAPI_NR_CONFIG_DL_BANDWIDTH_TAG, &(pNfapiMsg->carrier_config.dl_bandwidth), &unpack_uint16_tlv_value},
+ { NFAPI_NR_CONFIG_DL_FREQUENCY_TAG, &(pNfapiMsg->carrier_config.dl_frequency), &unpack_uint32_tlv_value},
+ { NFAPI_NR_CONFIG_DL_GRID_SIZE_TAG, &(pNfapiMsg->carrier_config.dl_grid_size[1]), &unpack_uint16_tlv_value},
+ { NFAPI_NR_CONFIG_DL_K0_TAG, &(pNfapiMsg->carrier_config.dl_k0[1]), &unpack_uint16_tlv_value},
+ { NFAPI_NR_CONFIG_NUM_RX_ANT_TAG, &(pNfapiMsg->carrier_config.num_rx_ant), &unpack_uint16_tlv_value},
+ { NFAPI_NR_CONFIG_NUM_TX_ANT_TAG, &(pNfapiMsg->carrier_config.num_tx_ant), &unpack_uint16_tlv_value},
+ { NFAPI_NR_CONFIG_UL_GRID_SIZE_TAG, &(pNfapiMsg->carrier_config.ul_grid_size[1]), &unpack_uint16_tlv_value},
+ { NFAPI_NR_CONFIG_UL_K0_TAG, &(pNfapiMsg->carrier_config.ul_k0[1]), &unpack_uint16_tlv_value},
+ { NFAPI_NR_CONFIG_UPLINK_BANDWIDTH_TAG, &(pNfapiMsg->carrier_config.uplink_bandwidth), &unpack_uint16_tlv_value},
+ { NFAPI_NR_CONFIG_UPLINK_FREQUENCY_TAG, &(pNfapiMsg->carrier_config.uplink_frequency), &unpack_uint32_tlv_value},
+ { NFAPI_NR_CONFIG_FRAME_DUPLEX_TYPE_TAG, &(pNfapiMsg->cell_config.frame_duplex_type), &unpack_uint8_tlv_value},
+ { NFAPI_NR_CONFIG_PHY_CELL_ID_TAG, &(pNfapiMsg->cell_config.phy_cell_id), &unpack_uint8_tlv_value},
+ { NFAPI_NR_CONFIG_NUM_PRACH_FD_OCCASIONS_TAG, &(pNfapiMsg->prach_config.num_prach_fd_occasions), &unpack_uint8_tlv_value},
+ { NFAPI_NR_CONFIG_PRACH_SEQUENCE_LENGTH_TAG, &(pNfapiMsg->prach_config.prach_sequence_length), &unpack_uint8_tlv_value},
+ { NFAPI_NR_CONFIG_RESTRICTED_SET_CONFIG_TAG, &(pNfapiMsg->prach_config.restricted_set_config), &unpack_uint8_tlv_value},
+ { NFAPI_NR_CONFIG_SSB_PER_RACH_TAG, &(pNfapiMsg->prach_config.ssb_per_rach), &unpack_uint8_tlv_value},
+ { NFAPI_NR_CONFIG_PRACH_SUB_C_SPACING_TAG, &(pNfapiMsg->prach_config.prach_sub_c_spacing), &unpack_uint8_tlv_value},
+ { NFAPI_NR_CONFIG_PRACH_ROOT_SEQUENCE_INDEX_TAG, &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].prach_root_sequence_index), &unpack_uint16_tlv_value},
+ { NFAPI_NR_CONFIG_K1_TAG, &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].k1), &unpack_uint16_tlv_value},
+ { NFAPI_NR_CONFIG_PRACH_ZERO_CORR_CONF_TAG, &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].prach_zero_corr_conf), &unpack_uint8_tlv_value},
+ { NFAPI_NR_CONFIG_NUM_ROOT_SEQUENCES_TAG, &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].num_root_sequences), &unpack_uint8_tlv_value},
+
+ { NFAPI_NR_CONFIG_SCS_COMMON_TAG, &(pNfapiMsg->ssb_config.scs_common), &unpack_uint8_tlv_value},
+ { NFAPI_NR_CONFIG_SS_PBCH_POWER_TAG, &(pNfapiMsg->ssb_config.ss_pbch_power), &unpack_uint32_tlv_value},
+ { NFAPI_NR_CONFIG_BETA_PSS_TAG, &(pNfapiMsg->ssb_table.beta_pss), &unpack_uint8_tlv_value},
+ { NFAPI_NR_CONFIG_MIB_TAG, &(pNfapiMsg->ssb_table.MIB), &unpack_uint32_tlv_value},
+ { NFAPI_NR_CONFIG_SSB_MASK_TAG, &(pNfapiMsg->ssb_table.ssb_mask_list[0].ssb_mask), &unpack_uint32_tlv_value},
+ { NFAPI_NR_CONFIG_SSB_MASK_TAG, &(pNfapiMsg->ssb_table.ssb_mask_list[1].ssb_mask), &unpack_uint32_tlv_value},
+
+ { NFAPI_NR_CONFIG_SSB_OFFSET_POINT_A_TAG, &(pNfapiMsg->ssb_table.ssb_offset_point_a), &unpack_uint16_tlv_value},
+ { NFAPI_NR_CONFIG_SSB_PERIOD_TAG, &(pNfapiMsg->ssb_table.ssb_period), &unpack_uint8_tlv_value},
+ { NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG, &(pNfapiMsg->ssb_table.ssb_subcarrier_offset), &unpack_uint8_tlv_value},
+ { NFAPI_NR_CONFIG_TDD_PERIOD_TAG, &(pNfapiMsg->tdd_table.tdd_period), &unpack_uint8_tlv_value},
+ { NFAPI_NR_CONFIG_SLOT_CONFIG_TAG, &(pNfapiMsg->tdd_table.max_tdd_periodicity_list[0].max_num_of_symbol_per_slot_list[0].slot_config), &unpack_uint8_tlv_value},
+ { NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv4), &unpack_ipv4_address_value},
+ { NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_address_ipv6), &unpack_ipv6_address_value},
+ { NFAPI_NR_NFAPI_P7_PNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_pnf_port), &unpack_uint16_tlv_value},
+ { NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4), &unpack_ipv4_address_value},
+ { NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv6), &unpack_ipv6_address_value},
+ { NFAPI_NR_NFAPI_P7_VNF_PORT_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_port), &unpack_uint16_tlv_value},
+ { NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG, &(pNfapiMsg->nfapi_config.timing_info_mode), &unpack_uint8_tlv_value},
+ { NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG, &(pNfapiMsg->nfapi_config.timing_info_period), &unpack_uint8_tlv_value},
+ { NFAPI_NR_NFAPI_TIMING_WINDOW_TAG, &(pNfapiMsg->nfapi_config.timing_window), &unpack_uint8_tlv_value},
+ };
+ 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)
@@ -1468,9 +2139,32 @@ static uint8_t unpack_config_response(uint8_t **ppReadPackedMsg, uint8_t *end, v
unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)));
}
+static uint8_t unpack_nr_config_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
+{
+ nfapi_nr_config_response_scf_t *pNfapiMsg = (nfapi_nr_config_response_scf_t*)msg;
+
+ unpack_tlv_t unpack_fns[] =
+ {
+ };
+
+ return ( pull8(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
+ unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)));
+}
+
+static uint8_t unpack_nr_start_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
+{
+ nfapi_nr_start_request_scf_t *pNfapiMsg = ( nfapi_nr_start_request_scf_t*)msg;
+
+ unpack_tlv_t unpack_fns[] =
+ {
+ };
+
+ return unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension));
+}
+
static uint8_t unpack_start_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
{
- nfapi_start_request_t *pNfapiMsg = (nfapi_start_request_t*)msg;
+ nfapi_start_request_t *pNfapiMsg = ( nfapi_start_request_t*)msg;
unpack_tlv_t unpack_fns[] =
{
@@ -1492,6 +2186,19 @@ static uint8_t unpack_start_response(uint8_t **ppReadPackedMsg, uint8_t *end, vo
}
+static uint8_t unpack_nr_start_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
+{
+ nfapi_nr_start_response_scf_t *pNfapiMsg = (nfapi_nr_start_response_scf_t*)msg;
+
+ unpack_tlv_t unpack_fns[] =
+ {
+ };
+
+ return ( pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) &&
+ unpack_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &(pNfapiMsg->vendor_extension)));
+
+}
+
static uint8_t unpack_stop_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t* config)
{
nfapi_stop_request_t *pNfapiMsg = (nfapi_stop_request_t*)msg;
@@ -1557,6 +2264,100 @@ static uint8_t unpack_measurement_response(uint8_t **ppReadPackedMsg, uint8_t *e
// unpack length check
+static int check_nr_unpack_length(nfapi_nr_phy_msg_type_e msgId, uint32_t unpackedBufLen)
+{
+ int retLen = 0;
+
+ switch (msgId)
+ {
+ case NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_REQUEST:
+ if (unpackedBufLen >= sizeof(nfapi_pnf_param_request_t))
+ retLen = sizeof(nfapi_pnf_param_request_t);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_RESPONSE:
+ if (unpackedBufLen >= sizeof(nfapi_nr_pnf_param_response_t))
+ retLen = sizeof(nfapi_nr_pnf_param_response_t);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_REQUEST:
+ if (unpackedBufLen >= sizeof(nfapi_nr_pnf_config_request_t))
+ retLen = sizeof(nfapi_nr_pnf_config_request_t);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_RESPONSE:
+ if (unpackedBufLen >= sizeof(nfapi_nr_pnf_config_response_t))
+ retLen = sizeof(nfapi_nr_pnf_config_response_t);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_PNF_START_REQUEST:
+ if (unpackedBufLen >= sizeof(nfapi_nr_pnf_start_request_t))
+ retLen = sizeof(nfapi_nr_pnf_start_request_t);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_PNF_START_RESPONSE:
+ if (unpackedBufLen >= sizeof(nfapi_nr_pnf_start_response_t))
+ retLen = sizeof(nfapi_nr_pnf_start_response_t);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_PNF_STOP_REQUEST:
+ if (unpackedBufLen >= sizeof(nfapi_nr_pnf_stop_request_t))
+ retLen = sizeof(nfapi_nr_pnf_stop_request_t);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_PNF_STOP_RESPONSE:
+ if (unpackedBufLen >= sizeof(nfapi_nr_pnf_stop_response_t))
+ retLen = sizeof(nfapi_nr_pnf_stop_response_t);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST:
+ if (unpackedBufLen >= sizeof(nfapi_nr_param_request_scf_t))
+ retLen = sizeof(nfapi_nr_param_request_scf_t);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE:
+ if (unpackedBufLen >= sizeof(nfapi_nr_param_response_scf_t))
+ retLen = sizeof(nfapi_nr_param_response_scf_t);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST:
+ if (unpackedBufLen >= sizeof(nfapi_nr_config_request_scf_t))
+ retLen = sizeof(nfapi_nr_config_request_scf_t);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE:
+ if (unpackedBufLen >= sizeof(nfapi_nr_config_response_scf_t))
+ retLen = sizeof(nfapi_nr_config_response_scf_t);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_START_REQUEST:
+ if (unpackedBufLen >= sizeof( nfapi_nr_start_request_scf_t))
+ retLen = sizeof( nfapi_nr_start_request_scf_t);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE:
+ if (unpackedBufLen >= sizeof(nfapi_nr_start_response_scf_t))
+ retLen = sizeof(nfapi_nr_start_response_scf_t);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST:
+ if (unpackedBufLen >= sizeof(nfapi_stop_request_t))
+ retLen = sizeof(nfapi_stop_request_t);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE:
+ if (unpackedBufLen >= sizeof(nfapi_stop_response_t))
+ retLen = sizeof(nfapi_stop_response_t);
+ break;
+ default:
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s Unknown message ID %d\n", __FUNCTION__, msgId);
+ break;
+ }
+
+ return retLen;
+}
+
+
static int check_unpack_length(nfapi_message_id_e msgId, uint32_t unpackedBufLen)
{
int retLen = 0;
@@ -1624,8 +2425,8 @@ static int check_unpack_length(nfapi_message_id_e msgId, uint32_t unpackedBufLen
break;
case NFAPI_START_REQUEST:
- if (unpackedBufLen >= sizeof(nfapi_start_request_t))
- retLen = sizeof(nfapi_start_request_t);
+ if (unpackedBufLen >= sizeof( nfapi_start_request_t))
+ retLen = sizeof( nfapi_start_request_t);
break;
case NFAPI_START_RESPONSE:
@@ -1690,6 +2491,152 @@ int nfapi_p5_message_header_unpack(void *pMessageBuf, uint32_t messageBufLen, vo
}
+int nfapi_nr_p5_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p4_p5_codec_config_t* config)
+{
+ nfapi_p4_p5_message_header_t *pMessageHeader = pUnpackedBuf;
+ uint8_t *pReadPackedMessage = pMessageBuf;
+ uint8_t *end = pMessageBuf + messageBufLen;
+
+ if (pMessageBuf == NULL || pUnpackedBuf == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 unpack supplied pointers are null\n");
+ return -1;
+ }
+
+ if (messageBufLen < NFAPI_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p4_p5_message_header_t))
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen);
+ return -1;
+ }
+
+ uint8_t *ptr = pReadPackedMessage;
+ printf("\n Read message unpack: ");
+ while(ptr < end){
+ printf(" %d ", *ptr);
+ ptr++;
+ }
+ printf("\n");
+
+ // clean the supplied buffer for - tag value blanking
+ (void)memset(pUnpackedBuf, 0, unpackedBufLen);
+
+ // process the header
+ if( !(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end ) &&
+ pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) &&
+ pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) &&
+ pull16(&pReadPackedMessage, &pMessageHeader->spare, end)))
+ {
+ // failed to read the header
+ return -1;
+ }
+
+ int result = -1;
+
+
+ if(check_nr_unpack_length(pMessageHeader->message_id, unpackedBufLen) == 0)
+ {
+ // the unpack buffer is not big enough for the struct
+ return -1;
+ }
+
+ // look for the specific message
+ switch (pMessageHeader->message_id)
+ {
+ case NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_REQUEST:
+ result = unpack_nr_pnf_param_request(&pReadPackedMessage, end, pMessageHeader, config);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_RESPONSE:
+ result = unpack_nr_pnf_param_response(&pReadPackedMessage, end, pMessageHeader, config);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_REQUEST:
+ result = unpack_nr_pnf_config_request(&pReadPackedMessage, end, pMessageHeader, config);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_RESPONSE:
+ result = unpack_nr_pnf_config_response(&pReadPackedMessage, end, pMessageHeader, config);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_PNF_START_REQUEST:
+ result = unpack_nr_pnf_start_request(&pReadPackedMessage, end, pMessageHeader, config);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_PNF_START_RESPONSE:
+ result = unpack_nr_pnf_start_response(&pReadPackedMessage, end, pMessageHeader, config);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_PNF_STOP_REQUEST:
+ result = unpack_pnf_stop_request(&pReadPackedMessage, end, pMessageHeader, config);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_PNF_STOP_RESPONSE:
+ result = unpack_pnf_stop_response(&pReadPackedMessage, end, pMessageHeader, config);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST:
+ result = unpack_nr_param_request(&pReadPackedMessage, end, pMessageHeader, config);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE:
+ result = unpack_nr_param_response(&pReadPackedMessage, end, pMessageHeader, config);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST:
+ result = unpack_nr_config_request(&pReadPackedMessage, end, pMessageHeader, config);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE:
+ result = unpack_nr_config_response(&pReadPackedMessage, end, pMessageHeader, config);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_START_REQUEST:
+ result = unpack_nr_start_request(&pReadPackedMessage, end, pMessageHeader, config);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE:
+ result = unpack_nr_start_response(&pReadPackedMessage, end, pMessageHeader, config);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST:
+ result = unpack_stop_request(&pReadPackedMessage, end, pMessageHeader, config);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE:
+ result = unpack_stop_response(&pReadPackedMessage, end, pMessageHeader, config);
+ break;
+
+ case NFAPI_MEASUREMENT_REQUEST:
+ result = unpack_measurement_request(&pReadPackedMessage, end, pMessageHeader, config);
+ break;
+
+ case NFAPI_MEASUREMENT_RESPONSE:
+ result = unpack_measurement_response(&pReadPackedMessage, end, pMessageHeader, config);
+ break;
+
+ default:
+ if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
+ pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX)
+ {
+ if(config && config->unpack_p4_p5_vendor_extension)
+ {
+ result = (config->unpack_p4_p5_vendor_extension)(pMessageHeader, &pReadPackedMessage, end, config);
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve decoder provided\n", __FUNCTION__, pMessageHeader->message_id);
+ }
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown P5 message ID %d\n", __FUNCTION__, pMessageHeader->message_id);
+ }
+ break;
+ }
+
+ return result;
+}
+
int nfapi_p5_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p4_p5_codec_config_t* config)
{
nfapi_p4_p5_message_header_t *pMessageHeader = pUnpackedBuf;
@@ -1708,6 +2655,14 @@ int nfapi_p5_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
return -1;
}
+ uint8_t *ptr = pReadPackedMessage;
+ printf("\n Read message unpack: ");
+ while(ptr < end){
+ printf(" %d ", *ptr);
+ ptr++;
+ }
+ printf("\n");
+
// clean the supplied buffer for - tag value blanking
(void)memset(pUnpackedBuf, 0, unpackedBufLen);
diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c
index be9205d035..837f33fe6f 100755
--- a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c
+++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c
@@ -36,6 +36,7 @@
#include
#include
#include
+#include "nfapi_nr_interface_scf.h"
extern int nfapi_unpack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t **ppReadPackedMsg, void* user_data);
extern int nfapi_pack_p7_vendor_extension(nfapi_p7_message_header_t* header, uint8_t **ppWritePackedMsg, void* user_data);
@@ -81,19 +82,19 @@ void* nfapi_p7_allocate(size_t size, nfapi_p7_codec_config_t* config)
if(size == 0)
return 0;
- void* buffer_p = NULL;
+ void* buffer_p = NULL;
if(config && config->allocate)
{
- buffer_p = (config->allocate)(size);
- if(buffer_p != NULL){
- memset(buffer_p,0,size);
- }
- return buffer_p;
+ buffer_p = (config->allocate)(size);
+ if(buffer_p != NULL){
+ memset(buffer_p,0,size);
+ }
+ return buffer_p;
}
else
{
- buffer_p = calloc(1, size);
- return buffer_p;
+ buffer_p = calloc(1, size);
+ return buffer_p;
}
}
@@ -226,6 +227,155 @@ static uint8_t pack_tpm_value(nfapi_dl_config_dci_dl_tpm_t* value, uint8_t **ppW
}
+
+static uint8_t pack_dl_tti_csi_rs_pdu_rel15_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+ nfapi_nr_dl_tti_csi_rs_pdu_rel15_t* value = (nfapi_nr_dl_tti_csi_rs_pdu_rel15_t*)tlv;
+
+ return(
+ push16(value->bwp_size, ppWritePackedMsg, end) &&
+ push16(value->bwp_start, ppWritePackedMsg, end) &&
+
+ push8(value->subcarrier_spacing, ppWritePackedMsg, end) &&
+ push8(value->cyclic_prefix, ppWritePackedMsg, end) &&
+
+ push16(value->start_rb, ppWritePackedMsg, end) &&
+ push16(value->nr_of_rbs, ppWritePackedMsg, end) &&
+
+ push8(value->csi_type, ppWritePackedMsg, end) &&
+ push8(value->row, ppWritePackedMsg, end) &&
+
+ push16(value->freq_domain, ppWritePackedMsg, end) &&
+ push8(value->symb_l0, ppWritePackedMsg, end) &&
+
+ push8(value->symb_l1, ppWritePackedMsg, end) &&
+ push8(value->cdm_type, ppWritePackedMsg, end) &&
+
+ push8(value->freq_density, ppWritePackedMsg, end) &&
+ push16(value->scramb_id, ppWritePackedMsg, end) &&
+
+ push8(value->power_control_offset, ppWritePackedMsg, end) &&
+ push8(value->power_control_offset_ss, ppWritePackedMsg, end)
+ );
+
+}
+
+
+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) &&
+ push16(value->dci_pdu[i].ScramblingId, ppWritePackedMsg, end) &&
+
+ push16(value->dci_pdu[i].ScramblingRNTI, ppWritePackedMsg, end) &&
+ push8(value->dci_pdu[i].CceIndex, ppWritePackedMsg, end) &&
+ push8(value->dci_pdu[i].AggregationLevel, ppWritePackedMsg, end) &&
+ push8(value->dci_pdu[i].beta_PDCCH_1_0, ppWritePackedMsg, end) &&
+
+ push8(value->dci_pdu[i].powerControlOffsetSS, ppWritePackedMsg, end) &&
+ push16(value->dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end) &&
+ pusharray8(value->dci_pdu[i].Payload, DCI_PAYLOAD_BYTE_LEN, value->dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end));
+
+ return 0;
+ }
+
+ // TODO: resolve the packaging of array (currently sending a single element)
+ return(
+ push16(value->BWPSize, ppWritePackedMsg, end) &&
+ push16(value->BWPStart, ppWritePackedMsg, end) &&
+ push8(value->SubcarrierSpacing, ppWritePackedMsg, end) &&
+ push8(value->CyclicPrefix, ppWritePackedMsg, end) &&
+
+ push8(value->StartSymbolIndex, ppWritePackedMsg, end) &&
+ push8(value->DurationSymbols, ppWritePackedMsg, end) &&
+ pusharray8(value->FreqDomainResource, 6, 6, ppWritePackedMsg, end) &&
+ push8(value->CceRegMappingType, ppWritePackedMsg, end) &&
+
+ push8(value->RegBundleSize, ppWritePackedMsg, end) &&
+ push8(value->InterleaverSize, ppWritePackedMsg, end) &&
+ push8(value->CoreSetType, ppWritePackedMsg, end) &&
+ push16(value->ShiftIndex, ppWritePackedMsg, end) &&
+
+ push8(value->precoderGranularity, ppWritePackedMsg, end) &&
+ push16(value->numDlDci, ppWritePackedMsg, end));
+
+}
+
+
+static uint8_t pack_dl_tti_pdsch_pdu_rel15_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+ nfapi_nr_dl_tti_pdsch_pdu_rel15_t* value = (nfapi_nr_dl_tti_pdsch_pdu_rel15_t*)tlv;
+
+ // TODO: resolve the packaging of array (currently sending a single element)
+ return(
+ push16(value->pduBitmap, ppWritePackedMsg, end) &&
+ push16(value->rnti, ppWritePackedMsg, end) &&
+ push16(value->pduIndex, ppWritePackedMsg, end) &&
+ push16(value->BWPSize, ppWritePackedMsg, end) &&
+
+ push16(value->BWPStart, ppWritePackedMsg, end) &&
+ push8(value->SubcarrierSpacing, ppWritePackedMsg, end) &&
+ push8(value->CyclicPrefix, ppWritePackedMsg, end) &&
+ push8(value->NrOfCodewords, ppWritePackedMsg, end) &&
+
+ pusharray16(value->targetCodeRate, 2, 1, ppWritePackedMsg, end) &&
+ pusharray8(value->qamModOrder, 2, 1, ppWritePackedMsg, end) &&
+ pusharray8(value->mcsIndex, 2, 1, ppWritePackedMsg, end) &&
+ pusharray8(value->mcsTable, 2, 1, ppWritePackedMsg, end) &&
+
+ pusharray8(value->rvIndex, 2, 1, ppWritePackedMsg, end) &&
+ pusharray32(value->TBSize, 2, 1, ppWritePackedMsg, end) &&
+ push16(value->dataScramblingId, ppWritePackedMsg, end) &&
+ push8(value->nrOfLayers, ppWritePackedMsg, end) &&
+
+ push8(value->transmissionScheme, ppWritePackedMsg, end) &&
+ push8(value->refPoint, ppWritePackedMsg, end) &&
+ push16(value->dlDmrsSymbPos, ppWritePackedMsg, end) &&
+ push8(value->dmrsConfigType, ppWritePackedMsg, end) &&
+
+ push16(value->dlDmrsScramblingId, ppWritePackedMsg, end) &&
+ push8(value->SCID, ppWritePackedMsg, end) &&
+ push8(value->numDmrsCdmGrpsNoData, ppWritePackedMsg, end) &&
+ push16(value->dmrsPorts, ppWritePackedMsg, end) &&
+
+ push8(value->resourceAlloc, ppWritePackedMsg, end) &&
+ push16(value->rbStart, ppWritePackedMsg, end) &&
+ push16(value->rbSize, ppWritePackedMsg, end) &&
+
+ push8(value->VRBtoPRBMapping, ppWritePackedMsg, end) &&
+ push8(value->StartSymbolIndex, ppWritePackedMsg, end) &&
+ push8(value->NrOfSymbols, ppWritePackedMsg, end) &&
+ push8(value->PTRSPortIndex, ppWritePackedMsg, end) &&
+
+ push8(value->PTRSTimeDensity, ppWritePackedMsg, end) &&
+ push8(value->PTRSFreqDensity, ppWritePackedMsg, end) &&
+ push8(value->PTRSReOffset, ppWritePackedMsg, end)
+ );
+
+}
+
+
+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
+ );
+
+}
+
+
static uint8_t pack_dl_config_dci_dl_pdu_rel13_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
{
nfapi_dl_config_dci_dl_pdu_rel13_t* value = (nfapi_dl_config_dci_dl_pdu_rel13_t*)tlv;
@@ -552,6 +702,55 @@ static uint8_t pack_dl_config_ndlsch_pdu_rel13_value(void* tlv, uint8_t **ppWrit
push8(value->nrs_antenna_ports_assumed_by_the_ue, ppWritePackedMsg, end));
}
+
+static uint8_t pack_dl_tti_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+ nfapi_nr_dl_tti_request_pdu_t* value = (nfapi_nr_dl_tti_request_pdu_t*)tlv;
+
+ if(!(push16(value->PDUSize, ppWritePackedMsg, end) &&
+ push16(value->PDUType, ppWritePackedMsg, end) ))
+ return 0;
+
+
+ // first match the pdu type, then call the respective function
+ switch(value->PDUType)
+ {
+ case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE:
+ {
+ if(!(pack_dl_tti_csi_rs_pdu_rel15_value(&value->csi_rs_pdu.csi_rs_pdu_rel15,ppWritePackedMsg,end)))
+ return 0;
+ }
+ break;
+
+ case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE:
+ {
+ if(!(pack_dl_tti_pdcch_pdu_rel15_value(&value->pdcch_pdu.pdcch_pdu_rel15,ppWritePackedMsg,end)))
+ return 0;
+ }
+ break;
+ case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE:
+ {
+ if(!(pack_dl_tti_pdsch_pdu_rel15_value(&value->pdsch_pdu.pdsch_pdu_rel15,ppWritePackedMsg,end)))
+ return 0;
+ }
+ break;
+ case NFAPI_NR_DL_TTI_SSB_PDU_TYPE:
+ {
+ if(!(pack_dl_tti_ssb_pdu_rel15_value(&value->ssb_pdu.ssb_pdu_rel15,ppWritePackedMsg,end)))
+ return 0;
+ }
+ break;
+
+ default:
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid DL_TTI pdu type %d \n", value->PDUType );
+ }
+ break;
+ }
+
+ return 1;
+}
+
static uint8_t pack_dl_config_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
{
nfapi_dl_config_request_body_t* value = (nfapi_dl_config_request_body_t*)tlv;
@@ -697,6 +896,41 @@ static uint8_t pack_dl_config_request_body_value(void* tlv, uint8_t **ppWritePac
return 1;
}
+
+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;
+
+ 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.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;
+}
+
+
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;
@@ -718,6 +952,9 @@ static uint8_t pack_dl_config_request(void *msg, uint8_t **ppWritePackedMsg, uin
}
}
+
+
+
static uint8_t pack_ul_config_request_ulsch_rel8_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t * end)
{
nfapi_ul_config_ulsch_pdu_rel8_t* ulsch_pdu_rel8 = (nfapi_ul_config_ulsch_pdu_rel8_t*)tlv;
@@ -772,6 +1009,196 @@ static uint8_t pack_ul_config_request_ulsch_rel13_value(void *tlv, uint8_t **ppW
push8(ulsch_pdu_rel13->empty_symbols_due_to_re_tunning, ppWritePackedMsg, end));
}
+//Pack fns for ul_tti PDUS
+
+
+static uint8_t pack_ul_tti_request_prach_pdu(nfapi_nr_prach_pdu_t* prach_pdu, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+ return(
+ push16(prach_pdu->phys_cell_id, ppWritePackedMsg, end) &&
+ push8(prach_pdu->num_prach_ocas, ppWritePackedMsg, end) &&
+ push8(prach_pdu->prach_format, ppWritePackedMsg, end) &&
+ push8(prach_pdu->num_ra, ppWritePackedMsg, end) &&
+ push8(prach_pdu->prach_start_symbol, ppWritePackedMsg, end) &&
+ push16(prach_pdu->num_cs, ppWritePackedMsg, end)
+ // TODO: ignoring beamforming tlv for now
+ );
+
+}
+
+static uint8_t pack_ul_tti_request_pucch_pdu(nfapi_nr_pucch_pdu_t* pucch_pdu, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+ return(
+ push16(pucch_pdu->rnti, ppWritePackedMsg, end) &&
+ push32(pucch_pdu->handle, ppWritePackedMsg, end) &&
+ push16(pucch_pdu->bwp_size, ppWritePackedMsg, end) &&
+ push16(pucch_pdu->bwp_start, ppWritePackedMsg, end) &&
+ push8(pucch_pdu->subcarrier_spacing, ppWritePackedMsg, end) &&
+ push8(pucch_pdu->cyclic_prefix, ppWritePackedMsg, end) &&
+ push8(pucch_pdu->format_type, ppWritePackedMsg, end) &&
+ push8(pucch_pdu->multi_slot_tx_indicator, ppWritePackedMsg, end) &&
+ push16(pucch_pdu->prb_start, ppWritePackedMsg, end) &&
+ push16(pucch_pdu->prb_size, ppWritePackedMsg, end) &&
+ push8(pucch_pdu->start_symbol_index, ppWritePackedMsg, end) &&
+ push8(pucch_pdu->nr_of_symbols, ppWritePackedMsg, end) &&
+ push8(pucch_pdu->freq_hop_flag, ppWritePackedMsg, end) &&
+ push16(pucch_pdu->second_hop_prb, ppWritePackedMsg, end) &&
+ push8(pucch_pdu->group_hop_flag, ppWritePackedMsg, end) &&
+ push8(pucch_pdu->sequence_hop_flag, ppWritePackedMsg, end) &&
+ push16(pucch_pdu->hopping_id, ppWritePackedMsg, end) &&
+ push16(pucch_pdu->initial_cyclic_shift, ppWritePackedMsg, end) &&
+ push16(pucch_pdu->data_scrambling_id, ppWritePackedMsg, end) &&
+ push8(pucch_pdu->time_domain_occ_idx, ppWritePackedMsg, end) &&
+ push8(pucch_pdu->pre_dft_occ_idx, ppWritePackedMsg, end) &&
+ push8(pucch_pdu->pre_dft_occ_len, ppWritePackedMsg, end) &&
+ push8(pucch_pdu->add_dmrs_flag, ppWritePackedMsg, end) &&
+ push16(pucch_pdu->dmrs_scrambling_id, ppWritePackedMsg, end) &&
+ push8(pucch_pdu->dmrs_cyclic_shift, ppWritePackedMsg, end) &&
+ push8(pucch_pdu->sr_flag, ppWritePackedMsg, end) &&
+ push8(pucch_pdu->bit_len_harq, ppWritePackedMsg, end) &&
+ push16(pucch_pdu->bit_len_csi_part1, ppWritePackedMsg, end) &&
+ push16(pucch_pdu->bit_len_csi_part2, ppWritePackedMsg, end)
+ // TODO: ignoring beamforming tlv for now
+ );
+
+}
+
+
+static uint8_t pack_ul_tti_request_pusch_pdu(nfapi_nr_pusch_pdu_t* pusch_pdu, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+
+ if (!(
+ push16(pusch_pdu->pdu_bit_map, ppWritePackedMsg, end) &&
+ push16(pusch_pdu->rnti, ppWritePackedMsg, end) &&
+ push32(pusch_pdu->handle, ppWritePackedMsg, end) &&
+ push16(pusch_pdu->bwp_size, ppWritePackedMsg, end) &&
+ push16(pusch_pdu->bwp_start, ppWritePackedMsg, end) &&
+ push8(pusch_pdu->subcarrier_spacing, ppWritePackedMsg, end) &&
+ push8(pusch_pdu->cyclic_prefix, ppWritePackedMsg, end) &&
+ push16(pusch_pdu->target_code_rate, ppWritePackedMsg, end) &&
+ push8(pusch_pdu->qam_mod_order, ppWritePackedMsg, end) &&
+ push8(pusch_pdu->mcs_index, ppWritePackedMsg, end) &&
+ push8(pusch_pdu->mcs_table, ppWritePackedMsg, end) &&
+ push8(pusch_pdu->transform_precoding, ppWritePackedMsg, end) &&
+ push16(pusch_pdu->data_scrambling_id, ppWritePackedMsg, end) &&
+ push8(pusch_pdu->nrOfLayers, ppWritePackedMsg, end) &&
+ push16(pusch_pdu->ul_dmrs_symb_pos, ppWritePackedMsg, end) &&
+ push8(pusch_pdu->dmrs_config_type, ppWritePackedMsg, end) &&
+ push16(pusch_pdu->ul_dmrs_scrambling_id, ppWritePackedMsg, end) &&
+ push8(pusch_pdu->scid, ppWritePackedMsg, end) &&
+ push8(pusch_pdu->num_dmrs_cdm_grps_no_data, ppWritePackedMsg, end) &&
+ push16(pusch_pdu->dmrs_ports, ppWritePackedMsg, end) &&
+ push8(pusch_pdu->resource_alloc, ppWritePackedMsg, end) &&
+ push8(pusch_pdu->resource_alloc,ppWritePackedMsg, end) &&
+ push16(pusch_pdu->dmrs_ports, ppWritePackedMsg, end) &&
+ push16(pusch_pdu->rb_start, ppWritePackedMsg, end) &&
+ push16(pusch_pdu->rb_size, ppWritePackedMsg, end) &&
+ push8(pusch_pdu->vrb_to_prb_mapping, ppWritePackedMsg, end) &&
+ push8(pusch_pdu->frequency_hopping, ppWritePackedMsg, end) &&
+ push16(pusch_pdu->tx_direct_current_location, ppWritePackedMsg, end) &&
+ push8(pusch_pdu->uplink_frequency_shift_7p5khz, ppWritePackedMsg, end) &&
+ push8(pusch_pdu->start_symbol_index, ppWritePackedMsg, end) &&
+ push8(pusch_pdu->nr_of_symbols, ppWritePackedMsg, end)
+ // TODO: ignoring beamforming tlv for now
+ ))
+ return 0;
+
+
+ //Pack Optional Data only included if indicated in pduBitmap
+ switch(pusch_pdu->pdu_bit_map){
+ case PUSCH_PDU_BITMAP_PUSCH_DATA:
+ {
+ // pack optional TLVs
+ return(
+ push8(pusch_pdu->pusch_data.rv_index, ppWritePackedMsg, end) &&
+ push8(pusch_pdu->pusch_data.harq_process_id, ppWritePackedMsg, end) &&
+ push32(pusch_pdu->pusch_data.tb_size, ppWritePackedMsg, end) &&
+ push16(pusch_pdu->pusch_data.num_cb, ppWritePackedMsg, end) &&
+ pusharray8(pusch_pdu->pusch_data.cb_present_and_position,1,1,ppWritePackedMsg, end)
+ );
+ }
+ break;
+
+ case PUSCH_PDU_BITMAP_PUSCH_UCI:
+ {
+ return(
+ push16(pusch_pdu->pusch_uci.harq_ack_bit_length, ppWritePackedMsg, end) &&
+ push16(pusch_pdu->pusch_uci.csi_part1_bit_length, ppWritePackedMsg, end) &&
+ push16(pusch_pdu->pusch_uci.csi_part2_bit_length, ppWritePackedMsg, end) &&
+ push8(pusch_pdu->pusch_uci.alpha_scaling, ppWritePackedMsg, end) &&
+ push8(pusch_pdu->pusch_uci.beta_offset_harq_ack, ppWritePackedMsg, end) &&
+ push8(pusch_pdu->pusch_uci.beta_offset_csi1, ppWritePackedMsg, end) &&
+ push8(pusch_pdu->pusch_uci.beta_offset_csi2, ppWritePackedMsg, end)
+ );
+ }
+ break;
+
+ case PUSCH_PDU_BITMAP_PUSCH_PTRS:
+ {
+ return(
+ push8(pusch_pdu->pusch_ptrs.num_ptrs_ports, ppWritePackedMsg, end) &&
+ push8(pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_dmrs_port, ppWritePackedMsg, end) &&
+ push16(pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_port_index, ppWritePackedMsg, end) &&
+ push8(pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_re_offset, ppWritePackedMsg, end) &&
+ push8(pusch_pdu->pusch_ptrs.ptrs_time_density, ppWritePackedMsg, end) &&
+ push8(pusch_pdu->pusch_ptrs.ptrs_freq_density, ppWritePackedMsg, end) &&
+ push8(pusch_pdu->pusch_ptrs.ul_ptrs_power, ppWritePackedMsg, end)
+ );
+ }
+ break;
+
+ case PUSCH_PDU_BITMAP_DFTS_OFDM:
+ {
+ return(
+ push8(pusch_pdu->dfts_ofdm.low_papr_group_number, ppWritePackedMsg, end) &&
+ push16(pusch_pdu->dfts_ofdm.low_papr_sequence_number, ppWritePackedMsg, end) &&
+ push8(pusch_pdu->dfts_ofdm.ul_ptrs_sample_density, ppWritePackedMsg, end) &&
+ push8(pusch_pdu->dfts_ofdm.ul_ptrs_time_density_transform_precoding, ppWritePackedMsg, end)
+ );
+ }
+ break;
+
+ default:
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "Invalid pdu bitmap %d \n", pusch_pdu->pdu_bit_map );
+ }
+ }
+
+ return 1;
+}
+
+static uint8_t pack_ul_tti_request_srs_pdu(nfapi_nr_srs_pdu_t* srs_pdu, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+ return(
+ push16(srs_pdu->rnti, ppWritePackedMsg, end) &&
+ push32(srs_pdu->handle, ppWritePackedMsg, end) &&
+ push16(srs_pdu->bwp_size, ppWritePackedMsg, end) &&
+ push16(srs_pdu->bwp_start, ppWritePackedMsg, end) &&
+ push8(srs_pdu->subcarrier_spacing, ppWritePackedMsg, end) &&
+ push8(srs_pdu->cyclic_prefix, ppWritePackedMsg, end) &&
+ push8(srs_pdu->num_ant_ports, ppWritePackedMsg, end) &&
+ push8(srs_pdu->num_symbols, ppWritePackedMsg, end) &&
+ push8(srs_pdu->num_repetitions, ppWritePackedMsg, end) &&
+ push8(srs_pdu->time_start_position, ppWritePackedMsg, end) &&
+ push8(srs_pdu->config_index, ppWritePackedMsg, end) &&
+ push16(srs_pdu->sequence_id, ppWritePackedMsg, end) &&
+ push8(srs_pdu->bandwidth_index, ppWritePackedMsg, end) &&
+ push8(srs_pdu->comb_size, ppWritePackedMsg, end) &&
+ push8(srs_pdu->comb_offset, ppWritePackedMsg, end) &&
+ push8(srs_pdu->cyclic_shift, ppWritePackedMsg, end) &&
+ push8(srs_pdu->frequency_position, ppWritePackedMsg, end) &&
+ push8(srs_pdu->frequency_shift, ppWritePackedMsg, end) &&
+ push8(srs_pdu->frequency_hopping, ppWritePackedMsg, end) &&
+ push8(srs_pdu->group_or_sequence_hopping, ppWritePackedMsg, end) &&
+ push8(srs_pdu->resource_type, ppWritePackedMsg, end) &&
+ push16(srs_pdu->t_srs, ppWritePackedMsg, end) &&
+ push16(srs_pdu->t_offset, ppWritePackedMsg, end)
+
+ // TODO: ignoring beamforming tlv for now
+ );
+
+}
+
static uint8_t pack_ul_config_request_ulsch_pdu(nfapi_ul_config_ulsch_pdu* ulsch_pdu, uint8_t **ppWritePackedMsg, uint8_t *end)
{
return ( pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG, &ulsch_pdu->ulsch_pdu_rel8, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_rel8_value) &&
@@ -1124,6 +1551,70 @@ static uint8_t pack_ul_config_request_nrach_pdu_rel13_value(void *tlv, uint8_t *
}
+
+
+static uint8_t pack_ul_tti_pdu_list_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+ nfapi_nr_ul_tti_request_number_of_pdus_t* value = (nfapi_nr_ul_tti_request_number_of_pdus_t*)tlv;
+
+ if(!(push16(value->pdu_size, ppWritePackedMsg, end) &&
+ push16(value->pdu_type, ppWritePackedMsg, end) ))
+ return 0;
+
+
+ // first match the pdu type, then call the respective function
+ switch(value->pdu_type)
+ {
+ case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE:
+ {
+ if(!pack_ul_tti_request_prach_pdu(&value->prach_pdu, ppWritePackedMsg, end))
+ return 0;
+ }
+ break;
+
+ case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE:
+ {
+ if(!pack_ul_tti_request_pucch_pdu(&value->pucch_pdu, ppWritePackedMsg, end))
+ return 0;
+ }
+ break;
+ case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE:
+ {
+ if(!pack_ul_tti_request_pusch_pdu(&value->pusch_pdu, ppWritePackedMsg, end))
+ return 0;
+ }
+ break;
+ case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE:
+ {
+ if(!pack_ul_tti_request_srs_pdu(&value->srs_pdu, ppWritePackedMsg, end))
+ return 0;
+ }
+ break;
+
+ default:
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid UL_TTI pdu type %d \n", value->pdu_type );
+ }
+ break;
+ }
+
+ return 1;
+}
+
+static uint8_t pack_ul_tti_groups_list_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+ nfapi_nr_ul_tti_request_number_of_groups_t* value = (nfapi_nr_ul_tti_request_number_of_groups_t*)tlv;
+
+ if(!push8(value->n_ue, ppWritePackedMsg, end))
+ return 0;
+ for(int i=0; in_ue;i++)
+ {
+ if(!push8(value->ue_list[i].pdu_idx, ppWritePackedMsg, end))
+ return 0;
+ }
+ return 1;
+}
+
static uint8_t pack_ul_config_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
{
nfapi_ul_config_request_body_t* value = (nfapi_ul_config_request_body_t*)tlv;
@@ -1298,6 +1789,37 @@ static uint8_t pack_ul_config_request_body_value(void* tlv, uint8_t **ppWritePac
return 1;
}
+
+static uint8_t pack_ul_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
+{
+ nfapi_nr_ul_tti_request_t *pNfapiMsg = (nfapi_nr_ul_tti_request_t*)msg;
+
+ if (!(push16(pNfapiMsg->SFN , ppWritePackedMsg, end) &&
+ push16(pNfapiMsg->Slot , ppWritePackedMsg, end) &&
+ push8(pNfapiMsg->n_pdus , ppWritePackedMsg, end) &&
+ push8(pNfapiMsg->rach_present, ppWritePackedMsg, end) &&
+ push8(pNfapiMsg->n_ulsch, ppWritePackedMsg, end) &&
+ push8(pNfapiMsg->n_ulcch, ppWritePackedMsg, end) &&
+ push8(pNfapiMsg->n_group, ppWritePackedMsg, end) ))
+ return 0;
+
+ for(int i=0; in_pdus; i++)
+ {
+ if(!pack_ul_tti_pdu_list_value(&pNfapiMsg->pdus_list[i], ppWritePackedMsg, end))
+ return 0;
+ }
+
+ for(int i=0; in_group; i++)
+ {
+ if(!pack_ul_tti_groups_list_value(&pNfapiMsg->groups_list[i], ppWritePackedMsg, end))
+ return 0;
+
+ }
+
+ return 1;
+}
+
+
static uint8_t pack_ul_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
{
nfapi_ul_config_request_t *pNfapiMsg = (nfapi_ul_config_request_t*)msg;
@@ -1517,6 +2039,69 @@ static uint8_t pack_hi_dci0_request_body_value(void *tlv, uint8_t **ppWritePacke
return 1;
}
+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) &&
+ push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].ScramblingId, ppWritePackedMsg, end) &&
+
+ push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].ScramblingRNTI, ppWritePackedMsg, end) &&
+ push8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].CceIndex, ppWritePackedMsg, end) &&
+ push8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].AggregationLevel, ppWritePackedMsg, end) &&
+ push8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].beta_PDCCH_1_0, ppWritePackedMsg, end) &&
+
+ 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, DCI_PAYLOAD_BYTE_LEN, value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end));
+
+ return 0;
+ }
+
+ return (push16(value->PDUType, ppWritePackedMsg, end) &&
+ push16(value->PDUSize, ppWritePackedMsg, end) &&
+ push16(value->pdcch_pdu.pdcch_pdu_rel15.BWPSize, ppWritePackedMsg, end) &&
+ push16(value->pdcch_pdu.pdcch_pdu_rel15.BWPStart, ppWritePackedMsg, end) &&
+ push8(value->pdcch_pdu.pdcch_pdu_rel15.SubcarrierSpacing, ppWritePackedMsg, end) &&
+ push8(value->pdcch_pdu.pdcch_pdu_rel15.CyclicPrefix, ppWritePackedMsg, end) &&
+
+ push8(value->pdcch_pdu.pdcch_pdu_rel15.StartSymbolIndex, ppWritePackedMsg, end) &&
+ push8(value->pdcch_pdu.pdcch_pdu_rel15.DurationSymbols, ppWritePackedMsg, end) &&
+ pusharray8(value->pdcch_pdu.pdcch_pdu_rel15.FreqDomainResource, 6, 6, ppWritePackedMsg, end) &&
+ push8(value->pdcch_pdu.pdcch_pdu_rel15.CceRegMappingType, ppWritePackedMsg, end) &&
+
+ push8(value->pdcch_pdu.pdcch_pdu_rel15.RegBundleSize, ppWritePackedMsg, end) &&
+ push8(value->pdcch_pdu.pdcch_pdu_rel15.InterleaverSize, ppWritePackedMsg, end) &&
+ push8(value->pdcch_pdu.pdcch_pdu_rel15.CoreSetType, ppWritePackedMsg, end) &&
+ push16(value->pdcch_pdu.pdcch_pdu_rel15.ShiftIndex, ppWritePackedMsg, end));
+
+}
+
+static uint8_t pack_ul_dci_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
+{
+ nfapi_nr_ul_dci_request_t *pNfapiMsg = (nfapi_nr_ul_dci_request_t*)msg;
+
+ if (!(push16(pNfapiMsg->SFN, ppWritePackedMsg, end) &&
+ push16(pNfapiMsg->Slot, ppWritePackedMsg, end) &&
+ push8(pNfapiMsg->numPdus, ppWritePackedMsg, end)
+ ))
+ return 0;
+
+ for(int i=0; inumPdus; i++)
+ {
+ if(!pack_ul_dci_pdu_list_value(&pNfapiMsg->ul_dci_pdu_list[i], ppWritePackedMsg, end))
+ return 0;
+ }
+ return 1;
+
+
+}
+
+
+
static uint8_t pack_hi_dci0_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
{
nfapi_hi_dci0_request_t *pNfapiMsg = (nfapi_hi_dci0_request_t*)msg;
@@ -1526,6 +2111,55 @@ static uint8_t pack_hi_dci0_request(void *msg, uint8_t **ppWritePackedMsg, uint8
pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
}
+//pack_tx_data_pdu_list_value
+static uint8_t pack_tx_data_pdu_list_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+ nfapi_nr_pdu_t* value = (nfapi_nr_pdu_t*)tlv;
+
+ if(!(push32(value->num_TLV, ppWritePackedMsg, end) &&
+ push16(value->PDU_index, ppWritePackedMsg, end) &&
+ push16(value->PDU_length, ppWritePackedMsg, end)
+ ))
+ return 0;
+
+ uint16_t i = 0;
+ uint16_t total_number_of_tlvs = value->num_TLV;
+ for(; i < total_number_of_tlvs; ++i)
+ {
+
+ if (!(push16(value->TLVs[i].length, ppWritePackedMsg, end) &&
+ push16(value->TLVs[i].tag, ppWritePackedMsg, end)))
+ return 0;
+
+ switch(value->TLVs[i].tag)
+ {
+ case 0:
+ {
+ if(!pusharray32(value->TLVs[i].value.direct, 16384, value->TLVs[i].length, ppWritePackedMsg, end))
+ return 0;
+ break;
+
+ }
+
+ case 1:
+ {
+ if(!pusharray32(value->TLVs[i].value.ptr, value->TLVs[i].length , value->TLVs[i].length, ppWritePackedMsg, end))
+ return 0;
+ break;
+
+ }
+
+ default:
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid tag value %d \n", value->TLVs[i].tag );
+ break;
+ }
+
+ }
+ }
+ return 1;
+}
+
static uint8_t pack_tx_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
{
nfapi_tx_request_body_t* value = (nfapi_tx_request_body_t*)tlv;
@@ -1551,7 +2185,7 @@ static uint8_t pack_tx_request_body_value(void* tlv, uint8_t **ppWritePackedMsg,
// DJP - if(pusharray8(pdu->segments[j].segment_data, (uint32_t)(-1), pdu->segments[j].segment_length, ppWritePackedMsg, end) == 0)
int push_ret = pusharray8(pdu->segments[j].segment_data, 65535, pdu->segments[j].segment_length, ppWritePackedMsg, end);
- if (pdu->segments[j].segment_length == 3)
+ if (pdu->segments[j].segment_length == 3)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() BCH? segment_data:%x %x %x\n", __FUNCTION__,
pdu->segments[j].segment_data[0],
@@ -1571,6 +2205,26 @@ static uint8_t pack_tx_request_body_value(void* tlv, uint8_t **ppWritePackedMsg,
return 1;
}
+static uint8_t pack_tx_data_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
+{
+ nfapi_nr_tx_data_request_t *pNfapiMsg = (nfapi_nr_tx_data_request_t*)msg;
+
+ if (!(
+ push16(pNfapiMsg->SFN, ppWritePackedMsg, end) &&
+ push16(pNfapiMsg->Slot, ppWritePackedMsg, end) &&
+ push16(pNfapiMsg->Number_of_PDUs, ppWritePackedMsg, end)
+ ))
+ return 0;
+
+ for(int i=0; iNumber_of_PDUs; i++)
+ {
+ if(!pack_tx_data_pdu_list_value(&pNfapiMsg->pdu_list[i], ppWritePackedMsg, end))
+ return 0;
+ }
+
+ return 1;
+}
+
static uint8_t pack_tx_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
{
nfapi_tx_request_t *pNfapiMsg = (nfapi_tx_request_t*)msg;
@@ -1583,43 +2237,43 @@ static uint8_t pack_tx_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *e
return x && y && z;
}
-
-static uint8_t pack_release_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
- nfapi_ue_release_request_body_t* value = (nfapi_ue_release_request_body_t*)tlv;
- if(push16(value->number_of_TLVs, ppWritePackedMsg, end) == 0){
- return 0;
- }
-
- uint8_t j;
- uint16_t num = value->number_of_TLVs;
- for(j = 0; j < num; ++j){
- if(push16(value->ue_release_request_TLVs_list[j].rnti, ppWritePackedMsg, end) == 0){
- return 0;
- }
- }
- return 1;
-}
-
-static uint8_t pack_ue_release_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
- nfapi_ue_release_request_t *pNfapiMsg = (nfapi_ue_release_request_t*)msg;
- int x = push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end);
- int y = pack_tlv(NFAPI_UE_RELEASE_BODY_TAG, &pNfapiMsg->ue_release_request_body, ppWritePackedMsg, end, &pack_release_request_body_value);
- int z = pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config);
- return x && y && z;
-}
-
-static uint8_t pack_ue_release_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
-{
-
- nfapi_ue_release_response_t *pNfapiMsg = (nfapi_ue_release_response_t*)msg;
-
- int x = push32(pNfapiMsg->error_code, ppWritePackedMsg, end);
- int z = pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config);
- return x && z;
-}
-
+
+static uint8_t pack_release_request_body_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+ nfapi_ue_release_request_body_t* value = (nfapi_ue_release_request_body_t*)tlv;
+ if(push16(value->number_of_TLVs, ppWritePackedMsg, end) == 0){
+ return 0;
+ }
+
+ uint8_t j;
+ uint16_t num = value->number_of_TLVs;
+ for(j = 0; j < num; ++j){
+ if(push16(value->ue_release_request_TLVs_list[j].rnti, ppWritePackedMsg, end) == 0){
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static uint8_t pack_ue_release_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
+{
+ nfapi_ue_release_request_t *pNfapiMsg = (nfapi_ue_release_request_t*)msg;
+ int x = push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end);
+ int y = pack_tlv(NFAPI_UE_RELEASE_BODY_TAG, &pNfapiMsg->ue_release_request_body, ppWritePackedMsg, end, &pack_release_request_body_value);
+ int z = pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config);
+ return x && y && z;
+}
+
+static uint8_t pack_ue_release_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
+{
+
+ nfapi_ue_release_response_t *pNfapiMsg = (nfapi_ue_release_response_t*)msg;
+
+ int x = push32(pNfapiMsg->error_code, ppWritePackedMsg, end);
+ int z = pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config);
+ return x && z;
+}
+
static uint8_t pack_rx_ue_information_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
{
nfapi_rx_ue_information* value = (nfapi_rx_ue_information*)tlv;
@@ -2614,6 +3268,15 @@ static uint8_t pack_nrach_indication(void *msg, uint8_t **ppWritePackedMsg, uint
pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
}
+static uint8_t pack_nr_dl_node_sync(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
+{
+ nfapi_nr_dl_node_sync_t *pNfapiMsg = (nfapi_nr_dl_node_sync_t*)msg;
+
+ return ( push32(pNfapiMsg->t1, ppWritePackedMsg, end) &&
+ pushs32(pNfapiMsg->delta_sfn_slot, ppWritePackedMsg, end) &&
+ pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
static uint8_t pack_dl_node_sync(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
{
nfapi_dl_node_sync_t *pNfapiMsg = (nfapi_dl_node_sync_t*)msg;
@@ -2623,6 +3286,16 @@ static uint8_t pack_dl_node_sync(void *msg, uint8_t **ppWritePackedMsg, uint8_t
pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
}
+static uint8_t pack_nr_ul_node_sync(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
+{
+ nfapi_nr_ul_node_sync_t *pNfapiMsg = (nfapi_nr_ul_node_sync_t*)msg;
+
+ return (push32(pNfapiMsg->t1, ppWritePackedMsg, end) &&
+ push32(pNfapiMsg->t2, ppWritePackedMsg, end) &&
+ push32(pNfapiMsg->t3, ppWritePackedMsg, end) &&
+ pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
static uint8_t pack_ul_node_sync(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
{
nfapi_ul_node_sync_t *pNfapiMsg = (nfapi_ul_node_sync_t*)msg;
@@ -2636,7 +3309,7 @@ static uint8_t pack_ul_node_sync(void *msg, uint8_t **ppWritePackedMsg, uint8_t
static uint8_t pack_timing_info(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
{
nfapi_timing_info_t *pNfapiMsg = (nfapi_timing_info_t*)msg;
-
+
return (push32(pNfapiMsg->last_sfn_sf, ppWritePackedMsg, end) &&
push32(pNfapiMsg->time_since_last_timing_info, ppWritePackedMsg, end) &&
push32(pNfapiMsg->dl_config_jitter, ppWritePackedMsg, end) &&
@@ -2654,9 +3327,211 @@ static uint8_t pack_timing_info(void *msg, uint8_t **ppWritePackedMsg, uint8_t *
pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
}
+static uint8_t pack_nr_timing_info(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
+{
+ nfapi_nr_timing_info_t *pNfapiMsg = (nfapi_nr_timing_info_t*)msg;
+
+ return (push32(pNfapiMsg->last_sfn, ppWritePackedMsg, end) &&
+ push32(pNfapiMsg->last_slot, ppWritePackedMsg, end) &&
+ push32(pNfapiMsg->time_since_last_timing_info, ppWritePackedMsg, end) &&
+ push32(pNfapiMsg->dl_tti_jitter, ppWritePackedMsg, end) &&
+ push32(pNfapiMsg->tx_data_request_jitter, ppWritePackedMsg, end) &&
+ push32(pNfapiMsg->ul_tti_jitter, ppWritePackedMsg, end) &&
+ push32(pNfapiMsg->ul_dci_jitter, ppWritePackedMsg, end) &&
+ pushs32(pNfapiMsg->dl_tti_latest_delay, ppWritePackedMsg, end) &&
+ pushs32(pNfapiMsg->tx_data_request_latest_delay, ppWritePackedMsg, end) &&
+ pushs32(pNfapiMsg->ul_tti_latest_delay, ppWritePackedMsg, end) &&
+ pushs32(pNfapiMsg->ul_dci_latest_delay, ppWritePackedMsg, end) &&
+ pushs32(pNfapiMsg->dl_tti_earliest_arrival, ppWritePackedMsg, end) &&
+ pushs32(pNfapiMsg->tx_data_request_earliest_arrival, ppWritePackedMsg, end) &&
+ pushs32(pNfapiMsg->ul_tti_earliest_arrival, ppWritePackedMsg, end) &&
+ pushs32(pNfapiMsg->ul_dci_earliest_arrival, ppWritePackedMsg, end) &&
+ pack_p7_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
+}
+
+
// Main pack function - public
+int nfapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t* config)
+{
+ nfapi_p7_message_header_t *pMessageHeader = pMessageBuf;
+ uint8_t *pWritePackedMessage = pPackedBuf;
+ uint8_t *pPackedLengthField = &pWritePackedMessage[4];
+ uint8_t *end = pPackedBuf + packedBufLen;
+
+ if (pMessageBuf == NULL || pPackedBuf == NULL)
+ {
+ 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) &&
+ push16(0/*pMessageHeader->message_length*/, &pWritePackedMessage, end) &&
+ push16(pMessageHeader->m_segment_sequence, &pWritePackedMessage, end) &&
+ push32(0/*pMessageHeader->checksum*/, &pWritePackedMessage, end) &&
+ push32(pMessageHeader->transmit_timestamp, &pWritePackedMessage, end)))
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack header failed\n");
+ return -1;
+ }
+
+ if (pMessageHeader->message_id != NFAPI_TIMING_INFO)
+ {
+ //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() message_id:0x%04x phy_id:%u m_segment_sequence:%u timestamp:%u\n", __FUNCTION__, pMessageHeader->message_id, pMessageHeader->phy_id, pMessageHeader->m_segment_sequence, pMessageHeader->transmit_timestamp);
+ }
+ // look for the specific message
+ uint8_t result = 0;
+ switch (pMessageHeader->message_id)
+ {
+ case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
+ result = pack_dl_tti_request(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
+ result = pack_ul_tti_request(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
+ case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
+ result = pack_tx_data_request(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
+ 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;
+
+ case NFAPI_UE_RELEASE_RESPONSE:
+ result =pack_ue_release_response(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
+
+ case NFAPI_HARQ_INDICATION:
+ result = pack_harq_indication(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
+
+ case NFAPI_CRC_INDICATION:
+ result = pack_crc_indication(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
+
+ case NFAPI_RX_ULSCH_INDICATION:
+ //printf("RX ULSCH\n");
+ result = pack_rx_ulsch_indication(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
+
+ case NFAPI_RACH_INDICATION:
+ result = pack_rach_indication(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
+
+ case NFAPI_SRS_INDICATION:
+ result = pack_srs_indication(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
+
+ case NFAPI_RX_SR_INDICATION:
+ result = pack_sr_indication(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
+
+ case NFAPI_RX_CQI_INDICATION:
+ result = pack_cqi_indication(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
+
+ case NFAPI_LBT_DL_CONFIG_REQUEST:
+ result = pack_lbt_dl_config_request(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
+
+ case NFAPI_LBT_DL_INDICATION:
+ result = pack_lbt_dl_indication(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
+
+ case NFAPI_NB_HARQ_INDICATION:
+ result = pack_nb_harq_indication(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
+
+ case NFAPI_NRACH_INDICATION:
+ result = pack_nrach_indication(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
+ result = pack_nr_dl_node_sync(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC:
+ result = pack_nr_ul_node_sync(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
+
+ case NFAPI_TIMING_INFO:
+ result = pack_nr_timing_info(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
+
+ default:
+ {
+ if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
+ pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX)
+ {
+ if(config && config->pack_p7_vendor_extension)
+ {
+ result = (config->pack_p7_vendor_extension)(pMessageHeader, &pWritePackedMessage, end, config);
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve ecoder provided\n", __FUNCTION__, pMessageHeader->message_id);
+ }
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, pMessageHeader->message_id);
+ }
+ }
+ break;
+ }
+
+ if(result == 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack failed to pack message\n");
+ return -1;
+ }
+
+ // check for a valid message length
+ uintptr_t msgHead = (uintptr_t)pPackedBuf;
+ uintptr_t msgEnd = (uintptr_t)pWritePackedMessage;
+ uint32_t packedMsgLen = msgEnd - msgHead;
+ uint16_t packedMsgLen16;
+ if (packedMsgLen > 0xFFFF || packedMsgLen > packedBufLen)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message length error %d, buffer supplied %d\n", packedMsgLen, packedBufLen);
+ return -1;
+ }
+ else
+ {
+ packedMsgLen16 = (uint16_t)packedMsgLen;
+ }
+
+ // Update the message length in the header
+ pMessageHeader->message_length = packedMsgLen16;
+
+ if(!push16(packedMsgLen16, &pPackedLengthField, end))
+ return -1;
+
+ if(1)
+ {
+ //quick test
+ if(pMessageHeader->message_length != packedMsgLen)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi packedMsgLen(%d) != message_length(%d) id %d\n", packedMsgLen, pMessageHeader->message_length, pMessageHeader->message_id);
+ }
+ }
+
+ return (packedMsgLen);
+}
+
int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t* config)
{
nfapi_p7_message_header_t *pMessageHeader = pMessageBuf;
@@ -2669,7 +3544,13 @@ int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBu
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) &&
@@ -2698,24 +3579,22 @@ int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBu
case NFAPI_UL_CONFIG_REQUEST:
result = pack_ul_config_request(pMessageHeader, &pWritePackedMessage, end, config);
break;
-
+ case NFAPI_TX_REQUEST:
+ //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() NFAPI_TX_REQUEST\n", __FUNCTION__);
+ result = pack_tx_request(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
case NFAPI_HI_DCI0_REQUEST:
result = pack_hi_dci0_request(pMessageHeader, &pWritePackedMessage, end, config);
break;
-
- case NFAPI_TX_REQUEST:
- //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() NFAPI_TX_REQUEST\n", __FUNCTION__);
- result = pack_tx_request(pMessageHeader, &pWritePackedMessage, end, config);
+
+ case NFAPI_UE_RELEASE_REQUEST:
+ result =pack_ue_release_request(pMessageHeader, &pWritePackedMessage, end, config);
break;
-
- case NFAPI_UE_RELEASE_REQUEST:
- result =pack_ue_release_request(pMessageHeader, &pWritePackedMessage, end, config);
- break;
-
- case NFAPI_UE_RELEASE_RESPONSE:
- result =pack_ue_release_response(pMessageHeader, &pWritePackedMessage, end, config);
- break;
-
+
+ case NFAPI_UE_RELEASE_RESPONSE:
+ result =pack_ue_release_response(pMessageHeader, &pWritePackedMessage, end, config);
+ break;
+
case NFAPI_HARQ_INDICATION:
result = pack_harq_indication(pMessageHeader, &pWritePackedMessage, end, config);
break;
@@ -2834,10 +3713,158 @@ int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBu
return (packedMsgLen);
}
-
-
// Unpack routines
+// NR:
+static uint8_t unpack_dl_tti_csi_rs_pdu_rel15_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
+{
+ nfapi_nr_dl_tti_csi_rs_pdu_rel15_t* value = (nfapi_nr_dl_tti_csi_rs_pdu_rel15_t*)tlv;
+ return(
+ pull16(ppReadPackedMsg, &value->bwp_size, end) &&
+ pull16(ppReadPackedMsg, &value->bwp_start, end) &&
+
+ pull8(ppReadPackedMsg, &value->subcarrier_spacing, end) &&
+ pull8(ppReadPackedMsg, &value->cyclic_prefix, end) &&
+
+ pull16(ppReadPackedMsg, &value->start_rb, end) &&
+ pull16(ppReadPackedMsg, &value->nr_of_rbs, end) &&
+
+ pull8(ppReadPackedMsg, &value->csi_type, end) &&
+ pull8(ppReadPackedMsg, &value->row, end) &&
+
+ pull16(ppReadPackedMsg, &value->freq_domain, end) &&
+ pull8(ppReadPackedMsg, &value->symb_l0, end) &&
+
+ pull8(ppReadPackedMsg, &value->symb_l1, end) &&
+ pull8(ppReadPackedMsg, &value->cdm_type, end) &&
+
+ pull8(ppReadPackedMsg, &value->freq_density, end) &&
+ pull16(ppReadPackedMsg, &value->scramb_id, end) &&
+
+ pull8(ppReadPackedMsg, &value->power_control_offset, end) &&
+ pull8(ppReadPackedMsg, &value->power_control_offset_ss, end)
+ );
+
+}
+
+
+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) &&
+ pull16(ppReadPackedMsg, &value->dci_pdu[i].ScramblingId, end) &&
+
+ pull16(ppReadPackedMsg, &value->dci_pdu[i].ScramblingRNTI, end) &&
+ pull8(ppReadPackedMsg, &value->dci_pdu[i].CceIndex, end) &&
+ pull8(ppReadPackedMsg, &value->dci_pdu[i].AggregationLevel, end) &&
+ pull8(ppReadPackedMsg, &value->dci_pdu[i].beta_PDCCH_1_0, end) &&
+
+ pull8(ppReadPackedMsg, &value->dci_pdu[i].powerControlOffsetSS, end) &&
+ pull16(ppReadPackedMsg, &value->dci_pdu[i].PayloadSizeBits, end) &&
+
+ pullarray8(ppReadPackedMsg, value->dci_pdu[i].Payload, DCI_PAYLOAD_BYTE_LEN, value->dci_pdu[i].PayloadSizeBits, end));
+
+ return 0;
+ }
+
+ // TODO: resolve the packaging of array (currently sending a single element)
+ return(
+ pull16(ppReadPackedMsg, &value->BWPSize, end) &&
+ pull16(ppReadPackedMsg, &value->BWPStart, end) &&
+ pull8(ppReadPackedMsg, &value->SubcarrierSpacing, end) &&
+ pull8(ppReadPackedMsg, &value->CyclicPrefix, end) &&
+
+ pull8(ppReadPackedMsg, &value->StartSymbolIndex, end) &&
+ pull8(ppReadPackedMsg, &value->DurationSymbols, end) &&
+ pullarray8(ppReadPackedMsg, value->FreqDomainResource, 6, 6, end) &&
+ pull8(ppReadPackedMsg, &value->CceRegMappingType, end) &&
+
+ pull8(ppReadPackedMsg, &value->RegBundleSize, end) &&
+ pull8(ppReadPackedMsg, &value->InterleaverSize, end) &&
+ pull8(ppReadPackedMsg, &value->CoreSetType, end) &&
+ pull16(ppReadPackedMsg, &value->ShiftIndex, end) &&
+
+ pull8(ppReadPackedMsg, &value->precoderGranularity, end) &&
+ pull16(ppReadPackedMsg, &value->numDlDci, end));
+
+}
+
+
+static uint8_t unpack_dl_tti_pdsch_pdu_rel15_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
+{
+ nfapi_nr_dl_tti_pdsch_pdu_rel15_t* value = (nfapi_nr_dl_tti_pdsch_pdu_rel15_t*)tlv;
+
+ // TODO: resolve the packaging of array (currently sending a single element)
+ return(
+ pull16(ppReadPackedMsg, &value->pduBitmap, end) &&
+ pull16(ppReadPackedMsg, &value->rnti, end) &&
+ pull16(ppReadPackedMsg, &value->pduIndex, end) &&
+ pull16(ppReadPackedMsg, &value->BWPSize, end) &&
+
+ pull16(ppReadPackedMsg, &value->BWPStart, end) &&
+ pull8(ppReadPackedMsg, &value->SubcarrierSpacing, end) &&
+ pull8(ppReadPackedMsg, &value->CyclicPrefix, end) &&
+ pull8(ppReadPackedMsg, &value->NrOfCodewords, end) &&
+
+ pullarray16(ppReadPackedMsg, value->targetCodeRate, 2, 1, end) &&
+ pullarray8(ppReadPackedMsg, value->qamModOrder, 2, 1, end) &&
+ pullarray8(ppReadPackedMsg, value->mcsIndex, 2, 1, end) &&
+ pullarray8(ppReadPackedMsg, value->mcsTable, 2, 1, end) &&
+
+ pullarray8(ppReadPackedMsg, value->rvIndex, 2, 1, end) &&
+ pullarray32(ppReadPackedMsg, value->TBSize, 2, 1, end) &&
+ pull16(ppReadPackedMsg, &value->dataScramblingId, end) &&
+ pull8(ppReadPackedMsg, &value->nrOfLayers, end) &&
+
+ pull8(ppReadPackedMsg, &value->transmissionScheme, end) &&
+ pull8(ppReadPackedMsg, &value->refPoint, end) &&
+ pull16(ppReadPackedMsg, &value->dlDmrsSymbPos, end) &&
+ pull8(ppReadPackedMsg, &value->dmrsConfigType, end) &&
+
+ pull16(ppReadPackedMsg, &value->dlDmrsScramblingId, end) &&
+ pull8(ppReadPackedMsg, &value->SCID, end) &&
+ pull8(ppReadPackedMsg, &value->numDmrsCdmGrpsNoData, end) &&
+ pull16(ppReadPackedMsg, &value->dmrsPorts, end) &&
+
+ pull8(ppReadPackedMsg, &value->resourceAlloc, end) &&
+ pull16(ppReadPackedMsg, &value->rbStart, end) &&
+ pull16(ppReadPackedMsg, &value->rbSize, end) &&
+
+ pull8(ppReadPackedMsg, &value->VRBtoPRBMapping, end) &&
+ pull8(ppReadPackedMsg, &value->StartSymbolIndex, end) &&
+ pull8(ppReadPackedMsg, &value->NrOfSymbols, end) &&
+ pull8(ppReadPackedMsg, &value->PTRSPortIndex, end) &&
+
+ pull8(ppReadPackedMsg, &value->PTRSTimeDensity, end) &&
+ pull8(ppReadPackedMsg, &value->PTRSFreqDensity, end) &&
+ pull8(ppReadPackedMsg, &value->PTRSReOffset, end)
+ );
+
+}
+
+
+static uint8_t unpack_dl_tti_ssb_pdu_rel15_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
+{
+ nfapi_nr_dl_tti_ssb_pdu_rel15_t* value = (nfapi_nr_dl_tti_ssb_pdu_rel15_t*)tlv;
+
+ return(
+ pull16(ppReadPackedMsg, &value->PhysCellId, end) &&
+ pull8(ppReadPackedMsg, &value->BetaPss, end) &&
+ pull8(ppReadPackedMsg, &value->SsbBlockIndex, end) &&
+ pull8(ppReadPackedMsg, &value->SsbSubcarrierOffset, end) &&
+ pull16(ppReadPackedMsg, &value->ssbOffsetPointA, end) &&
+ pull8(ppReadPackedMsg, &value->bchPayloadFlag, end) &&
+ pull32(ppReadPackedMsg, &value->bchPayload, end)
+ // TODO: pack precoding_and_beamforming too
+ );
+
+}
+
+
+// LTE:
static uint8_t unpack_dl_config_dci_dl_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
{
nfapi_dl_config_dci_dl_pdu_rel8_t* dci_dl_pdu_rel8 = (nfapi_dl_config_dci_dl_pdu_rel8_t*)tlv;
@@ -3279,7 +4306,58 @@ static uint8_t unpack_dl_config_ndlsch_pdu_rel13_value(void *tlv, uint8_t **ppRe
pull8(ppReadPackedMsg, &ndlsch_params_rel13->scrambling_sequence_initialization_cinit, end) &&
pull16(ppReadPackedMsg, &ndlsch_params_rel13->sf_idx, end) &&
pull8(ppReadPackedMsg, &ndlsch_params_rel13->nrs_antenna_ports_assumed_by_the_ue, end));
-}
+}
+
+
+static uint8_t unpack_dl_tti_request_body_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg)
+{
+ nfapi_nr_dl_tti_request_pdu_t* value = (nfapi_nr_dl_tti_request_pdu_t*)msg;
+
+ if(!(pull16(ppReadPackedMsg, &value->PDUSize, end) &&
+ pull16(ppReadPackedMsg, &value->PDUType, end) ))
+ return 0;
+
+
+ // first match the pdu type, then call the respective function
+ switch(value->PDUType)
+ {
+ case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE:
+ {
+ if(!(unpack_dl_tti_csi_rs_pdu_rel15_value(&value->csi_rs_pdu.csi_rs_pdu_rel15,ppReadPackedMsg,end)))
+ return 0;
+ }
+ break;
+
+ case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE:
+ {
+ if(!(unpack_dl_tti_pdcch_pdu_rel15_value(&value->pdcch_pdu.pdcch_pdu_rel15,ppReadPackedMsg,end)))
+ return 0;
+ }
+ break;
+ case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE:
+ {
+ if(!(unpack_dl_tti_pdsch_pdu_rel15_value(&value->pdsch_pdu.pdsch_pdu_rel15,ppReadPackedMsg,end)))
+ return 0;
+ }
+ break;
+ case NFAPI_NR_DL_TTI_SSB_PDU_TYPE:
+ {
+ if(!(unpack_dl_tti_ssb_pdu_rel15_value(&value->ssb_pdu.ssb_pdu_rel15,ppReadPackedMsg,end)))
+ return 0;
+ }
+ break;
+
+ default:
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid DL_TTI pdu type %d \n", value->PDUType );
+ }
+ break;
+ }
+
+ return 1;
+}
+
+
static uint8_t unpack_dl_config_request_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
@@ -3483,6 +4561,334 @@ static uint8_t unpack_dl_config_request_body_value(void *tlv, uint8_t **ppReadPa
return 1;
}
+
+static uint8_t unpack_dl_tti_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
+{
+ nfapi_nr_dl_tti_request_t *pNfapiMsg = (nfapi_nr_dl_tti_request_t*)msg;
+
+ if (!(pull16(ppReadPackedMsg,&pNfapiMsg->SFN, end) &&
+ pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end) &&
+ pull8(ppReadPackedMsg, &pNfapiMsg->dl_tti_request_body.nGroup, end) &&
+ pull8(ppReadPackedMsg, &pNfapiMsg->dl_tti_request_body.nPDUs, end) &&
+ pullarray8(ppReadPackedMsg,pNfapiMsg->dl_tti_request_body.nUe ,256,pNfapiMsg->dl_tti_request_body.nGroup, end)
+ //pusharray8(pNfapiMsg->PduIdx[0] ,256,256, ppWritePackedMsg, end)
+ ))
+ return 0;
+
+ 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(!(pullarrays32(ppReadPackedMsg,arr,12,pNfapiMsg->dl_tti_request_body.nUe[i], end)))
+ return 0;
+ }
+
+ for(int i=0;idl_tti_request_body.nPDUs;i++)
+ {
+ if(!unpack_dl_tti_request_body_value(ppReadPackedMsg, end, &pNfapiMsg->dl_tti_request_body.dl_tti_pdu_list[i]))
+ return 0;
+ }
+
+return 1;
+}
+
+
+static uint8_t unpack_ul_tti_request_prach_pdu(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
+{
+ nfapi_nr_prach_pdu_t* prach_pdu = (nfapi_nr_prach_pdu_t*)tlv;
+
+ return(
+ pull16(ppReadPackedMsg, &prach_pdu->phys_cell_id, end) &&
+ pull8(ppReadPackedMsg, &prach_pdu->num_prach_ocas, end) &&
+ pull8(ppReadPackedMsg, &prach_pdu->prach_format, end) &&
+ pull8(ppReadPackedMsg, &prach_pdu->num_ra, end) &&
+ pull8(ppReadPackedMsg, &prach_pdu->prach_start_symbol, end) &&
+ pull16(ppReadPackedMsg, &prach_pdu->num_cs, end)
+ // TODO: ignoring beamforming tlv for now
+ );
+}
+
+
+static uint8_t unpack_ul_tti_request_pucch_pdu(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
+{
+ nfapi_nr_pucch_pdu_t* pucch_pdu = (nfapi_nr_pucch_pdu_t*)tlv;
+
+ return(
+ pull16(ppReadPackedMsg, &pucch_pdu->rnti, end) &&
+ pull32(ppReadPackedMsg, &pucch_pdu->handle, end) &&
+ pull16(ppReadPackedMsg, &pucch_pdu->bwp_size, end) &&
+ pull16(ppReadPackedMsg, &pucch_pdu->bwp_start, end) &&
+ pull8(ppReadPackedMsg, &pucch_pdu->subcarrier_spacing, end) &&
+ pull8(ppReadPackedMsg, &pucch_pdu->cyclic_prefix, end) &&
+ pull8(ppReadPackedMsg, &pucch_pdu->format_type, end) &&
+ pull8(ppReadPackedMsg, &pucch_pdu->multi_slot_tx_indicator, end) &&
+ pull16(ppReadPackedMsg, &pucch_pdu->prb_start, end) &&
+ pull16(ppReadPackedMsg, &pucch_pdu->prb_size, end) &&
+ pull8(ppReadPackedMsg, &pucch_pdu->start_symbol_index, end) &&
+ pull8(ppReadPackedMsg, &pucch_pdu->nr_of_symbols, end) &&
+ pull8(ppReadPackedMsg, &pucch_pdu->freq_hop_flag, end) &&
+ pull16(ppReadPackedMsg, &pucch_pdu->second_hop_prb, end) &&
+ pull8(ppReadPackedMsg, &pucch_pdu->group_hop_flag, end) &&
+ pull8(ppReadPackedMsg, &pucch_pdu->sequence_hop_flag, end) &&
+ pull16(ppReadPackedMsg, &pucch_pdu->hopping_id, end) &&
+ pull16(ppReadPackedMsg, &pucch_pdu->initial_cyclic_shift, end) &&
+ pull16(ppReadPackedMsg, &pucch_pdu->data_scrambling_id, end) &&
+ pull8(ppReadPackedMsg, &pucch_pdu->time_domain_occ_idx, end) &&
+ pull8(ppReadPackedMsg, &pucch_pdu->pre_dft_occ_idx, end) &&
+ pull8(ppReadPackedMsg, &pucch_pdu->pre_dft_occ_len, end) &&
+ pull8(ppReadPackedMsg, &pucch_pdu->add_dmrs_flag, end) &&
+ pull16(ppReadPackedMsg, &pucch_pdu->dmrs_scrambling_id, end) &&
+ pull8(ppReadPackedMsg, &pucch_pdu->dmrs_cyclic_shift, end) &&
+ pull8(ppReadPackedMsg, &pucch_pdu->sr_flag, end) &&
+ pull8(ppReadPackedMsg, &pucch_pdu->bit_len_harq, end) &&
+ pull16(ppReadPackedMsg, &pucch_pdu->bit_len_csi_part1, end) &&
+ pull16(ppReadPackedMsg, &pucch_pdu->bit_len_csi_part2, end)
+ // TODO: ignoring beamforming tlv for now
+ );
+}
+
+
+static uint8_t unpack_ul_tti_request_pusch_pdu(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
+{
+ nfapi_nr_pusch_pdu_t* pusch_pdu = (nfapi_nr_pusch_pdu_t*)tlv;
+
+ if (!(
+ pull16(ppReadPackedMsg, &pusch_pdu->pdu_bit_map, end) &&
+ pull16(ppReadPackedMsg, &pusch_pdu->rnti, end) &&
+ pull32(ppReadPackedMsg, &pusch_pdu->handle, end) &&
+ pull16(ppReadPackedMsg, &pusch_pdu->bwp_size, end) &&
+ pull16(ppReadPackedMsg, &pusch_pdu->bwp_start, end) &&
+ pull8(ppReadPackedMsg, &pusch_pdu->subcarrier_spacing, end) &&
+ pull8(ppReadPackedMsg, &pusch_pdu->cyclic_prefix, end) &&
+ pull16(ppReadPackedMsg, &pusch_pdu->target_code_rate, end) &&
+ pull8(ppReadPackedMsg, &pusch_pdu->qam_mod_order, end) &&
+ pull8(ppReadPackedMsg, &pusch_pdu->mcs_index, end) &&
+ pull8(ppReadPackedMsg, &pusch_pdu->mcs_table, end) &&
+ pull8(ppReadPackedMsg, &pusch_pdu->transform_precoding, end) &&
+ pull16(ppReadPackedMsg, &pusch_pdu->data_scrambling_id, end) &&
+ pull8(ppReadPackedMsg, &pusch_pdu->nrOfLayers, end) &&
+ pull16(ppReadPackedMsg, &pusch_pdu->ul_dmrs_symb_pos, end) &&
+ pull8(ppReadPackedMsg, &pusch_pdu->dmrs_config_type, end) &&
+ pull16(ppReadPackedMsg, &pusch_pdu->ul_dmrs_scrambling_id, end) &&
+ pull8(ppReadPackedMsg, &pusch_pdu->scid, end) &&
+ pull8(ppReadPackedMsg, &pusch_pdu->num_dmrs_cdm_grps_no_data, end) &&
+ pull16(ppReadPackedMsg, &pusch_pdu->dmrs_ports, end) &&
+ pull8(ppReadPackedMsg, &pusch_pdu->resource_alloc, end) &&
+ pull8(ppReadPackedMsg, &pusch_pdu->resource_alloc,end) &&
+ pull16(ppReadPackedMsg, &pusch_pdu->dmrs_ports, end) &&
+ pull16(ppReadPackedMsg, &pusch_pdu->rb_start, end) &&
+ pull16(ppReadPackedMsg, &pusch_pdu->rb_size, end) &&
+ pull8(ppReadPackedMsg, &pusch_pdu->vrb_to_prb_mapping, end) &&
+ pull8(ppReadPackedMsg, &pusch_pdu->frequency_hopping, end) &&
+ pull16(ppReadPackedMsg, &pusch_pdu->tx_direct_current_location, end) &&
+ pull8(ppReadPackedMsg, &pusch_pdu->uplink_frequency_shift_7p5khz, end) &&
+ pull8(ppReadPackedMsg, &pusch_pdu->start_symbol_index, end) &&
+ pull8(ppReadPackedMsg, &pusch_pdu->nr_of_symbols, end)
+ // TODO: ignoring beamforming tlv for now
+ ))
+ return 0;
+
+
+ //Pack Optional Data only included if indicated in pduBitmap
+ switch(pusch_pdu->pdu_bit_map){
+ case PUSCH_PDU_BITMAP_PUSCH_DATA:
+ {
+ // pack optional TLVs
+ return(
+ pull8(ppReadPackedMsg, &pusch_pdu->pusch_data.rv_index, end) &&
+ pull8(ppReadPackedMsg, &pusch_pdu->pusch_data.harq_process_id, end) &&
+ pull32(ppReadPackedMsg, &pusch_pdu->pusch_data.tb_size, end) &&
+ pull16(ppReadPackedMsg, &pusch_pdu->pusch_data.num_cb, end) &&
+ pullarray8(ppReadPackedMsg, pusch_pdu->pusch_data.cb_present_and_position,1,1,end)
+ );
+ }
+ break;
+
+ case PUSCH_PDU_BITMAP_PUSCH_UCI:
+ {
+ return(
+ pull16(ppReadPackedMsg, &pusch_pdu->pusch_uci.harq_ack_bit_length, end) &&
+ pull16(ppReadPackedMsg, &pusch_pdu->pusch_uci.csi_part1_bit_length, end) &&
+ pull16(ppReadPackedMsg, &pusch_pdu->pusch_uci.csi_part2_bit_length, end) &&
+ pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.alpha_scaling, end) &&
+ pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.beta_offset_harq_ack, end) &&
+ pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.beta_offset_csi1, end) &&
+ pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.beta_offset_csi2, end)
+ );
+ }
+ break;
+
+ case PUSCH_PDU_BITMAP_PUSCH_PTRS:
+ {
+ return(
+ pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.num_ptrs_ports, end) &&
+ pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_dmrs_port, end) &&
++ pull16(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_port_index, end) &&
++ pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_re_offset, end) &&
+ pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_time_density, end) &&
+ pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_freq_density, end) &&
+ pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ul_ptrs_power, end)
+ );
+ }
+ break;
+
+ case PUSCH_PDU_BITMAP_DFTS_OFDM:
+ {
+ return(
+ pull8(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.low_papr_group_number, end) &&
+ pull16(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.low_papr_sequence_number, end) &&
+ pull8(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.ul_ptrs_sample_density, end) &&
+ pull8(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.ul_ptrs_time_density_transform_precoding, end)
+ );
+ }
+ break;
+
+ default:
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "Invalid pdu bitmap %d \n", pusch_pdu->pdu_bit_map );
+ }
+ }
+
+ return 1;
+}
+
+
+static uint8_t unpack_ul_tti_request_srs_pdu(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
+{
+ nfapi_nr_srs_pdu_t* srs_pdu = (nfapi_nr_srs_pdu_t*)tlv;
+
+ return(
+ pull16(ppReadPackedMsg, &srs_pdu->rnti, end) &&
+ pull32(ppReadPackedMsg, &srs_pdu->handle, end) &&
+ pull16(ppReadPackedMsg, &srs_pdu->bwp_size, end) &&
+ pull16(ppReadPackedMsg, &srs_pdu->bwp_start, end) &&
+ pull8(ppReadPackedMsg, &srs_pdu->subcarrier_spacing, end) &&
+ pull8(ppReadPackedMsg, &srs_pdu->cyclic_prefix, end) &&
+ pull8(ppReadPackedMsg, &srs_pdu->num_ant_ports, end) &&
+ pull8(ppReadPackedMsg, &srs_pdu->num_symbols, end) &&
+ pull8(ppReadPackedMsg, &srs_pdu->num_repetitions, end) &&
+ pull8(ppReadPackedMsg, &srs_pdu->time_start_position, end) &&
+ pull8(ppReadPackedMsg, &srs_pdu->config_index, end) &&
+ pull16(ppReadPackedMsg, &srs_pdu->sequence_id, end) &&
+ pull8(ppReadPackedMsg, &srs_pdu->bandwidth_index, end) &&
+ pull8(ppReadPackedMsg, &srs_pdu->comb_size, end) &&
+ pull8(ppReadPackedMsg, &srs_pdu->comb_offset, end) &&
+ pull8(ppReadPackedMsg, &srs_pdu->cyclic_shift, end) &&
+ pull8(ppReadPackedMsg, &srs_pdu->frequency_position, end) &&
+ pull8(ppReadPackedMsg, &srs_pdu->frequency_shift, end) &&
+ pull8(ppReadPackedMsg, &srs_pdu->frequency_hopping, end) &&
+ pull8(ppReadPackedMsg, &srs_pdu->group_or_sequence_hopping, end) &&
+ pull8(ppReadPackedMsg, &srs_pdu->resource_type, end) &&
+ pull16(ppReadPackedMsg, &srs_pdu->t_srs, end) &&
+ pull16(ppReadPackedMsg, &srs_pdu->t_offset, end)
+ // TODO: ignoring beamforming tlv for now
+ );
+}
+
+
+static uint8_t unpack_ul_tti_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg)
+{
+ nfapi_nr_ul_tti_request_number_of_pdus_t* pNfapiMsg = (nfapi_nr_ul_tti_request_number_of_pdus_t*)msg;
+
+ if(!(pull16(ppReadPackedMsg, &pNfapiMsg->pdu_size, end) &&
+ pull16(ppReadPackedMsg, &pNfapiMsg->pdu_type, end) ))
+ return 0;
+
+
+ // first natch the pdu type, then call the respective function
+ switch(pNfapiMsg->pdu_type)
+ {
+
+ case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE:
+ {
+ if(!unpack_ul_tti_request_prach_pdu(&pNfapiMsg->prach_pdu, ppReadPackedMsg, end))
+ return 0;
+ }
+ break;
+
+ case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE:
+ {
+ if(!unpack_ul_tti_request_pucch_pdu(&pNfapiMsg->pucch_pdu, ppReadPackedMsg, end))
+ return 0;
+ }
+ break;
+
+ case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE:
+ {
+ if(!unpack_ul_tti_request_pusch_pdu(&pNfapiMsg->pusch_pdu, ppReadPackedMsg, end))
+ return 0;
+ }
+ break;
+
+ case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE:
+ {
+ if(!unpack_ul_tti_request_srs_pdu(&pNfapiMsg->srs_pdu, ppReadPackedMsg, end))
+ return 0;
+ }
+ break;
+
+ default:
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid UL_TTI pdu type %d \n", pNfapiMsg->pdu_type );
+ }
+ break;
+
+
+ }
+
+ return 1;
+}
+
+
+static uint8_t unpack_ul_tti_groups_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg)
+{
+ nfapi_nr_ul_tti_request_number_of_groups_t* pNfapiMsg = (nfapi_nr_ul_tti_request_number_of_groups_t*)msg;
+
+ if(!pull8(ppReadPackedMsg, &pNfapiMsg->n_ue, end))
+ return 0;
+ for (int i = 0; i < pNfapiMsg->n_ue; i++)
+ {
+ if(!pull8(ppReadPackedMsg, &pNfapiMsg->ue_list[i].pdu_idx ,end) )
+ return 0;
+ }
+ return 1;
+}
+
+
+static uint8_t unpack_ul_tti_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
+{
+ nfapi_nr_ul_tti_request_t *pNfapiMsg = (nfapi_nr_ul_tti_request_t*)msg;
+
+ if (!(
+ pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end) &&
+ pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end) &&
+ pull8(ppReadPackedMsg, &pNfapiMsg->n_pdus, end) &&
+ pull8(ppReadPackedMsg, &pNfapiMsg->n_group, end) &&
+ pull8(ppReadPackedMsg, &pNfapiMsg->rach_present, end) &&
+ pull8(ppReadPackedMsg, &pNfapiMsg->n_ulcch, end) &&
+ pull8(ppReadPackedMsg, &pNfapiMsg->n_ulsch, end) ))
+ return 0;
+
+ for(int i=0; i< pNfapiMsg->n_pdus; i++)
+ {
+ if (!unpack_ul_tti_pdu_list_value(ppReadPackedMsg, end, &pNfapiMsg->pdus_list[i]))
+ return 0;
+ }
+
+ for(int i=0; i< pNfapiMsg->n_group; i++)
+ {
+ if (!unpack_ul_tti_groups_list_value(ppReadPackedMsg, end, &pNfapiMsg->groups_list[i]))
+ return 0;
+ }
+
+ return 1;
+}
+
+
+
static uint8_t unpack_dl_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
{
nfapi_dl_config_request_t *pNfapiMsg = (nfapi_dl_config_request_t*)msg;
@@ -3498,6 +4904,9 @@ static uint8_t unpack_dl_config_request(uint8_t **ppReadPackedMsg, uint8_t *end,
static uint8_t unpack_ul_config_ulsch_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
{
+
+
+
nfapi_ul_config_ulsch_pdu_rel8_t* ulsch_pdu_rel8 = (nfapi_ul_config_ulsch_pdu_rel8_t*)tlv;
return (pull32(ppReadPackedMsg, &ulsch_pdu_rel8->handle, end) &&
@@ -3516,6 +4925,7 @@ static uint8_t unpack_ul_config_ulsch_pdu_rel8_value(void *tlv, uint8_t **ppRead
pull8(ppReadPackedMsg, &ulsch_pdu_rel8->current_tx_nb, end) &&
pull8(ppReadPackedMsg, &ulsch_pdu_rel8->n_srs, end ));
}
+
static uint8_t unpack_ul_config_ulsch_pdu_rel10_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
{
nfapi_ul_config_ulsch_pdu_rel10_t* ulsch_pdu_rel10 = (nfapi_ul_config_ulsch_pdu_rel10_t*)tlv;
@@ -4415,6 +5825,70 @@ static uint8_t unpack_hi_dci0_request_body_value(void *tlv, uint8_t **ppReadPack
return 1;
}
+//unpack_ul_dci_pdu_list_value
+
+static uint8_t unpack_ul_dci_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg)
+{
+ nfapi_nr_ul_dci_request_pdus_t* value = (nfapi_nr_ul_dci_request_pdus_t*)msg;
+
+ for(uint8_t i = 0; i < MAX_DCI_CORESET; ++i)
+ {
+ if(!pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].RNTI, end) &&
+ pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].ScramblingId, end) &&
+
+ pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].ScramblingRNTI, end) &&
+ pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].CceIndex, end) &&
+ pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].AggregationLevel, end) &&
+ pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].beta_PDCCH_1_0, end) &&
+
+ pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].powerControlOffsetSS, end) &&
+ pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].PayloadSizeBits, end) &&
+
+ pullarray8(ppReadPackedMsg, value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].Payload, DCI_PAYLOAD_BYTE_LEN, value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].PayloadSizeBits, end));
+
+ return 0;
+ }
+
+ return (pull16(ppReadPackedMsg, &value->PDUType, end) &&
+ pull16(ppReadPackedMsg, &value->PDUSize, end) &&
+ pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.BWPSize, end) &&
+ pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.BWPStart, end) &&
+ pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.SubcarrierSpacing, end) &&
+ pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.CyclicPrefix, end) &&
+
+ pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.StartSymbolIndex, end) &&
+ pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.DurationSymbols, end) &&
+ pullarray8(ppReadPackedMsg, value->pdcch_pdu.pdcch_pdu_rel15.FreqDomainResource, 6, 6, end) &&
+ pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.CceRegMappingType, end) &&
+
+ pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.RegBundleSize, end) &&
+ pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.InterleaverSize, end) &&
+ pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.CoreSetType, end) &&
+ 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)
+{
+nfapi_nr_ul_dci_request_t *pNfapiMsg = (nfapi_nr_ul_dci_request_t*)msg;
+
+ if (!(pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end) &&
+ pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end) &&
+ pull8(ppReadPackedMsg, &pNfapiMsg->numPdus, end)
+ ))
+ return 0;
+ for(int i=0; i< pNfapiMsg->numPdus; i++)
+ {
+ if (!unpack_ul_dci_pdu_list_value(ppReadPackedMsg, end, &pNfapiMsg->ul_dci_pdu_list[i]))
+ return 0;
+ }
+
+ return 1;
+
+}
static uint8_t unpack_hi_dci0_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
{
@@ -4429,6 +5903,72 @@ static uint8_t unpack_hi_dci0_request(uint8_t **ppReadPackedMsg, uint8_t *end, v
unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
}
+static uint8_t unpack_tx_data_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg)
+{
+ nfapi_nr_pdu_t* pNfapiMsg = (nfapi_nr_pdu_t*)msg;
+
+ if(!(pull32(ppReadPackedMsg, &pNfapiMsg->num_TLV, end) &&
+ pull16(ppReadPackedMsg, &pNfapiMsg->PDU_index, end) &&
+ pull16(ppReadPackedMsg, &pNfapiMsg->PDU_length, end)
+ ))
+ return 0;
+
+ uint16_t i = 0;
+ uint16_t total_number_of_tlvs = pNfapiMsg->num_TLV;
+ for(; i < total_number_of_tlvs; ++i)
+ {
+
+ if (!(pull16(ppReadPackedMsg, &pNfapiMsg->TLVs[i].length, end) &&
+ pull16(ppReadPackedMsg, &pNfapiMsg->TLVs[i].tag, end)))
+ return 0;
+
+ switch(pNfapiMsg->TLVs[i].tag){
+ case 0:
+ {
+ if(!pullarray32(ppReadPackedMsg, pNfapiMsg->TLVs[i].value.direct, 16384, pNfapiMsg->TLVs[i].length, end))
+ return 0;
+ break;
+
+ }
+
+ case 1:
+ {
+ if(!pullarray32(ppReadPackedMsg, pNfapiMsg->TLVs[i].value.ptr, pNfapiMsg->TLVs[i].length , pNfapiMsg->TLVs[i].length, end))
+ return 0;
+ break;
+
+ }
+
+ default:
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid tag value %d \n", pNfapiMsg->TLVs[i].tag );
+ break;
+ }
+
+ }
+ }
+
+
+ return 1;
+}
+
+static uint8_t unpack_tx_data_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
+{
+ nfapi_nr_tx_data_request_t *pNfapiMsg = (nfapi_nr_tx_data_request_t*)msg;
+
+ if(!(pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end) &&
+ pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end) &&
+ pull16(ppReadPackedMsg, &pNfapiMsg->Number_of_PDUs, end)))
+ return 0;
+
+ for(int i=0; i< pNfapiMsg->Number_of_PDUs; i++)
+ {
+ if (!unpack_tx_data_pdu_list_value(ppReadPackedMsg, end, &pNfapiMsg->pdu_list[i]))
+ return 0;
+ }
+
+ return 1;
+}
static uint8_t unpack_tx_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
{
@@ -4479,43 +6019,43 @@ static uint8_t unpack_tx_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *
for(i = 0; i < totalNumPdus; ++i)
{
nfapi_tx_request_pdu_t* pdu = &(pNfapiMsg->tx_request_body.tx_pdu_list[i]);
- if (pdu) {
- uint16_t length = 0;
- uint16_t index = 0;
+ if (pdu) {
+ uint16_t length = 0;
+ uint16_t index = 0;
- if(!(pull16(ppReadPackedMsg, &length, end) &&
+ if(!(pull16(ppReadPackedMsg, &length, end) &&
pull16(ppReadPackedMsg, &index, end)))
- return 0;
+ return 0;
- pdu->pdu_length = length;
- pdu->pdu_index = index;
+ pdu->pdu_length = length;
+ pdu->pdu_index = index;
// TODO : May need to rethink this bit
- pdu->num_segments = 1;
- pdu->segments[0].segment_length = pdu->pdu_length;
- pdu->segments[0].segment_data = nfapi_p7_allocate(pdu->pdu_length, config);
+ pdu->num_segments = 1;
+ pdu->segments[0].segment_length = pdu->pdu_length;
+ pdu->segments[0].segment_data = nfapi_p7_allocate(pdu->pdu_length, config);
- if(pdu->segments[0].segment_data)
- {
- if(!pullarray8(ppReadPackedMsg, pdu->segments[0].segment_data, pdu->segments[0].segment_length, pdu->segments[0].segment_length, end))
+ if(pdu->segments[0].segment_data)
+ {
+ if(!pullarray8(ppReadPackedMsg, pdu->segments[0].segment_data, pdu->segments[0].segment_length, pdu->segments[0].segment_length, end))
return 0;
- if (pdu->segments[0].segment_length == 3)
- {
+ if (pdu->segments[0].segment_length == 3)
+ {
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() BCH? segment_data:%x %x %x\n", __FUNCTION__,
pdu->segments[0].segment_data[0],
pdu->segments[0].segment_data[1],
pdu->segments[0].segment_data[2]
);
- }
- }
- else
- {
+ }
+ }
+ else
+ {
NFAPI_TRACE(NFAPI_TRACE_ERROR, "unpack_tx_request: Failed to allocate pdu (len:%d) %d/%d %d\n", pdu->pdu_length, totalNumPdus, i, pdu->pdu_index);
- }
- } else {
- NFAPI_TRACE(NFAPI_TRACE_ERROR, "NULL pdu\n");
- }
+ }
+ } else {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "NULL pdu\n");
+ }
}
}
break;
@@ -4529,55 +6069,55 @@ static uint8_t unpack_tx_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *
return 1;
}
-
-static uint8_t unpack_ue_release_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
-{
- uint8_t proceed = 1;
- nfapi_ue_release_request_t *pNfapiMsg = (nfapi_ue_release_request_t*)msg;
-
- if(pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) == 0)
- return 0;
-
- while (((uint8_t*)(*ppReadPackedMsg) < end) && proceed)
- {
- nfapi_tl_t generic_tl;
- if(unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0)
- return 0;
-
- switch(generic_tl.tag)
- {
- case NFAPI_UE_RELEASE_BODY_TAG:
- {
- pNfapiMsg->ue_release_request_body.tl = generic_tl;
- if( pull16(ppReadPackedMsg, &pNfapiMsg->ue_release_request_body.number_of_TLVs, end) == 0)
- return 0;
-
- if(pNfapiMsg->ue_release_request_body.number_of_TLVs > NFAPI_RELEASE_MAX_RNTI)
- {
- NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of relese rnti's exceed maxium (count:%d max:%d)\n", __FUNCTION__, pNfapiMsg->ue_release_request_body.number_of_TLVs, NFAPI_RELEASE_MAX_RNTI);
- return 0;
- } else {
- uint8_t j;
- uint16_t num = pNfapiMsg->ue_release_request_body.number_of_TLVs;
- for(j = 0; j < num; ++j){
- if(pull16(ppReadPackedMsg, &pNfapiMsg->ue_release_request_body.ue_release_request_TLVs_list[j].rnti, end) == 0){
- return 0;
- }
- }
- }
- }
- break;
- default:
- {
- NFAPI_TRACE(NFAPI_TRACE_ERROR, "unpack_ue_release_request FIXME : Invalid type %d \n", generic_tl.tag );
- }
- break;
- };
- }
-
- return 1;
-}
-
+
+static uint8_t unpack_ue_release_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
+{
+ uint8_t proceed = 1;
+ nfapi_ue_release_request_t *pNfapiMsg = (nfapi_ue_release_request_t*)msg;
+
+ if(pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) == 0)
+ return 0;
+
+ while (((uint8_t*)(*ppReadPackedMsg) < end) && proceed)
+ {
+ nfapi_tl_t generic_tl;
+ if(unpack_tl(ppReadPackedMsg, &generic_tl, end) == 0)
+ return 0;
+
+ switch(generic_tl.tag)
+ {
+ case NFAPI_UE_RELEASE_BODY_TAG:
+ {
+ pNfapiMsg->ue_release_request_body.tl = generic_tl;
+ if( pull16(ppReadPackedMsg, &pNfapiMsg->ue_release_request_body.number_of_TLVs, end) == 0)
+ return 0;
+
+ if(pNfapiMsg->ue_release_request_body.number_of_TLVs > NFAPI_RELEASE_MAX_RNTI)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s number of relese rnti's exceed maxium (count:%d max:%d)\n", __FUNCTION__, pNfapiMsg->ue_release_request_body.number_of_TLVs, NFAPI_RELEASE_MAX_RNTI);
+ return 0;
+ } else {
+ uint8_t j;
+ uint16_t num = pNfapiMsg->ue_release_request_body.number_of_TLVs;
+ for(j = 0; j < num; ++j){
+ if(pull16(ppReadPackedMsg, &pNfapiMsg->ue_release_request_body.ue_release_request_TLVs_list[j].rnti, end) == 0){
+ return 0;
+ }
+ }
+ }
+ }
+ break;
+ default:
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "unpack_ue_release_request FIXME : Invalid type %d \n", generic_tl.tag );
+ }
+ break;
+ };
+ }
+
+ return 1;
+}
+
static uint8_t unpack_harq_indication_tdd_harq_data_bundling(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
{
nfapi_harq_indication_tdd_harq_data_bundling_t* value = (nfapi_harq_indication_tdd_harq_data_bundling_t*)tlv;
@@ -5825,18 +7365,18 @@ static uint8_t unpack_nrach_indication_rel13_value(void *tlv, uint8_t **ppReadPa
pull8(ppReadPackedMsg, &value->nrach_ce_level, end));
}
-static uint8_t unpack_ue_release_resp(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
-{
- nfapi_ue_release_response_t *pNfapiMsg = (nfapi_ue_release_response_t*)msg;
- if(pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) == 0){
- return 0;
- }
- else{
- NFAPI_TRACE(NFAPI_TRACE_INFO, "ue_release_response:error_code = %d\n", pNfapiMsg->error_code);
- }
- return 1;
-}
-
+static uint8_t unpack_ue_release_resp(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
+{
+ nfapi_ue_release_response_t *pNfapiMsg = (nfapi_ue_release_response_t*)msg;
+ if(pull32(ppReadPackedMsg, &pNfapiMsg->error_code, end) == 0){
+ return 0;
+ }
+ else{
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "ue_release_response:error_code = %d\n", pNfapiMsg->error_code);
+ }
+ return 1;
+}
+
static uint8_t unpack_nrach_indication_body_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t* config)
{
nfapi_nrach_indication_body_t* value = (nfapi_nrach_indication_body_t*)tlv;
@@ -5894,6 +7434,19 @@ static uint8_t unpack_nrach_indication(uint8_t **ppReadPackedMsg, uint8_t *end,
unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
}
+static uint8_t unpack_nr_dl_node_sync(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
+{
+ nfapi_nr_dl_node_sync_t *pNfapiMsg = (nfapi_nr_dl_node_sync_t*)msg;
+
+ unpack_p7_tlv_t unpack_fns[] =
+ {
+ };
+
+ return (pull32(ppReadPackedMsg, &pNfapiMsg->t1, end) &&
+ pulls32(ppReadPackedMsg, &pNfapiMsg->delta_sfn_slot, end) &&
+ unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
static uint8_t unpack_dl_node_sync(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
{
nfapi_dl_node_sync_t *pNfapiMsg = (nfapi_dl_node_sync_t*)msg;
@@ -5907,6 +7460,22 @@ static uint8_t unpack_dl_node_sync(uint8_t **ppReadPackedMsg, uint8_t *end, void
unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
}
+
+static uint8_t unpack_nr_ul_node_sync(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
+{
+ nfapi_nr_ul_node_sync_t *pNfapiMsg = (nfapi_nr_ul_node_sync_t*)msg;
+
+ unpack_p7_tlv_t unpack_fns[] =
+ {
+ };
+
+ return (pull32(ppReadPackedMsg, &pNfapiMsg->t1, end) &&
+ pull32(ppReadPackedMsg, &pNfapiMsg->t2, end) &&
+ pull32(ppReadPackedMsg, &pNfapiMsg->t3, end) &&
+ unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+
static uint8_t unpack_ul_node_sync(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
{
nfapi_ul_node_sync_t *pNfapiMsg = (nfapi_ul_node_sync_t*)msg;
@@ -5928,7 +7497,7 @@ static uint8_t unpack_timing_info(uint8_t **ppReadPackedMsg, uint8_t *end, void
unpack_p7_tlv_t unpack_fns[] =
{
};
-
+
return (pull32(ppReadPackedMsg, &pNfapiMsg->last_sfn_sf, end) &&
pull32(ppReadPackedMsg, &pNfapiMsg->time_since_last_timing_info, end) &&
pull32(ppReadPackedMsg, &pNfapiMsg->dl_config_jitter, end) &&
@@ -5947,6 +7516,34 @@ static uint8_t unpack_timing_info(uint8_t **ppReadPackedMsg, uint8_t *end, void
}
+static uint8_t unpack_nr_timing_info(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t* config)
+{
+ nfapi_nr_timing_info_t *pNfapiMsg = (nfapi_nr_timing_info_t*)msg;
+
+ unpack_p7_tlv_t unpack_fns[] =
+ {
+ };
+
+ return (pull32(ppReadPackedMsg, &pNfapiMsg->last_sfn, end) &&
+ pull32(ppReadPackedMsg, &pNfapiMsg->last_slot, end) &&
+ pull32(ppReadPackedMsg, &pNfapiMsg->time_since_last_timing_info, end) &&
+ pull32(ppReadPackedMsg, &pNfapiMsg->dl_tti_jitter, end) &&
+ pull32(ppReadPackedMsg, &pNfapiMsg->tx_data_request_jitter, end) &&
+ pull32(ppReadPackedMsg, &pNfapiMsg->ul_tti_jitter, end) &&
+ pull32(ppReadPackedMsg, &pNfapiMsg->ul_dci_jitter, end) &&
+ pulls32(ppReadPackedMsg, &pNfapiMsg->dl_tti_latest_delay, end) &&
+ pulls32(ppReadPackedMsg, &pNfapiMsg->tx_data_request_latest_delay, end) &&
+ pulls32(ppReadPackedMsg, &pNfapiMsg->ul_tti_latest_delay, end) &&
+ pulls32(ppReadPackedMsg, &pNfapiMsg->ul_dci_latest_delay, end) &&
+ pulls32(ppReadPackedMsg, &pNfapiMsg->dl_tti_earliest_arrival, end) &&
+ pulls32(ppReadPackedMsg, &pNfapiMsg->tx_data_request_earliest_arrival, end) &&
+ pulls32(ppReadPackedMsg, &pNfapiMsg->ul_tti_earliest_arrival, end) &&
+ pulls32(ppReadPackedMsg, &pNfapiMsg->ul_dci_earliest_arrival, end) &&
+ unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
+}
+
+
+
// unpack length check
static int check_unpack_length(nfapi_message_id_e msgId, uint32_t unpackedBufLen)
@@ -6049,17 +7646,17 @@ static int check_unpack_length(nfapi_message_id_e msgId, uint32_t unpackedBufLen
if (unpackedBufLen >= sizeof(nfapi_timing_info_t))
retLen = sizeof(nfapi_timing_info_t);
break;
-
- case NFAPI_UE_RELEASE_REQUEST:
- if (unpackedBufLen >= sizeof(nfapi_ue_release_request_t))
- retLen = sizeof(nfapi_ue_release_request_t);
- break;
-
- case NFAPI_UE_RELEASE_RESPONSE:
- if (unpackedBufLen >= sizeof(nfapi_ue_release_response_t))
- retLen = sizeof(nfapi_ue_release_response_t);
- break;
-
+
+ case NFAPI_UE_RELEASE_REQUEST:
+ if (unpackedBufLen >= sizeof(nfapi_ue_release_request_t))
+ retLen = sizeof(nfapi_ue_release_request_t);
+ break;
+
+ case NFAPI_UE_RELEASE_RESPONSE:
+ if (unpackedBufLen >= sizeof(nfapi_ue_release_response_t))
+ retLen = sizeof(nfapi_ue_release_response_t);
+ break;
+
default:
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown message ID %d\n", msgId);
break;
@@ -6068,6 +7665,126 @@ static int check_unpack_length(nfapi_message_id_e msgId, uint32_t unpackedBufLen
return retLen;
}
+static int check_nr_unpack_length(nfapi_message_id_e msgId, uint32_t unpackedBufLen)
+{
+ int retLen = 0;
+
+ switch (msgId)
+ {
+ case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
+ if (unpackedBufLen >= sizeof(nfapi_nr_dl_tti_request_t))
+ retLen = sizeof(nfapi_nr_dl_tti_request_t);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
+ if (unpackedBufLen >= sizeof(nfapi_nr_ul_tti_request_t))
+ retLen = sizeof(nfapi_nr_ul_tti_request_t);
+ break;
+
+ case NFAPI_SUBFRAME_INDICATION:
+ if (unpackedBufLen >= sizeof(nfapi_subframe_indication_t))
+ retLen = sizeof(nfapi_subframe_indication_t);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
+ if (unpackedBufLen >= sizeof(nfapi_nr_ul_dci_request_t))
+ retLen = sizeof(nfapi_nr_ul_dci_request_t);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
+ if (unpackedBufLen >= sizeof(nfapi_nr_tx_data_request_t))
+ retLen = sizeof(nfapi_nr_tx_data_request_t);
+ break;
+
+ case NFAPI_HARQ_INDICATION:
+ if (unpackedBufLen >= sizeof(nfapi_harq_indication_t))
+ retLen = sizeof(nfapi_harq_indication_t);
+ break;
+
+ case NFAPI_CRC_INDICATION:
+ if (unpackedBufLen >= sizeof(nfapi_crc_indication_t))
+ retLen = sizeof(nfapi_crc_indication_t);
+ break;
+
+ case NFAPI_RX_ULSCH_INDICATION:
+ if (unpackedBufLen >= sizeof(nfapi_rx_indication_t))
+ retLen = sizeof(nfapi_rx_indication_t);
+ break;
+
+ case NFAPI_RACH_INDICATION:
+ if (unpackedBufLen >= sizeof(nfapi_rach_indication_t))
+ retLen = sizeof(nfapi_rach_indication_t);
+ break;
+
+ case NFAPI_SRS_INDICATION:
+ if (unpackedBufLen >= sizeof(nfapi_srs_indication_t))
+ retLen = sizeof(nfapi_srs_indication_t);
+ break;
+
+ case NFAPI_RX_SR_INDICATION:
+ if (unpackedBufLen >= sizeof(nfapi_sr_indication_t))
+ retLen = sizeof(nfapi_sr_indication_t);
+ break;
+
+ case NFAPI_RX_CQI_INDICATION:
+ if (unpackedBufLen >= sizeof(nfapi_cqi_indication_t))
+ retLen = sizeof(nfapi_cqi_indication_t);
+ break;
+
+ case NFAPI_LBT_DL_CONFIG_REQUEST:
+ if (unpackedBufLen >= sizeof(nfapi_lbt_dl_config_request_t))
+ retLen = sizeof(nfapi_lbt_dl_config_request_t);
+ break;
+
+ case NFAPI_LBT_DL_INDICATION:
+ if (unpackedBufLen >= sizeof(nfapi_lbt_dl_indication_t))
+ retLen = sizeof(nfapi_lbt_dl_indication_t);
+ break;
+
+ case NFAPI_NB_HARQ_INDICATION:
+ if (unpackedBufLen >= sizeof(nfapi_nb_harq_indication_t))
+ retLen = sizeof(nfapi_nb_harq_indication_t);
+ break;
+
+ case NFAPI_NRACH_INDICATION:
+ if (unpackedBufLen >= sizeof(nfapi_nrach_indication_t))
+ retLen = sizeof(nfapi_nrach_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);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC:
+ if (unpackedBufLen >= sizeof(nfapi_nr_ul_node_sync_t))
+ retLen = sizeof(nfapi_nr_ul_node_sync_t);
+ break;
+
+ case NFAPI_TIMING_INFO:
+ if (unpackedBufLen >= sizeof(nfapi_timing_info_t))
+ retLen = sizeof(nfapi_timing_info_t);
+ break;
+
+ case NFAPI_UE_RELEASE_REQUEST:
+ if (unpackedBufLen >= sizeof(nfapi_ue_release_request_t))
+ retLen = sizeof(nfapi_ue_release_request_t);
+ break;
+
+ case NFAPI_UE_RELEASE_RESPONSE:
+ if (unpackedBufLen >= sizeof(nfapi_ue_release_response_t))
+ retLen = sizeof(nfapi_ue_release_response_t);
+ break;
+
+ default:
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown message ID %d\n", msgId);
+ break;
+ }
+
+ return retLen;
+}
+
+
// Main unpack functions - public
@@ -6119,7 +7836,15 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen);
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);
@@ -6151,7 +7876,7 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
// look for the specific message
switch (pMessageHeader->message_id)
- {
+ {
case NFAPI_DL_CONFIG_REQUEST:
if (check_unpack_length(NFAPI_DL_CONFIG_REQUEST, unpackedBufLen))
result = unpack_dl_config_request(&pReadPackedMessage, end, pMessageHeader, config);
@@ -6165,28 +7890,26 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
else
return -1;
break;
-
- case NFAPI_HI_DCI0_REQUEST:
- if (check_unpack_length(NFAPI_HI_DCI0_REQUEST, unpackedBufLen))
- result = unpack_hi_dci0_request(&pReadPackedMessage, end, pMessageHeader, config);
- else
- return -1;
- break;
-
case NFAPI_TX_REQUEST:
if (check_unpack_length(NFAPI_TX_REQUEST, unpackedBufLen))
result = unpack_tx_request(&pReadPackedMessage, end, pMessageHeader, config);
else
return -1;
break;
-
- case NFAPI_UE_RELEASE_REQUEST:
- if (check_unpack_length(NFAPI_UE_RELEASE_REQUEST, unpackedBufLen))
- result = unpack_ue_release_request(&pReadPackedMessage, end, pMessageHeader, config);
- else
- return -1;
- break;
-
+ case NFAPI_HI_DCI0_REQUEST:
+ if (check_unpack_length(NFAPI_HI_DCI0_REQUEST, unpackedBufLen))
+ result = unpack_hi_dci0_request(&pReadPackedMessage, end, pMessageHeader, config);
+ else
+ return -1;
+ break;
+
+ case NFAPI_UE_RELEASE_REQUEST:
+ if (check_unpack_length(NFAPI_UE_RELEASE_REQUEST, unpackedBufLen))
+ result = unpack_ue_release_request(&pReadPackedMessage, end, pMessageHeader, config);
+ else
+ return -1;
+ break;
+
case NFAPI_HARQ_INDICATION:
if (check_unpack_length(NFAPI_HARQ_INDICATION, unpackedBufLen))
result = unpack_harq_indication(&pReadPackedMessage, end, pMessageHeader, config);
@@ -6284,14 +8007,14 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
else
return -1;
break;
-
- case NFAPI_UE_RELEASE_RESPONSE:
- if (check_unpack_length(NFAPI_UE_RELEASE_RESPONSE, unpackedBufLen))
- result = unpack_ue_release_resp(&pReadPackedMessage, end, pMessageHeader, config);
- else
- return -1;
- break;
-
+
+ case NFAPI_UE_RELEASE_RESPONSE:
+ if (check_unpack_length(NFAPI_UE_RELEASE_RESPONSE, unpackedBufLen))
+ result = unpack_ue_release_resp(&pReadPackedMessage, end, pMessageHeader, config);
+ else
+ return -1;
+ break;
+
default:
if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
@@ -6319,3 +8042,228 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
return 0;
}
+int nfapi_nr_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p7_codec_config_t* config)
+{
+ int result = 0;
+ nfapi_p7_message_header_t *pMessageHeader = (nfapi_p7_message_header_t*)pUnpackedBuf;
+ uint8_t *pReadPackedMessage = pMessageBuf;
+ uint8_t *end = pMessageBuf + messageBufLen;
+
+ if (pMessageBuf == NULL || pUnpackedBuf == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack supplied pointers are null\n");
+ return -1;
+ }
+
+ if (messageBufLen < NFAPI_P7_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p7_message_header_t))
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen);
+ 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);
+
+ // process the header
+ if(!(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) &&
+ pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) &&
+ pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) &&
+ pull16(&pReadPackedMessage, &pMessageHeader->m_segment_sequence, end) &&
+ pull32(&pReadPackedMessage, &pMessageHeader->checksum, end) &&
+ pull32(&pReadPackedMessage, &pMessageHeader->transmit_timestamp, end)))
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack header failed\n");
+ return -1;
+ }
+
+ if((uint8_t*)(pMessageBuf + pMessageHeader->message_length) > end)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack message length is greater than the message buffer \n");
+ return -1;
+ }
+
+ /*
+ if(check_unpack_length(pMessageHeader->message_id, unpackedBufLen) == 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack unpack buffer is not large enough \n");
+ return -1;
+ }
+ */
+
+ // look for the specific message
+ switch (pMessageHeader->message_id)
+ {
+ case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
+ if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST, unpackedBufLen))
+ result = unpack_dl_tti_request(&pReadPackedMessage, end, pMessageHeader, config);
+ else
+ return -1;
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
+ if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST, unpackedBufLen))
+ result = unpack_ul_tti_request(&pReadPackedMessage, end, pMessageHeader, config);
+ else
+ return -1;
+ break;
+ case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
+ if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST, unpackedBufLen))
+ result = unpack_tx_data_request(&pReadPackedMessage, end, pMessageHeader, config);
+ else
+ return -1;
+ break;
+ case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
+ if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST, unpackedBufLen))
+ result = unpack_ul_dci_request(&pReadPackedMessage, end, pMessageHeader, config);
+ 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);
+ else
+ return -1;
+ break;
+
+ case NFAPI_HARQ_INDICATION:
+ if (check_nr_unpack_length(NFAPI_HARQ_INDICATION, unpackedBufLen))
+ result = unpack_harq_indication(&pReadPackedMessage, end, pMessageHeader, config);
+ else
+ return -1;
+ break;
+
+ case NFAPI_CRC_INDICATION:
+ if (check_nr_unpack_length(NFAPI_CRC_INDICATION, unpackedBufLen))
+ result = unpack_crc_indication(&pReadPackedMessage,end , pMessageHeader, config);
+ else
+ return -1;
+ break;
+
+ case NFAPI_RX_ULSCH_INDICATION:
+ if (check_nr_unpack_length(NFAPI_RX_ULSCH_INDICATION, unpackedBufLen))
+ result = unpack_rx_indication(&pReadPackedMessage, end, pMessageHeader, config);
+ else
+ return -1;
+ break;
+
+ case NFAPI_RACH_INDICATION:
+ if (check_nr_unpack_length(NFAPI_RACH_INDICATION, unpackedBufLen))
+ result = unpack_rach_indication(&pReadPackedMessage, end, pMessageHeader, config);
+ else
+ return -1;
+ break;
+
+ case NFAPI_SRS_INDICATION:
+ if (check_nr_unpack_length(NFAPI_SRS_INDICATION, unpackedBufLen))
+ result = unpack_srs_indication(&pReadPackedMessage, end, pMessageHeader, config);
+ else
+ return -1;
+ break;
+
+ case NFAPI_RX_SR_INDICATION:
+ if (check_nr_unpack_length(NFAPI_RX_SR_INDICATION, unpackedBufLen))
+ result = unpack_sr_indication(&pReadPackedMessage, end, pMessageHeader, config);
+ else
+ return -1;
+ break;
+
+ case NFAPI_RX_CQI_INDICATION:
+ if (check_nr_unpack_length(NFAPI_RX_CQI_INDICATION, unpackedBufLen))
+ result = unpack_cqi_indication(&pReadPackedMessage, end, pMessageHeader, config);
+ else
+ return -1;
+ break;
+
+ case NFAPI_LBT_DL_CONFIG_REQUEST:
+ if (check_nr_unpack_length(NFAPI_LBT_DL_CONFIG_REQUEST, unpackedBufLen))
+ result = unpack_lbt_dl_config_request(&pReadPackedMessage, end, pMessageHeader, config);
+ else
+ return -1;
+ break;
+
+ case NFAPI_LBT_DL_INDICATION:
+ if (check_nr_unpack_length(NFAPI_LBT_DL_INDICATION, unpackedBufLen))
+ result = unpack_lbt_dl_indication(&pReadPackedMessage, end, pMessageHeader, config);
+ else
+ return -1;
+ break;
+
+ case NFAPI_NB_HARQ_INDICATION:
+ if (check_nr_unpack_length(NFAPI_NB_HARQ_INDICATION, unpackedBufLen))
+ result = unpack_nb_harq_indication(&pReadPackedMessage, end, pMessageHeader, config);
+ else
+ return -1;
+ break;
+
+ case NFAPI_NRACH_INDICATION:
+ if (check_nr_unpack_length(NFAPI_NRACH_INDICATION, unpackedBufLen))
+ result = unpack_nrach_indication(&pReadPackedMessage, end, pMessageHeader, config);
+ else
+ return -1;
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
+ if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC, unpackedBufLen))
+ result = unpack_nr_dl_node_sync(&pReadPackedMessage, end, pMessageHeader, config);
+ else
+ return -1;
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC:
+ if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC, unpackedBufLen))
+ result = unpack_nr_ul_node_sync(&pReadPackedMessage, end , pMessageHeader, config);
+ else
+ return -1;
+ break;
+
+ case NFAPI_TIMING_INFO:
+ if (check_nr_unpack_length(NFAPI_TIMING_INFO, unpackedBufLen))
+ result = unpack_nr_timing_info(&pReadPackedMessage, end, pMessageHeader, config);
+ else
+ return -1;
+ break;
+
+ case NFAPI_UE_RELEASE_RESPONSE:
+ if (check_nr_unpack_length(NFAPI_UE_RELEASE_RESPONSE, unpackedBufLen))
+ result = unpack_ue_release_resp(&pReadPackedMessage, end, pMessageHeader, config);
+ else
+ return -1;
+ break;
+
+ default:
+
+ if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
+ pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX)
+ {
+ if(config && config->unpack_p7_vendor_extension)
+ {
+ result = (config->unpack_p7_vendor_extension)(pMessageHeader, &pReadPackedMessage, end, config);
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve decoder provided\n", __FUNCTION__, pMessageHeader->message_id);
+ }
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, pMessageHeader->message_id);
+ }
+ break;
+ }
+
+ if(result == 0)
+ return -1;
+ else
+ return 0;
+}
+
+
diff --git a/nfapi/open-nFAPI/pnf/inc/pnf.h b/nfapi/open-nFAPI/pnf/inc/pnf.h
index ab38c66e09..8c4e5cf9ab 100644
--- a/nfapi/open-nFAPI/pnf/inc/pnf.h
+++ b/nfapi/open-nFAPI/pnf/inc/pnf.h
@@ -38,7 +38,9 @@ typedef struct {
int pnf_connect(pnf_t *pnf);
int pnf_message_pump(pnf_t *pnf);
+int pnf_nr_message_pump(pnf_t *pnf);
+int pnf_nr_pack_and_send_p5_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len);
int pnf_pack_and_send_p5_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len);
int pnf_pack_and_send_p4_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len);
int pnf_send_message(pnf_t* pnf, uint8_t* msg, uint32_t msg_len, uint16_t stream_id);
diff --git a/nfapi/open-nFAPI/pnf/inc/pnf_p7.h b/nfapi/open-nFAPI/pnf/inc/pnf_p7.h
index 3f08d85e6b..1e2e2fa21d 100644
--- a/nfapi/open-nFAPI/pnf/inc/pnf_p7.h
+++ b/nfapi/open-nFAPI/pnf/inc/pnf_p7.h
@@ -29,15 +29,37 @@
typedef struct {
uint16_t dl_conf_ontime;
+ uint16_t dl_tti_ontime;
uint16_t dl_conf_late;
+ uint16_t dl_tti_late;
uint16_t ul_conf_ontime;
+ uint16_t ul_tti_ontime;
uint16_t ul_conf_late;
+ uint16_t ul_tti_late;
uint16_t hi_dci0_ontime;
uint16_t hi_dci0_late;
+ uint16_t ul_dci_ontime;
+ uint16_t ul_dci_late;
uint16_t tx_ontime;
uint16_t tx_late;
+ uint16_t tx_data_ontime;
+ uint16_t tx_data_late;
} pnf_p7_stats_t;
+
+typedef struct { // TODO: replace with the stats
+ uint16_t dl_tti_ontime;
+ uint16_t dl_tti_late;
+ uint16_t ul_tti_ontime;
+ uint16_t ul_tti_late;
+ uint16_t ul_dci_ontime;
+ uint16_t ul_dci_late;
+ uint16_t tx_data_ontime;
+ uint16_t tx_data_late;
+} pnf_p7_nr_stats_t;
+
+
+
typedef struct {
uint8_t* buffer;
uint16_t length;
@@ -82,7 +104,7 @@ typedef struct {
pthread_mutex_t pack_mutex; // should we allow the client to specifiy
nfapi_pnf_p7_subframe_buffer_t subframe_buffer[30/*NFAPI_MAX_TIMING_WINDOW_SIZE*/];
-
+ nfapi_pnf_p7_slot_buffer_t slot_buffer[30/*NFAPI_MAX_TIMING_WINDOW_SIZE*/];
uint32_t sequence_number;
uint16_t max_num_segments;
@@ -94,6 +116,12 @@ typedef struct {
uint16_t sfn_sf;
uint32_t sf_start_time_hr;
int32_t sfn_sf_shift;
+
+ uint16_t sfn;
+ uint16_t slot;
+ uint16_t sfn_slot;
+ uint32_t slot_start_time_hr;
+ int32_t slot_shift;
uint8_t timing_info_period_counter;
uint8_t timing_info_aperiodic_send; // 0:false 1:true
@@ -104,18 +132,26 @@ typedef struct {
uint32_t ul_config_jitter;
uint32_t hi_dci0_jitter;
uint32_t tx_jitter;
+
+ //P7 NR
+ uint32_t dl_tti_jitter;
+ uint32_t ul_tti_jitter;
+ uint32_t ul_dci_jitter;
+ uint32_t tx_data_jitter;
uint32_t tick;
pnf_p7_stats_t stats;
+ pnf_p7_nr_stats_t nr_stats;
} pnf_p7_t;
int pnf_p7_message_pump(pnf_p7_t* pnf_p7);
-
+int pnf_nr_p7_message_pump(pnf_p7_t* pnf_p7);
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_p7_send_message(pnf_p7_t* pnf_p7, uint8_t* msg, uint32_t msg_len);
+int pnf_p7_slot_ind(pnf_p7_t* config, uint16_t phy_id, uint16_t sfn, uint16_t slot);
int pnf_p7_subframe_ind(pnf_p7_t* config, uint16_t phy_id, uint16_t sfn_sf);
pnf_p7_rx_message_t* pnf_p7_rx_reassembly_queue_add_segment(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, uint32_t rx_hr_time, uint16_t sequence_number, uint16_t segment_number, uint8_t m, uint8_t* data, uint16_t data_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 d169177d6b..fc9cd66077 100644
--- a/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h
+++ b/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h
@@ -25,8 +25,14 @@ extern "C" {
#include "nfapi_interface.h"
#include "debug.h"
#include
+#include "nfapi_nr_interface.h"
+#include "nfapi_nr_interface_scf.h"
#include
+#include "openair1/PHY/defs_gNB.h"
+
+
+
/*! This enum is used to describe the states of the pnf
*/
@@ -121,6 +127,7 @@ typedef struct nfapi_pnf_config
* The client is expected to send the PNF_PARAM.response after receiving the
* PNF_PARAM.request. This can be done in the call back.
*/
+ int (*pnf_nr_param_req)(nfapi_pnf_config_t* config, nfapi_nr_pnf_param_request_t* req);
int (*pnf_param_req)(nfapi_pnf_config_t* config, nfapi_pnf_param_request_t* req);
/*! A callback for the PNF_CONFIG.request
@@ -133,7 +140,8 @@ typedef struct nfapi_pnf_config
* PNF_CONFIG.request. This can be done in the call back.
*/
int (*pnf_config_req)(nfapi_pnf_config_t* config, nfapi_pnf_config_request_t* req);
-
+ int (*pnf_nr_config_req)(nfapi_pnf_config_t* config, nfapi_nr_pnf_config_request_t* req);
+
/*! A callback for the PNF_START.request
* \param config A pointer to the pnf configuration
* \param req A data structure for the decoded PNF_CONFIG.request. This will have
@@ -144,7 +152,8 @@ typedef struct nfapi_pnf_config
* PNF_START.request. This can be done in the call back.
*/
int (*pnf_start_req)(nfapi_pnf_config_t* config, nfapi_pnf_start_request_t* req);
-
+ int (*pnf_nr_start_req)(nfapi_pnf_config_t* config, nfapi_nr_pnf_start_request_t* req);
+
/*! A callback for the PNF_STOP.request
* \param config A pointer to the pnf configuration
* \param req A data structure for the decoded PNF_STOP.request. This will have
@@ -167,7 +176,8 @@ typedef struct nfapi_pnf_config
* PARAM.request. This can be done in the call back.
*/
int (*param_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_param_request_t* req);
-
+ int (*nr_param_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_nr_param_request_scf_t* req);
+
/*! A callback for the CONFIG.request
* \param config A pointer to the pnf configuration
* \param phy A pointer to the pnf phy configuration
@@ -179,6 +189,7 @@ typedef struct nfapi_pnf_config
* CONFIG.request. This can be done in the call back.
*/
int (*config_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_config_request_t* req);
+ int (*nr_config_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_nr_config_request_scf_t* req);
/*! A callback for the START.request
* \param config A pointer to the pnf configuration
@@ -190,8 +201,8 @@ typedef struct nfapi_pnf_config
* The client is expected to send the START.response after the client has received the
* first subframe indication from FAPI.
*/
- int (*start_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_start_request_t* req);
-
+ int (*start_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_start_request_t* req);
+ int (*nr_start_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_nr_start_request_scf_t* req);
/*! A callback for the STOP.request
* \param config A pointer to the pnf configuration
* \param phy A pointer to the pnf phy configuration
@@ -203,7 +214,8 @@ typedef struct nfapi_pnf_config
* STOP.request. This can be done in the call back.
*/
int (*stop_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_stop_request_t* req);
-
+ int (*nr_stop_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_nr_stop_request_t* req);
+
/*! A callback for the MEASUREMENT.request
* \param config A pointer to the pnf configuration
* \param phy A pointer to the pnf phy configuration
@@ -355,6 +367,7 @@ int nfapi_pnf_config_destroy(nfapi_pnf_config_t* config);
* \endcode
*/
int nfapi_pnf_start(nfapi_pnf_config_t* config);
+int nfapi_nr_pnf_start(nfapi_pnf_config_t* config);
/*! Stop the PNF library.
* \param config A pointer to the pnf configuration
@@ -371,6 +384,8 @@ int nfapi_pnf_stop(nfapi_pnf_config_t* config);
*
*/
int nfapi_pnf_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_pnf_param_response_t* resp);
+int nfapi_nr_pnf_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_nr_pnf_param_response_t* resp);
+
/*! Send the PNF_CONFIG.response
* \param config A pointer to a pnf configuraiton
@@ -379,6 +394,7 @@ int nfapi_pnf_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_pnf_param_respons
*
*/
int nfapi_pnf_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_pnf_config_response_t* resp);
+int nfapi_nr_pnf_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_nr_pnf_config_response_t* resp);
/*! Send the PNF_START.response
* \param config A pointer to a pnf configuraiton
@@ -387,7 +403,7 @@ int nfapi_pnf_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_pnf_config_respo
*
*/
int nfapi_pnf_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_pnf_start_response_t* resp);
-
+int nfapi_nr_pnf_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_nr_pnf_start_response_t* resp);
/*! Send the PNF_STOP.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
@@ -403,6 +419,7 @@ int nfapi_pnf_pnf_stop_resp(nfapi_pnf_config_t* config, nfapi_pnf_stop_response_
*
*/
int nfapi_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_param_response_t* resp);
+int nfapi_nr_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_nr_param_response_scf_t* resp);
/*! Send the CONFIG.response
* \param config A pointer to a pnf configuraiton
@@ -411,7 +428,7 @@ int nfapi_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_param_response_t* res
*
*/
int nfapi_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_config_response_t* resp);
-
+int nfapi_nr_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_nr_config_response_scf_t* resp);
/*! Send the START.response
* \param config A pointer to a pnf configuraiton
* \param resp A pointer to the message structure
@@ -419,6 +436,7 @@ int nfapi_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_config_response_t* r
*
*/
int nfapi_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_start_response_t* resp);
+int nfapi_nr_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_nr_start_response_scf_t* resp);
/*! Send the STOP.response
* \param config A pointer to a pnf configuraiton
@@ -550,6 +568,22 @@ typedef struct
nfapi_ue_release_request_t* ue_release_req;
} nfapi_pnf_p7_subframe_buffer_t;
+typedef struct
+{
+ //uint16_t sfn_slot
+ int16_t sfn;
+ int16_t slot;
+ //TODO: Change P7 structs to NR
+ nfapi_nr_dl_tti_request_t* dl_tti_req;//nfapi_dl_config_request_t* dl_config_req;
+ nfapi_nr_ul_tti_request_t* ul_tti_req;//nfapi_ul_config_request_t* ul_config_req;
+ nfapi_nr_ul_dci_request_t* ul_dci_req;//nfapi_hi_dci0_request_t* hi_dci0_req;
+ nfapi_nr_tx_data_request_t* tx_data_req;//nfapi_tx_request_t* tx_req;
+
+ //TODO: check these two later
+ //nfapi_lbt_dl_config_request_t* lbt_dl_config_req;
+ //nfapi_ue_release_request_t* ue_release_req;
+} nfapi_pnf_p7_slot_buffer_t;
+
typedef struct nfapi_pnf_p7_config nfapi_pnf_p7_config_t;
/*! The nfapi PNF PHY P7 configuration information created using the nfapi_pnf_p7_create function
@@ -602,6 +636,8 @@ typedef struct nfapi_pnf_p7_config
/*! The dummy subframe buffer structure that should be used in case there
* are no 'valid' subframe messages */
nfapi_pnf_p7_subframe_buffer_t dummy_subframe;
+
+ nfapi_pnf_p7_slot_buffer_t dummy_slot; // defining a slot equivalent for now
/*! Configuration options for the p7 pack unpack functions*/
nfapi_p7_codec_config_t codec_config;
@@ -611,6 +647,7 @@ typedef struct nfapi_pnf_p7_config
// tdb : if these should be public
uint16_t subframe_buffer_size;
+ uint16_t slot_buffer_size;
uint8_t timing_info_mode_periodic; // 0:false 1:true
uint8_t timing_info_mode_aperiodic; // 0:false 1:true
uint8_t timing_info_period; // 1..225 in subframes
@@ -620,6 +657,7 @@ typedef struct nfapi_pnf_p7_config
* \param req A pointer to the dl config request message structure
* \return not currently used
*/
+ int (*dl_tti_req_fn)(gNB_L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_nr_dl_tti_request_t* req);
int (*dl_config_req)(L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_dl_config_request_t* req);
/*! A callback for the UL_CONFIG.request
@@ -627,6 +665,7 @@ typedef struct nfapi_pnf_p7_config
* \param req A pointer to the ul config request message structure
* \return not currently used
*/
+ int (*ul_tti_req_fn)(gNB_L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_nr_ul_tti_request_t* req);
int (*ul_config_req)(L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_ul_config_request_t* req);
/*! A callback for the HI_DCI0.request
@@ -634,8 +673,9 @@ typedef struct nfapi_pnf_p7_config
* \param req A pointer to the hi dci0 request message structure
* \return not currently used
*/
+ int (*ul_dci_req_fn)(gNB_L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_nr_ul_dci_request_t* req);
int (*hi_dci0_req)(L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_hi_dci0_request_t* req);
-
+
/*! A callback for the TX_REQ.request
* \param config A poiner to the PNF P7 config
* \param req A pointer to the tx request message structure
@@ -645,6 +685,7 @@ typedef struct nfapi_pnf_p7_config
* will 'keep' the pointers until they are transmitted the callee should set the pointers in the req to 0
* and then use the p7 codec config free function to release the pdu's when appropriate.
*/
+ int (*tx_data_req_fn)(nfapi_pnf_p7_config_t* config, nfapi_nr_tx_data_request_t* req);
int (*tx_req)(nfapi_pnf_p7_config_t* config, nfapi_tx_request_t* req);
/*! A callback for the LBT_DL_CONFIG.request
@@ -708,6 +749,7 @@ int nfapi_pnf_p7_config_destroy(nfapi_pnf_p7_config_t* config);
* This function will not return until nfapi_pnf_p7_stop is called.
*/
int nfapi_pnf_p7_start(nfapi_pnf_p7_config_t* config);
+int nfapi_nr_pnf_p7_start(nfapi_pnf_p7_config_t* config);
/*! Stop the PNF P7 library.
* \param config A pointer to a PNF P7 config
@@ -717,6 +759,21 @@ int nfapi_pnf_p7_start(nfapi_pnf_p7_config_t* config);
*/
int nfapi_pnf_p7_stop(nfapi_pnf_p7_config_t* config);
+/*! NR Slot indication
+ * message copied from nfapi_pnf_p7_subframe_ind
+ * \param config A pointer to a PNF P7 config
+ * \param phy_id The phy_id for the phy instance
+ * \param sfn_sf The SFN and SF in the format of FAPI
+ * \return 0 means success, -1 means failure
+ *
+ * The client should call the subframe indication every 1ms. The PNF will
+ * respond by invoking the pnf p7 subframe callbacks with the messages from the subframe buffer
+ *
+ * If messages are not in the subframe buffer, they dummy subframe messages will be sent
+ */
+int nfapi_pnf_p7_slot_ind(nfapi_pnf_p7_config_t* config, uint16_t phy_id, uint16_t sfn, uint16_t slot);
+
+
/*! Subframe indication
* \param config A pointer to a PNF P7 config
* \param phy_id The phy_id for the phy instance
diff --git a/nfapi/open-nFAPI/pnf/src/pnf.c b/nfapi/open-nFAPI/pnf/src/pnf.c
index eec9ff80c3..fdafd93279 100644
--- a/nfapi/open-nFAPI/pnf/src/pnf.c
+++ b/nfapi/open-nFAPI/pnf/src/pnf.c
@@ -26,9 +26,29 @@
#include
#include
#include
-
+#include "nfapi_nr_interface.h"
+#include "nfapi_nr_interface_scf.h"
#include "pnf.h"
+# if 1 // for hard-code (remove later)
+#include "COMMON/platform_types.h"
+#include "COMMON/platform_constants.h"
+#include "common/ran_context.h"
+
+#include "common/utils/LOG/log.h"
+#include "common/utils/LOG/vcd_signal_dumper.h"
+
+#include "NR_BCCH-BCH-Message.h"
+#include "NR_ServingCellConfigCommon.h"
+
+#include "LAYER2/NR_MAC_gNB/mac_proto.h"
+#include "SCHED_NR/phy_frame_config_nr.h"
+
+#include "NR_MIB.h"
+#include "openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h"
+
+#endif
+
#define MAX_SCTP_STREAMS 16
void nfapi_pnf_phy_config_delete_all(nfapi_pnf_config_t* config)
@@ -63,6 +83,50 @@ nfapi_pnf_phy_config_t* nfapi_pnf_phy_config_find(nfapi_pnf_config_t* config, ui
return 0;
}
+void pnf_nr_handle_pnf_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
+{
+ // ensure it's valid
+ if (pRecvMsg == NULL || pnf == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
+ }
+ 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)
+ {
+ if(pnf->_public.state == NFAPI_PNF_IDLE)
+ {
+ if(pnf->_public.pnf_nr_param_req)
+ {
+ (pnf->_public.pnf_nr_param_req)(&pnf->_public, &req);
+ }
+ }
+ 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;
+ resp.error_code = NFAPI_MSG_INVALID_STATE;
+ nfapi_nr_pnf_pnf_param_resp(&pnf->_public, &resp);
+ }
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
+ }
+
+ if(req.vendor_extension)
+ pnf->_public.codec_config.deallocate(req.vendor_extension);
+ }
+}
+
void pnf_handle_pnf_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
// ensure it's valid
@@ -173,6 +237,72 @@ void pnf_handle_pnf_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
}
}
+void pnf_nr_handle_pnf_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
+{
+
+
+ // ensure it's valid
+ if (pRecvMsg == NULL || pnf == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
+ }
+ else
+ {
+ 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)
+ {
+ // ensure correct state
+ if(pnf->_public.state != NFAPI_PNF_RUNNING)
+ {
+ // 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)
+ {
+ int i = 0;
+ for(i = 0; i < req.pnf_phy_rf_config.number_phy_rf_config_info; ++i)
+ {
+ 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);
+ }
+ }
+ 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;
+ resp.error_code = NFAPI_MSG_INVALID_STATE;
+ nfapi_nr_pnf_pnf_config_resp(&(pnf->_public), &resp);
+ }
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
+ }
+
+ if(req.vendor_extension)
+ pnf->_public.codec_config.deallocate(req.vendor_extension);
+ }
+}
+
void pnf_handle_pnf_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
// ensure it's valid
@@ -215,6 +345,48 @@ void pnf_handle_pnf_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
}
}
+void pnf_nr_handle_pnf_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
+{
+ // ensure it's valid
+ if (pRecvMsg == NULL || pnf == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
+ }
+ else
+ {
+ 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)
+ {
+ if(pnf->_public.state == NFAPI_PNF_CONFIGURED)
+ {
+ if(pnf->_public.pnf_nr_start_req)
+ {
+ (pnf->_public.pnf_nr_start_req)(&(pnf->_public), &req);
+ }
+ }
+ else
+ {
+ nfapi_nr_pnf_start_response_t resp;
+ memset(&resp, 0, sizeof(resp));
+ resp.header.message_id = NFAPI_PNF_START_RESPONSE;
+ resp.error_code = NFAPI_MSG_INVALID_STATE;
+ nfapi_nr_pnf_pnf_start_resp(&(pnf->_public), &resp);
+ }
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
+ }
+
+ if(req.vendor_extension)
+ pnf->_public.codec_config.deallocate(req.vendor_extension);
+ }
+}
+
void pnf_handle_pnf_stop_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
// ensure it's valid
@@ -330,6 +502,78 @@ void pnf_handle_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
}
}
+void pnf_nr_handle_param_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
+{
+ // ensure it's valid
+ if (pRecvMsg == NULL || pnf == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
+ }
+ 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)
+ {
+ if(config->state == NFAPI_PNF_RUNNING)
+ {
+ nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, req.header.phy_id);
+ if(phy)
+ {
+ if(phy->state == NFAPI_PNF_PHY_IDLE)
+ {
+ if(config->nr_param_req)
+ {
+ (config->nr_param_req)(config, phy, &req);
+ }
+ }
+ else
+ {
+ nfapi_nr_param_response_scf_t resp;
+ memset(&resp, 0, sizeof(resp));
+ resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE;
+ resp.header.phy_id = req.header.phy_id;
+ resp.error_code = NFAPI_MSG_INVALID_STATE;
+ nfapi_nr_pnf_param_resp(config, &resp);
+ }
+ }
+ else
+ {
+ nfapi_nr_param_response_scf_t resp;
+ memset(&resp, 0, sizeof(resp));
+ resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE;
+ resp.header.phy_id = req.header.phy_id;
+ resp.error_code = NFAPI_MSG_INVALID_CONFIG;
+ nfapi_nr_pnf_param_resp(config, &resp);
+ }
+
+ }
+ else
+ {
+ nfapi_nr_param_response_scf_t resp;
+ memset(&resp, 0, sizeof(resp));
+ resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE;
+ resp.header.phy_id = req.header.phy_id;
+ resp.error_code = NFAPI_MSG_INVALID_STATE;
+ nfapi_nr_pnf_param_resp(config, &resp);
+ }
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
+ }
+
+ if(req.vendor_extension)
+ pnf->_public.codec_config.deallocate(req.vendor_extension);
+
+ }
+}
+
void pnf_handle_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
@@ -401,6 +645,85 @@ void pnf_handle_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
}
}
+
+void pnf_nr_handle_config_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
+{
+
+ // ensure it's valid
+ if (pRecvMsg == NULL || pnf == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
+ }
+ else
+ {
+ 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)
+ {
+ if(config->state == NFAPI_PNF_RUNNING)
+ {
+ nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, req.header.phy_id);
+
+#if 0 // emulate set_config TLV reception (hard-code)
+ int tdd_return = set_tdd_config_nr(&req, 1, 7, 6, 2, 4);
+#endif
+
+ if(phy)
+ {
+ if(phy->state != NFAPI_PNF_PHY_RUNNING)
+ {
+ if(config->nr_config_req)
+ {
+ (config->nr_config_req)(config, phy, &req);
+
+
+ }
+ }
+ else
+ {
+ nfapi_nr_config_response_scf_t resp;
+ memset(&resp, 0, sizeof(resp));
+ resp.header.message_id = NFAPI_CONFIG_RESPONSE;
+ resp.header.phy_id = req.header.phy_id;
+ resp.error_code = NFAPI_MSG_INVALID_STATE;
+ nfapi_nr_pnf_config_resp(config, &resp);
+ }
+ }
+ else
+ {
+ nfapi_nr_config_response_scf_t resp;
+ memset(&resp, 0, sizeof(resp));
+ resp.header.message_id = NFAPI_CONFIG_RESPONSE;
+ resp.header.phy_id = req.header.phy_id;
+ resp.error_code = NFAPI_MSG_INVALID_CONFIG;
+ nfapi_nr_pnf_config_resp(config, &resp);
+ }
+ }
+ else
+ {
+ nfapi_nr_config_response_scf_t resp;
+ memset(&resp, 0, sizeof(resp));
+ resp.header.message_id = NFAPI_CONFIG_RESPONSE;
+ resp.header.phy_id = req.header.phy_id;
+ resp.error_code = NFAPI_MSG_INVALID_STATE;
+ nfapi_nr_pnf_config_resp(config, &resp);
+ }
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
+ }
+
+ if(req.vendor_extension)
+ pnf->_public.codec_config.deallocate(req.vendor_extension);
+ }
+}
+
void pnf_handle_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
// ensure it's valid
@@ -472,6 +795,77 @@ void pnf_handle_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
}
}
+void pnf_nr_handle_start_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
+{
+ // ensure it's valid
+ if (pRecvMsg == NULL || pnf == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
+ }
+ 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)
+ {
+ if(config->state == NFAPI_PNF_RUNNING)
+ {
+ nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, req.header.phy_id);
+ if(phy)
+ {
+ if(phy->state != NFAPI_PNF_PHY_RUNNING)
+ {
+ if(config->nr_start_req)
+ {
+ (config->nr_start_req)(config, phy, &req);
+ }
+ }
+ else
+ {
+ nfapi_nr_start_response_scf_t resp;
+ memset(&resp, 0, sizeof(resp));
+ resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE;
+ resp.header.phy_id = req.header.phy_id;
+ resp.error_code = NFAPI_MSG_INVALID_STATE;
+ nfapi_nr_pnf_start_resp(config, &resp);
+ }
+ }
+ else
+ {
+ nfapi_nr_start_response_scf_t resp;
+ memset(&resp, 0, sizeof(resp));
+ resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE;
+ resp.header.phy_id = req.header.phy_id;
+ resp.error_code = NFAPI_MSG_INVALID_CONFIG;
+ nfapi_nr_pnf_start_resp(config, &resp);
+ }
+ }
+ else
+ {
+ nfapi_nr_start_response_scf_t resp;
+ memset(&resp, 0, sizeof(resp));
+ resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE;
+ resp.header.phy_id = req.header.phy_id;
+ resp.error_code = NFAPI_MSG_INVALID_STATE;
+ nfapi_nr_pnf_start_resp(config, &resp);
+ }
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
+ }
+
+ if(req.vendor_extension)
+ pnf->_public.codec_config.deallocate(req.vendor_extension);
+
+ }
+}
+
void pnf_handle_stop_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
// ensure it's valid
@@ -543,6 +937,77 @@ void pnf_handle_stop_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
}
}
+void pnf_nr_handle_stop_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
+{
+ // ensure it's valid
+ if (pRecvMsg == NULL || pnf == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
+ }
+ else
+ {
+ 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)
+ {
+ if(config->state == NFAPI_PNF_RUNNING)
+ {
+ nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, req.header.phy_id);
+ if(phy)
+ {
+ if(phy->state != NFAPI_PNF_PHY_RUNNING)
+ {
+ if(config->nr_stop_req)
+ {
+ (config->nr_stop_req)(config, phy, &req);
+ }
+ }
+ else
+ {
+ nfapi_stop_response_t resp;
+ memset(&resp, 0, sizeof(resp));
+ resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE;
+ resp.header.phy_id = req.header.phy_id;
+ resp.error_code = NFAPI_MSG_INVALID_STATE;
+ nfapi_pnf_stop_resp(config, &resp);
+ }
+ }
+ else
+ {
+ nfapi_stop_response_t resp;
+ memset(&resp, 0, sizeof(resp));
+ resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE;
+ resp.header.phy_id = req.header.phy_id;
+ resp.error_code = NFAPI_MSG_INVALID_CONFIG;
+ nfapi_pnf_stop_resp(config, &resp);
+ }
+ }
+ else
+ {
+ nfapi_stop_response_t resp;
+ memset(&resp, 0, sizeof(resp));
+ resp.header.message_id = NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE;
+ resp.header.phy_id = req.header.phy_id;
+ resp.error_code = NFAPI_MSG_INVALID_STATE;
+ nfapi_pnf_stop_resp(config, &resp);
+ }
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
+ }
+
+ if(req.vendor_extension)
+ pnf->_public.codec_config.deallocate(req.vendor_extension);
+
+ }
+}
+
void pnf_handle_measurement_request(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
// ensure it's valid
@@ -1071,7 +1536,101 @@ void pnf_handle_vendor_extension(void* pRecvMsg, int recvMsgLen, pnf_t* pnf, uin
}
}
+void pnf_nr_handle_p5_message(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
+{
+ nfapi_p4_p5_message_header_t messageHeader;
+ // validate the input params
+ if(pRecvMsg == NULL || recvMsgLen < NFAPI_HEADER_LENGTH)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
+ return;
+ }
+
+ // unpack the message header
+ if (nfapi_p5_message_header_unpack(pRecvMsg, recvMsgLen, &messageHeader, sizeof(nfapi_p4_p5_message_header_t), &pnf->_public.codec_config) < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n");
+ return;
+ }
+
+ switch (messageHeader.message_id)
+ {
+ case NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_REQUEST:
+ pnf_nr_handle_pnf_param_request(pnf, pRecvMsg, recvMsgLen);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_REQUEST:
+ pnf_nr_handle_pnf_config_request(pnf, pRecvMsg, recvMsgLen);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_PNF_START_REQUEST:
+ pnf_nr_handle_pnf_start_request(pnf, pRecvMsg, recvMsgLen);
+ break;
+
+ case NFAPI_PNF_STOP_REQUEST:
+ pnf_handle_pnf_stop_request(pnf, pRecvMsg, recvMsgLen);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST:
+ pnf_nr_handle_param_request(pnf, pRecvMsg, recvMsgLen);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST:
+ pnf_nr_handle_config_request(pnf, pRecvMsg, recvMsgLen);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_START_REQUEST:
+ pnf_nr_handle_start_request(pnf, pRecvMsg, recvMsgLen);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST:
+ pnf_nr_handle_stop_request(pnf, pRecvMsg, recvMsgLen);
+ break;
+
+ case NFAPI_MEASUREMENT_REQUEST:
+ pnf_handle_measurement_request(pnf, pRecvMsg, recvMsgLen);
+ break;
+
+ case NFAPI_RSSI_REQUEST:
+ pnf_handle_rssi_request(pnf, pRecvMsg, recvMsgLen);
+ break;
+
+ case NFAPI_CELL_SEARCH_REQUEST:
+ pnf_handle_cell_search_request(pnf, pRecvMsg, recvMsgLen);
+ break;
+
+ case NFAPI_BROADCAST_DETECT_REQUEST:
+ pnf_handle_broadcast_detect_request(pnf, pRecvMsg, recvMsgLen);
+ break;
+
+ case NFAPI_SYSTEM_INFORMATION_SCHEDULE_REQUEST:
+ pnf_handle_system_information_schedule_request(pnf, pRecvMsg, recvMsgLen);
+ break;
+
+ case NFAPI_SYSTEM_INFORMATION_REQUEST:
+ pnf_handle_system_information_request(pnf, pRecvMsg, recvMsgLen);
+ break;
+
+ case NFAPI_NMM_STOP_REQUEST:
+ pnf_handle_nmm_stop_request(pnf, pRecvMsg, recvMsgLen);
+ break;
+
+ default:
+ {
+ if(messageHeader.message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
+ messageHeader.message_id <= NFAPI_VENDOR_EXT_MSG_MAX)
+ {
+ pnf_handle_vendor_extension(pRecvMsg, recvMsgLen, pnf, messageHeader.message_id);
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s P5 Unknown message ID %d\n", __FUNCTION__, messageHeader.message_id);
+ }
+ }
+ break;
+ }
+}
void pnf_handle_p5_message(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
{
@@ -1169,6 +1728,24 @@ 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->_public.codec_config);
+
+ if (packed_len < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_p5_message_pack failed (%d)\n", packed_len);
+ return -1;
+ }
+
+ return pnf_send_message(pnf, pnf->tx_message_buffer, packed_len, 0/*msg->stream_id*/);
+}
+
+
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,
@@ -1393,8 +1970,15 @@ 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)
{
+ 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)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "sctp_sendmsg failed errno: %d\n", errno);
@@ -1412,7 +1996,6 @@ int pnf_send_message(pnf_t* pnf, uint8_t *msg, uint32_t len, uint16_t stream)
return 0;
}
-
int pnf_read_dispatch_message(pnf_t* pnf)
{
int socket_connected = 1;
@@ -1486,6 +2069,13 @@ int pnf_read_dispatch_message(pnf_t* pnf)
}
else
{
+ // print the received message
+ printf("\n MESSAGE RECEIVED: \n");
+ for(int i=0; ip5_sock, header_buffer, header_buffer_size, /*(struct sockaddr*)&addr, &addr_len*/ 0, 0, &sndrcvinfo, &flags);
+
+ if(message_size == -1)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF Failed to peek sctp message size errno:%d\n", errno);
+ return 0;
+ }
+
+ nfapi_p4_p5_message_header_t header;
+ int unpack_result = nfapi_p5_message_header_unpack(header_buffer, header_buffer_size, &header, sizeof(header), 0);
+ if(unpack_result < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF Failed to unpack p5 message header\n");
+ return 0;
+ }
+ message_size = header.message_length;
+
+ // now have the size of the mesage
+ }
+
+ if(message_size > stack_buffer_size)
+ {
+ dynamic_buffer = (uint8_t*)malloc(message_size);
+
+ if(dynamic_buffer == NULL)
+ {
+ // todo : add error mesage
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF Failed to allocate dynamic buffer for sctp_recvmsg size:%d\n", message_size);
+ return -1;
+ }
+
+ read_buffer = dynamic_buffer;
+ }
+
+ {
+ int flags = 0;
+ (void)memset(&sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo));
+
+ int recvmsg_result = sctp_recvmsg(pnf->p5_sock, read_buffer, message_size, (struct sockaddr*)&addr, &addr_len, &sndrcvinfo, &flags);
+ if(recvmsg_result == -1)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "Failed to read sctp message size errno:%d\n", errno);
+ }
+ else
+ {
+ // print the received message
+ printf("\n MESSAGE RECEIVED: \n");
+ for(int i=0; ip5_sock,
+ inet_ntoa(addr.sin_addr),
+ ntohs(addr.sin_port),
+ sndrcvinfo.sinfo_assoc_id,
+ sndrcvinfo.sinfo_stream,
+ ntohl(sndrcvinfo.sinfo_ppid),
+ message_size,
+ flags);
+ */
+
+ // handle now if complete message in one or more segments
+ if ((flags & 0x80) == 0x80)
+ {
+ pnf_nr_handle_p5_message(pnf, read_buffer, message_size);
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_WARN, "sctp_recvmsg: unhandled mode with flags 0x%x\n", flags);
+
+ // assume socket disconnected
+ NFAPI_TRACE(NFAPI_TRACE_WARN, "Disconnected socket\n");
+ socket_connected = 0;
+ }
+
+
+ }
+ }
+ }
+
+ if(dynamic_buffer)
+ {
+ free(dynamic_buffer);
+ }
+
+ return socket_connected;
+
+
}
@@ -1597,3 +2316,64 @@ int pnf_message_pump(pnf_t* pnf)
}
+int pnf_nr_message_pump(pnf_t* pnf)
+{
+ uint8_t socketConnected = 1;
+
+ while(socketConnected && pnf->terminate == 0)
+ {
+ fd_set rfds;
+ int selectRetval = 0;
+
+ // select on a timeout and then get the message
+ FD_ZERO(&rfds);
+ FD_SET(pnf->p5_sock, &rfds);
+
+ struct timeval timeout;
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+
+ selectRetval = select(pnf->p5_sock+1, &rfds, NULL, NULL, &timeout);
+
+ if(selectRetval == 0)
+ {
+ // timeout
+ continue;
+ }
+ else if (selectRetval == -1 && (errno == EINTR))
+ {
+ // interrupted by signal
+ NFAPI_TRACE(NFAPI_TRACE_WARN, "P5 Signal Interrupt %d\n", errno);
+ continue;
+ }
+ else if (selectRetval == -1)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_WARN, "P5 select() failed\n");
+ sleep(1);
+ continue;
+ }
+
+ if(FD_ISSET(pnf->p5_sock, &rfds))
+ {
+ socketConnected = pnf_nr_read_dispatch_message(pnf);
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_WARN, "Why are we here\n");
+ }
+ }
+
+ // Drop back to idle if we have lost connection
+ pnf->_public.state = NFAPI_PNF_PHY_IDLE;
+
+
+ // close the connection and socket
+ if (close(pnf->p5_sock) < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "close(sctpSock) failed errno: %d\n", errno);
+ }
+
+ return 0;
+
+}
+
diff --git a/nfapi/open-nFAPI/pnf/src/pnf_interface.c b/nfapi/open-nFAPI/pnf/src/pnf_interface.c
index dda0d0fdc6..8c9722c13e 100644
--- a/nfapi/open-nFAPI/pnf/src/pnf_interface.c
+++ b/nfapi/open-nFAPI/pnf/src/pnf_interface.c
@@ -19,6 +19,8 @@
#include
#include
#include
+#include "nfapi_nr_interface.h"
+#include "nfapi_nr_interface_scf.h"
nfapi_pnf_config_t* nfapi_pnf_config_create()
{
@@ -81,6 +83,40 @@ int nfapi_pnf_start(nfapi_pnf_config_t* config)
return 0;
}
+int nfapi_nr_pnf_start(nfapi_pnf_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 = config->trace;
+
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
+
+ pnf_t* _this = (pnf_t*)(config);
+
+ while (_this->terminate == 0)
+ {
+ int connect_result = pnf_connect(_this);
+
+ if(connect_result > 0)
+ {
+ pnf_nr_message_pump(_this);
+ }
+ else if(connect_result < 0)
+ {
+ return connect_result;
+ }
+
+ sleep(1);
+ }
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() terminate=1 - EXITTING............\n", __FUNCTION__);
+
+ return 0;
+}
+
int nfapi_pnf_stop(nfapi_pnf_config_t* config)
{
// Verify that config is not null
@@ -96,6 +132,21 @@ int nfapi_pnf_stop(nfapi_pnf_config_t* config)
return 0;
}
+
+int nfapi_nr_pnf_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_nr_pnf_param_response_t* resp)
+{
+ // ensure it's valid
+ if (config == NULL || resp == NULL)
+ {
+ 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_pnf_param_response_t));
+}
+
int nfapi_pnf_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_pnf_param_response_t* resp)
{
// ensure it's valid
@@ -129,6 +180,27 @@ int nfapi_pnf_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_pnf_config_respo
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_pnf_config_response_t));
}
+
+int nfapi_nr_pnf_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_nr_pnf_config_response_t* resp)
+{
+ // ensure it's valid
+ if (config == NULL || resp == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
+ return -1;
+ }
+
+ if(resp->error_code == NFAPI_MSG_OK)
+ {
+ config->state = NFAPI_PNF_CONFIGURED;
+ }
+
+ pnf_t* _this = (pnf_t*)(config);
+
+ return pnf_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_pnf_config_response_t));
+}
+
+
int nfapi_pnf_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_pnf_start_response_t* resp)
{
// ensure it's valid
@@ -148,6 +220,26 @@ int nfapi_pnf_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_pnf_start_respons
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_pnf_start_response_t));
}
+int nfapi_nr_pnf_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_nr_pnf_start_response_t* resp)
+{
+ // ensure it's valid
+ if (config == NULL || resp == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
+ return -1;
+ }
+
+ if(resp->error_code == NFAPI_MSG_OK)
+ {
+ config->state = NFAPI_PNF_RUNNING;
+ }
+
+ pnf_t* _this = (pnf_t*)(config);
+
+ return pnf_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_pnf_start_response_t));
+}
+
+
int nfapi_pnf_pnf_stop_resp(nfapi_pnf_config_t* config, nfapi_pnf_stop_response_t* resp)
{
// ensure it's valid
@@ -166,7 +258,6 @@ int nfapi_pnf_pnf_stop_resp(nfapi_pnf_config_t* config, nfapi_pnf_stop_response_
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_pnf_stop_response_t));
}
-
int nfapi_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_param_response_t* resp)
{
if (config == NULL || resp == NULL)
@@ -180,6 +271,20 @@ int nfapi_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_param_response_t* res
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_param_response_t));
}
+
+int nfapi_nr_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_nr_param_response_scf_t* resp)
+{
+ if (config == NULL || resp == NULL)
+ {
+ 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));
+}
+
int nfapi_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_config_response_t* resp)
{
if (config == NULL || resp == NULL)
@@ -208,6 +313,35 @@ int nfapi_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_config_response_t* r
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_config_response_t));
}
+int nfapi_nr_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_nr_config_response_scf_t* resp)
+{
+ if (config == NULL || resp == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
+ return -1;
+ }
+
+ pnf_t* _this = (pnf_t*)(config);
+
+ nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, resp->header.phy_id);
+
+ if(phy)
+ {
+ if(resp->error_code == NFAPI_NR_CONFIG_MSG_OK)
+ {
+ phy->state = NFAPI_PNF_PHY_CONFIGURED;
+ }
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: unknow phy id %d\n", __FUNCTION__, resp->header.phy_id);
+ return -1;
+ }
+
+ return pnf_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_config_response_scf_t));
+}
+
+
int nfapi_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_start_response_t* resp)
{
if (config == NULL || resp == NULL)
@@ -235,6 +369,34 @@ int nfapi_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_start_response_t* res
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_start_response_t));
}
+int nfapi_nr_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_nr_start_response_scf_t* resp)
+{
+ if (config == NULL || resp == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
+ return -1;
+ }
+
+ pnf_t* _this = (pnf_t*)(config);
+
+ nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, resp->header.phy_id);
+ if(phy)
+ {
+ if(resp->error_code == NFAPI_NR_START_MSG_OK)
+ {
+ phy->state = NFAPI_PNF_PHY_RUNNING;
+ }
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: unknown phy id %d\n", __FUNCTION__, resp->header.phy_id);
+ return -1;
+ }
+
+ return pnf_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_start_response_scf_t));
+}
+
+
int nfapi_pnf_stop_resp(nfapi_pnf_config_t* config, nfapi_stop_response_t* resp)
{
if (config == NULL || resp == NULL)
diff --git a/nfapi/open-nFAPI/pnf/src/pnf_p7.c b/nfapi/open-nFAPI/pnf/src/pnf_p7.c
index 5ba912e059..18891cdee9 100644
--- a/nfapi/open-nFAPI/pnf/src/pnf_p7.c
+++ b/nfapi/open-nFAPI/pnf/src/pnf_p7.c
@@ -32,8 +32,19 @@
#define FAPI2_IP_DSCP 0
extern uint16_t sf_ahead;
+extern uint16_t slot_ahead;
+
//uint16_t sf_ahead=4;
+void add_slot(uint16_t *frameP, uint16_t *slotP, int offset)
+{
+ uint16_t num_slots = 20; // set based on numerlogy (fixing for 1)
+
+ *frameP = (*frameP + ((*slotP + offset) / num_slots))%1024;
+
+ *slotP = ((*slotP + offset) % num_slots);
+}
+
void add_sf(uint16_t *frameP, uint16_t *subframeP, int offset)
{
*frameP = (*frameP + ((*subframeP + offset) / 10))%1024;
@@ -50,6 +61,22 @@ void subtract_sf(uint16_t *frameP, uint16_t *subframeP, int offset)
*subframeP = (*subframeP+10-offset)%10;
}
+uint32_t sfnslot_add_slot(uint16_t sfn, uint16_t slot, int offset)
+{
+ uint32_t new_sfnslot;
+// uint16_t sfn = NFAPI_SFNSLOT2SFN(sfnslot);
+// uint16_t slot = NFAPI_SFNSLOT2SLOT(sfnslot);
+
+ //printf("%s() sfn:%u sf:%u\n", __FUNCTION__, sfn, sf);
+ add_slot(&sfn, &slot, offset);
+
+ new_sfnslot = sfn<<6|slot;
+
+ //printf("%s() sfn:%u sf:%u offset:%d sfnsf:%d(DEC:%d) new:%d(DEC:%d)\n", __FUNCTION__, sfn, sf, offset, sfnsf, NFAPI_SFNSF2DEC(sfnsf), new_sfnsf, NFAPI_SFNSF2DEC(new_sfnsf));
+
+ return new_sfnslot;
+}
+
uint16_t sfnsf_add_sf(uint16_t sfnsf, int offset)
{
uint16_t new_sfnsf;
@@ -114,12 +141,34 @@ void pnf_p7_free(pnf_p7_t* pnf_p7, void* ptr)
}
// todo : for now these just malloc/free need to move to a memory cache
+nfapi_nr_dl_tti_request_t* allocate_nfapi_dl_tti_request(pnf_p7_t* pnf_p7)
+{
+ void *ptr= pnf_p7_malloc(pnf_p7, sizeof(nfapi_nr_dl_tti_request_t));
+ //printf("%s() ptr:%p\n", __FUNCTION__, ptr);
+ return ptr;
+}
nfapi_dl_config_request_t* allocate_nfapi_dl_config_request(pnf_p7_t* pnf_p7)
{
void *ptr= pnf_p7_malloc(pnf_p7, sizeof(nfapi_dl_config_request_t));
//printf("%s() ptr:%p\n", __FUNCTION__, ptr);
return ptr;
}
+void deallocate_nfapi_dl_tti_request(nfapi_nr_dl_tti_request_t* req, pnf_p7_t* pnf_p7)
+{
+ //printf("%s() SFN/SF:%d %s req:%p pdu_list:%p\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), pnf_p7->_public.codec_config.deallocate ? "DEALLOCATE" : "FREE", req, req->dl_config_request_body.dl_config_pdu_list);
+ /*
+ if(pnf_p7->_public.codec_config.deallocate)
+ {
+ //nfapi_nr_dl_tti_request_pdu_t *temp = &req->dl_tti_pdu_list;
+ (pnf_p7->_public.codec_config.deallocate)(req);
+ }
+ else
+ {
+ free(req);
+ }
+*/
+ pnf_p7_free(pnf_p7, req);
+}
void deallocate_nfapi_dl_config_request(nfapi_dl_config_request_t* req, pnf_p7_t* pnf_p7)
{
@@ -137,6 +186,13 @@ void deallocate_nfapi_dl_config_request(nfapi_dl_config_request_t* req, pnf_p7_t
pnf_p7_free(pnf_p7, req);
}
+nfapi_nr_ul_tti_request_t* allocate_nfapi_ul_tti_request(pnf_p7_t* pnf_p7)
+{
+ void *ptr= pnf_p7_malloc(pnf_p7, sizeof(nfapi_nr_ul_tti_request_t));
+ //printf("%s() ptr:%p\n", __FUNCTION__, ptr);
+ return ptr;
+}
+
nfapi_ul_config_request_t* allocate_nfapi_ul_config_request(pnf_p7_t* pnf_p7)
{
void *ptr= pnf_p7_malloc(pnf_p7, sizeof(nfapi_ul_config_request_t));
@@ -144,6 +200,23 @@ nfapi_ul_config_request_t* allocate_nfapi_ul_config_request(pnf_p7_t* pnf_p7)
return ptr;
}
+void deallocate_nfapi_ul_tti_request(nfapi_nr_ul_tti_request_t* req, pnf_p7_t* pnf_p7)
+{
+ //printf("%s() SFN/SF:%d %s req:%p pdu_list:%p\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), pnf_p7->_public.codec_config.deallocate ? "DEALLOCATE" : "FREE", req, req->ul_config_request_body.ul_config_pdu_list);
+ /*if(pnf_p7->_public.codec_config.deallocate)
+ {
+ (pnf_p7->_public.codec_config.deallocate)(req->pdus_list);
+ (pnf_p7->_public.codec_config.deallocate)(req->groups_list);
+ }
+ else
+ {
+ free(req->pdus_list);
+ free(req->groups_list);
+ }
+ */
+ pnf_p7_free(pnf_p7, req);
+}
+
void deallocate_nfapi_ul_config_request(nfapi_ul_config_request_t* req, pnf_p7_t* pnf_p7)
{
//printf("%s() SFN/SF:%d %s req:%p pdu_list:%p\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), pnf_p7->_public.codec_config.deallocate ? "DEALLOCATE" : "FREE", req, req->ul_config_request_body.ul_config_pdu_list);
@@ -160,11 +233,31 @@ void deallocate_nfapi_ul_config_request(nfapi_ul_config_request_t* req, pnf_p7_t
pnf_p7_free(pnf_p7, req);
}
+nfapi_nr_ul_dci_request_t* allocate_nfapi_ul_dci_request(pnf_p7_t* pnf_p7)
+{
+ return pnf_p7_malloc(pnf_p7, sizeof(nfapi_nr_ul_dci_request_t));
+}
+
nfapi_hi_dci0_request_t* allocate_nfapi_hi_dci0_request(pnf_p7_t* pnf_p7)
{
return pnf_p7_malloc(pnf_p7, sizeof(nfapi_hi_dci0_request_t));
}
+void deallocate_nfapi_ul_dci_request(nfapi_nr_ul_dci_request_t* req, pnf_p7_t* pnf_p7)
+{
+ //printf("%s() SFN/SF:%d %s req:%p pdu_list:%p\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), pnf_p7->_public.codec_config.deallocate ? "DEALLOCATE" : "FREE", req, req->hi_dci0_request_body.hi_dci0_pdu_list);
+ // if(pnf_p7->_public.codec_config.deallocate)
+ // {
+ // (pnf_p7->_public.codec_config.deallocate)(req->ul_dci_pdu_list);
+ // }
+ // else
+ // {
+ // free(req->ul_dci_pdu_list);
+ // }
+
+ pnf_p7_free(pnf_p7, req);
+}
+
void deallocate_nfapi_hi_dci0_request(nfapi_hi_dci0_request_t* req, pnf_p7_t* pnf_p7)
{
//printf("%s() SFN/SF:%d %s req:%p pdu_list:%p\n", __FUNCTION__, NFAPI_SFNSF2DEC(req->sfn_sf), pnf_p7->_public.codec_config.deallocate ? "DEALLOCATE" : "FREE", req, req->hi_dci0_request_body.hi_dci0_pdu_list);
@@ -181,11 +274,32 @@ void deallocate_nfapi_hi_dci0_request(nfapi_hi_dci0_request_t* req, pnf_p7_t* pn
pnf_p7_free(pnf_p7, req);
}
+nfapi_nr_tx_data_request_t* allocate_nfapi_tx_data_request(pnf_p7_t* pnf_p7)
+{
+ return pnf_p7_malloc(pnf_p7, sizeof(nfapi_nr_tx_data_request_t));
+}
+
nfapi_tx_request_t* allocate_nfapi_tx_request(pnf_p7_t* pnf_p7)
{
return pnf_p7_malloc(pnf_p7, sizeof(nfapi_tx_request_t));
}
+//TODO: Check if deallocate_nfapi_tx_data_request defn is proper
+void deallocate_nfapi_tx_data_request(nfapi_nr_tx_data_request_t* req, pnf_p7_t* pnf_p7)
+{
+/*
+ if(pnf_p7->_public.codec_config.deallocate)
+ {
+ (pnf_p7->_public.codec_config.deallocate)(req->pdu_list);
+ }
+ else
+ {
+ free(req->pdu_list);
+ }
+*/
+ pnf_p7_free(pnf_p7, req);
+}
+
void deallocate_nfapi_tx_request(nfapi_tx_request_t* req, pnf_p7_t* pnf_p7)
{
int i = 0;
@@ -385,11 +499,33 @@ void pnf_p7_rx_reassembly_queue_remove_old_msgs(pnf_p7_t* pnf_p7, pnf_p7_rx_reas
}
+static uint32_t get_slot_time(uint32_t now_hr, uint32_t slot_start_hr)
+{
+ if(now_hr < slot_start_hr)
+ {
+ //NFAPI_TRACE(NFAPI_TRACE_INFO, "now is earlier than start of subframe now_hr:%u sf_start_hr:%u\n", now_hr, sf_start_hr);
+ return 0;
+ }
+ else
+ {
+ uint32_t now_us = TIMEHR_USEC(now_hr);
+ uint32_t slot_start_us = TIMEHR_USEC(slot_start_hr);
+
+ // if the us have wrapped adjust for it
+ if(now_hr < slot_start_us)
+ {
+ now_us += 500000;
+ }
+
+ return now_us - slot_start_us;
+ }
+}
+
static uint32_t get_sf_time(uint32_t now_hr, uint32_t sf_start_hr)
{
if(now_hr < sf_start_hr)
{
- //NFAPI_TRACE(NFAPI_TRACE_INFO, "now is earlier than start of subframe now_hr:%u sf_start_hr:%u\n", now_hr, sf_start_hr);
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "now is earlier than start of subframe\n");
return 0;
}
else
@@ -407,6 +543,8 @@ static uint32_t get_sf_time(uint32_t now_hr, uint32_t sf_start_hr)
}
}
+
+
int pnf_p7_send_message(pnf_p7_t* pnf_p7, uint8_t* msg, uint32_t len)
{
// todo : consider how to do this only once
@@ -414,7 +552,8 @@ int pnf_p7_send_message(pnf_p7_t* pnf_p7, uint8_t* msg, uint32_t len)
memset((char*)&remote_addr, 0, sizeof(struct sockaddr_in));
remote_addr.sin_family = AF_INET;
remote_addr.sin_port = htons(pnf_p7->_public.remote_p7_port);
- //remote_addr.sin_addr.s_addr = inet_addr(pnf_p7->_public.remote_p7_addr);
+
+
if(inet_aton(pnf_p7->_public.remote_p7_addr, &remote_addr.sin_addr) == -1)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "inet_aton failed %d\n", errno);
@@ -424,7 +563,9 @@ int pnf_p7_send_message(pnf_p7_t* pnf_p7, uint8_t* msg, uint32_t len)
socklen_t remote_addr_len = sizeof(struct sockaddr_in);
int sendto_result;
+
if ((sendto_result = sendto((int)pnf_p7->p7_sock, (const char*)msg, len, 0, (const struct sockaddr*)&remote_addr, remote_addr_len)) < 0)
+//if ((sendto_result = sendto((int)pnf_p7->p7_sock,"hello", 6, 0, (const struct sockaddr*)&remote_addr, remote_addr_len)) < 0)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s %s:%d sendto(%d, %p, %d) %d failed errno: %d\n", __FUNCTION__, pnf_p7->_public.remote_p7_addr, pnf_p7->_public.remote_p7_port, (int)pnf_p7->p7_sock, (const char*)msg, len, remote_addr_len, errno);
return -1;
@@ -527,6 +668,97 @@ int pnf_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_p7_message_header_t*
return 0;
}
+
+int pnf_nr_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_p7_message_header_t* header, uint32_t msg_len)
+{
+ header->m_segment_sequence = NFAPI_P7_SET_MSS(0, 0, pnf_p7->sequence_number);
+
+ // Need to guard against different threads calling the encode function at the same time
+ if(pthread_mutex_lock(&(pnf_p7->pack_mutex)) != 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n");
+ return -1;
+ }
+
+ int len = nfapi_nr_p7_message_pack(header, pnf_p7->tx_message_buffer, sizeof(pnf_p7->tx_message_buffer), &pnf_p7->_public.codec_config);
+
+ if (len < 0)
+ {
+ if(pthread_mutex_unlock(&(pnf_p7->pack_mutex)) != 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n");
+ return -1;
+ }
+
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_p7_message_pack failed with return %d\n", len );
+ return -1;
+ }
+
+ if(len > pnf_p7->_public.segment_size)
+ {
+ int msg_body_len = len - NFAPI_P7_HEADER_LENGTH ;
+ int seg_body_len = pnf_p7->_public.segment_size - NFAPI_P7_HEADER_LENGTH ;
+ int segment_count = (msg_body_len / (seg_body_len)) + ((msg_body_len % seg_body_len) ? 1 : 0);
+
+ int segment = 0;
+ int offset = NFAPI_P7_HEADER_LENGTH;
+ uint8_t buffer[pnf_p7->_public.segment_size];
+ for(segment = 0; segment < segment_count; ++segment)
+ {
+ uint8_t last = 0;
+ uint16_t size = pnf_p7->_public.segment_size - NFAPI_P7_HEADER_LENGTH;
+ if(segment + 1 == segment_count)
+ {
+ last = 1;
+ size = (msg_body_len) - (seg_body_len * segment);
+ }
+
+ uint16_t segment_size = size + NFAPI_P7_HEADER_LENGTH;
+
+ // Update the header with the m and segement
+ memcpy(&buffer[0], pnf_p7->tx_message_buffer, NFAPI_P7_HEADER_LENGTH);
+
+ // set the segment length
+ buffer[4] = (segment_size & 0xFF00) >> 8;
+ buffer[5] = (segment_size & 0xFF);
+
+ // set the m & segment number
+ buffer[6] = ((!last) << 7) + segment;
+
+ memcpy(&buffer[NFAPI_P7_HEADER_LENGTH], pnf_p7->tx_message_buffer + offset, size);
+ offset += size;
+
+ if(pnf_p7->_public.checksum_enabled)
+ {
+ nfapi_p7_update_checksum(buffer, segment_size);
+ }
+
+
+ pnf_p7_send_message(pnf_p7, &buffer[0], segment_size);
+ }
+ }
+ else
+ {
+ if(pnf_p7->_public.checksum_enabled)
+ {
+ nfapi_p7_update_checksum(pnf_p7->tx_message_buffer, len);
+ }
+
+ // simple case that the message fits in a single segment
+ pnf_p7_send_message(pnf_p7, pnf_p7->tx_message_buffer, len);
+ }
+
+ pnf_p7->sequence_number++;
+
+ if(pthread_mutex_unlock(&(pnf_p7->pack_mutex)) != 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n");
+ return -1;
+ }
+
+ return 0;
+}
+
void pnf_pack_and_send_timing_info(pnf_p7_t* pnf_p7)
{
nfapi_timing_info_t timing_info;
@@ -558,6 +790,88 @@ void pnf_pack_and_send_timing_info(pnf_p7_t* pnf_p7)
pnf_p7->timing_info_ms_counter = 0;
}
+
+void pnf_nr_pack_and_send_timing_info(pnf_p7_t* pnf_p7)
+{
+ nfapi_nr_timing_info_t timing_info;
+ memset(&timing_info, 0, sizeof(timing_info));
+ timing_info.header.message_id = NFAPI_TIMING_INFO;
+ timing_info.header.phy_id = pnf_p7->_public.phy_id;
+
+ timing_info.last_sfn = pnf_p7->sfn;
+ timing_info.last_slot = pnf_p7->slot;
+ timing_info.time_since_last_timing_info = pnf_p7->timing_info_ms_counter;
+
+ timing_info.dl_tti_jitter = pnf_p7->dl_tti_jitter;
+ timing_info.tx_data_request_jitter = pnf_p7->tx_data_jitter;
+ timing_info.ul_tti_jitter = pnf_p7->ul_tti_jitter;
+ timing_info.ul_dci_jitter = pnf_p7->ul_dci_jitter;
+
+ timing_info.dl_tti_latest_delay = 0;
+ timing_info.tx_data_request_latest_delay = 0;
+ timing_info.ul_tti_latest_delay = 0;
+ timing_info.ul_dci_latest_delay = 0;
+
+ timing_info.dl_tti_earliest_arrival = 0;
+ timing_info.tx_data_request_earliest_arrival = 0;
+ timing_info.ul_tti_earliest_arrival = 0;
+ timing_info.ul_dci_earliest_arrival = 0;
+
+
+ pnf_nr_p7_pack_and_send_p7_message(pnf_p7, &(timing_info.header), sizeof(timing_info));
+
+ pnf_p7->timing_info_ms_counter = 0;
+}
+
+
+void send_dummy_slot(pnf_p7_t* pnf_p7, uint16_t sfn, uint16_t slot)
+{
+ struct timespec t;
+ clock_gettime( CLOCK_MONOTONIC, &t);
+
+ //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s(sfn_sf:%d) t:%ld.%09ld\n", __FUNCTION__, NFAPI_SFNSF2DEC(sfn_sf), t.tv_sec, t.tv_nsec);
+
+ if(pnf_p7->_public.tx_data_req_fn && pnf_p7->_public.dummy_slot.tx_data_req)
+ {
+ pnf_p7->_public.dummy_slot.tx_data_req->SFN = sfn;
+ pnf_p7->_public.dummy_slot.tx_data_req->Slot = slot;
+ //NFAPI_TRACE(NFAPI_TRACE_INFO, "Dummy tx_req - enter\n");
+ (pnf_p7->_public.tx_data_req_fn)(&pnf_p7->_public, pnf_p7->_public.dummy_slot.tx_data_req);
+ //NFAPI_TRACE(NFAPI_TRACE_INFO, "Dummy tx_req - exit\n");
+ }
+ if(pnf_p7->_public.dl_tti_req_fn && pnf_p7->_public.dummy_slot.dl_tti_req)
+ {
+ pnf_p7->_public.dummy_slot.dl_tti_req->SFN = sfn;
+ pnf_p7->_public.dummy_slot.dl_tti_req->Slot = slot;
+ //NFAPI_TRACE(NFAPI_TRACE_INFO, "Dummy dl_config_req - enter\n");
+ (pnf_p7->_public.dl_tti_req_fn)(NULL, &(pnf_p7->_public), pnf_p7->_public.dummy_slot.dl_tti_req);
+ //NFAPI_TRACE(NFAPI_TRACE_INFO, "Dummy dl_config_req - exit\n");
+ }
+ 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;
+ pnf_p7->_public.dummy_slot.ul_tti_req->Slot = slot;
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "Dummy ul_config_req - enter\n");
+ (pnf_p7->_public.ul_tti_req_fn)(NULL, &pnf_p7->_public, pnf_p7->_public.dummy_slot.ul_tti_req);
+ }
+ if(pnf_p7->_public.ul_dci_req_fn && pnf_p7->_public.dummy_slot.ul_dci_req)
+ {
+ pnf_p7->_public.dummy_slot.ul_dci_req->SFN = sfn;
+ pnf_p7->_public.dummy_slot.ul_dci_req->Slot = slot;
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "Dummy hi_dci0 - enter\n");
+ (pnf_p7->_public.ul_dci_req_fn)(NULL, &pnf_p7->_public, pnf_p7->_public.dummy_slot.ul_dci_req);
+ }
+ #if 0
+ if(pnf_p7->_public.lbt_dl_config_req && pnf_p7->_public.dummy_subframe.lbt_dl_config_req) // TODO: Change later
+ {
+ pnf_p7->_public.dummy_slot.lbt_dl_config_req->sfn_sf = sfn;
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "Dummy lbt - enter\n");
+ (pnf_p7->_public.lbt_dl_config_req)(&pnf_p7->_public, pnf_p7->_public.dummy_slot.lbt_dl_config_req);
+ }
+ #endif
+}
+
+
void send_dummy_subframe(pnf_p7_t* pnf_p7, uint16_t sfn_sf)
{
struct timespec t;
@@ -599,6 +913,292 @@ void send_dummy_subframe(pnf_p7_t* pnf_p7, uint16_t sfn_sf)
}
}
+
+int pnf_p7_slot_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn, uint16_t slot)
+{
+ // We could either send an event to the p7 thread have have it run the
+ // subframe or we could handle it here and lock access to the subframe
+ // buffers. If we do it on the p7 thread then we run the risk of blocking
+ // on the udp send.
+ //
+ // todo : start a timer to give us more of the 1 ms tick before send back
+ // the frame
+
+ // todo : consider a more efficent lock mechasium
+ //uint16_t NUM_SLOTS = 20;//10* 2^mu
+
+ if(pthread_mutex_lock(&(pnf_p7->mutex)) != 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n");
+ return -1;
+ }
+
+ // save the curren time, sfn and slot
+ pnf_p7->slot_start_time_hr = pnf_get_current_time_hr();
+ pnf_p7->sfn = sfn;
+
+ pnf_p7->slot = slot;
+
+
+
+ uint32_t sfn_slot_tx = sfnslot_add_slot(sfn, slot, slot_ahead);
+ uint16_t sfn_tx = sfn_slot_tx>>6;
+ uint16_t slot_tx = sfn_slot_tx & 0X3F;
+
+ // uint32_t tx_sfn_slot_dec = NFAPI_SFNSLOT2DEC(sfn,slot);
+ uint32_t tx_slot_dec = NFAPI_SFNSLOT2DEC(sfn,slot);
+
+
+ //uint32_t tx_sfn_slot_dec = NFAPI_SFNSLOT2DEC(sfn_slot_tx);
+
+ // If the subframe_buffer has been configured
+ if(pnf_p7->_public.slot_buffer_size!= 0) // for now value is same as sf_buffer_size
+ {
+
+ // apply the shift to the incoming sfn_sf
+ if(pnf_p7->slot_shift != 0) // see in vnf_build_send_dl_node_sync
+ {
+ uint16_t shifted_slot = slot + pnf_p7->slot_shift;
+
+ // adjust for wrap-around
+ if(shifted_slot < 0)
+ shifted_slot += NFAPI_MAX_SFNSLOTDEC;
+ else if(shifted_slot > NFAPI_MAX_SFNSLOTDEC)
+ shifted_slot -= NFAPI_MAX_SFNSLOTDEC;
+
+ // NFAPI_TRACE(NFAPI_TRACE_INFO, "Applying shift %d to sfn/slot (%d -> %d)\n", pnf_p7->sfn_slot_shift, NFAPI_SFNSF2DEC(sfn_slot), shifted_sfn_slot);
+ slot = shifted_slot;
+
+ //
+ // DJP - why does the shift not apply to pnf_p7->sfn_sf???
+ //
+
+ pnf_p7->slot_shift = 0;
+ }
+
+ uint32_t slot_dec = NFAPI_SFNSLOT2DEC(sfn, slot);
+ uint8_t buffer_index = slot_dec % pnf_p7->_public.slot_buffer_size;
+
+ nfapi_pnf_p7_slot_buffer_t* slot_buffer = &(pnf_p7->slot_buffer[buffer_index]);
+ // see where the PNF_P7 slot buffer its getting filled
+
+ uint8_t tx_buffer_index = tx_slot_dec % pnf_p7->_public.slot_buffer_size;
+ nfapi_pnf_p7_slot_buffer_t* tx_slot_buffer = &(pnf_p7->slot_buffer[tx_buffer_index]);
+
+ if (0) NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() shift:%d slot_buffer->sfn_sf:%d tx_slot_buffer->sfn_slot:%d sfn_sf:%d subframe_buffer[buffer_index:%u dl_config_req:%p tx_req:%p] "
+ "TX:sfn_sf:%d:tx_buffer_index:%d[dl_config_req:%p tx_req:%p]\n",
+ __FUNCTION__,
+ pnf_p7->slot_shift,
+ NFAPI_SFNSLOT2DEC(slot_buffer->sfn, slot_buffer->slot),
+ NFAPI_SFNSLOT2DEC(tx_slot_buffer->sfn, tx_slot_buffer->slot),
+ slot_dec, buffer_index, slot_buffer->dl_tti_req, slot_buffer->tx_data_req,
+ tx_slot_dec, tx_buffer_index, tx_slot_buffer->dl_tti_req, tx_slot_buffer->tx_data_req);
+ //TODO: Change later if required
+
+
+ // if the subframe buffer sfn sf is set then we have atlease 1 message
+ // from the vnf.
+ // todo : how to handle the messages we don't have, send dummies for
+ // now
+
+ //printf("tx_subframe_buffer->sfn_sf:%d sfn_sf_tx:%d\n", tx_subframe_buffer->sfn_sf, sfn_sf_tx);
+ //printf("subframe_buffer->sfn_sf:%d sfn_sf:%d\n", subframe_buffer->sfn_sf, sfn_sf);
+ //printf("tx_slot_buff_sfn - %d, tx_slot_buf_slot - %d, sfn_tx = %d, sllot_tx - %d \n",tx_slot_buffer->sfn,tx_slot_buffer->slot,sfn_tx,slot_tx);
+ // if(tx_slot_buffer->slot == slot_tx && tx_slot_buffer->sfn == sfn_tx)
+ // {
+
+ if(tx_slot_buffer->tx_data_req != 0)
+ {
+
+ if(pnf_p7->_public.tx_data_req_fn)
+ {
+ (pnf_p7->_public.tx_data_req_fn)(&(pnf_p7->_public), tx_slot_buffer->tx_data_req);
+ }
+ }
+ else
+ {
+ // send dummy
+ if(pnf_p7->_public.tx_data_req_fn && pnf_p7->_public.dummy_slot.tx_data_req)
+ {
+ pnf_p7->_public.dummy_slot.tx_data_req->SFN = sfn_tx;
+ pnf_p7->_public.dummy_slot.tx_data_req->Slot = slot_tx;
+
+ (pnf_p7->_public.tx_data_req_fn)(&(pnf_p7->_public), pnf_p7->_public.dummy_slot.tx_data_req);
+ }
+ }
+ //}
+
+ if( tx_slot_buffer->dl_tti_req != 0) // ADDED & TO BYPASS ERROR
+ {
+ if(pnf_p7->_public.dl_tti_req_fn)
+ {
+ (pnf_p7->_public.dl_tti_req_fn)(NULL, &(pnf_p7->_public), tx_slot_buffer->dl_tti_req);
+ }
+ }
+
+
+ else
+ {
+ // send dummy
+ if(pnf_p7->_public.dl_tti_req_fn && pnf_p7->_public.dummy_slot.dl_tti_req)
+ {
+ pnf_p7->_public.dummy_slot.dl_tti_req->SFN = sfn_tx;
+ pnf_p7->_public.dummy_slot.dl_tti_req->Slot = slot_tx;
+ (pnf_p7->_public.dl_tti_req_fn)(NULL, &(pnf_p7->_public), pnf_p7->_public.dummy_slot.dl_tti_req);
+ }
+ }
+
+ if(tx_slot_buffer->ul_dci_req!= 0)
+ {
+ if(pnf_p7->_public.ul_dci_req_fn)
+ {
+ (pnf_p7->_public.ul_dci_req_fn)(NULL, &(pnf_p7->_public), tx_slot_buffer->ul_dci_req);
+ }
+ }
+ else
+ {
+ //send dummy
+ if(pnf_p7->_public.ul_dci_req_fn && pnf_p7->_public.dummy_slot.ul_dci_req)
+ {
+ pnf_p7->_public.dummy_slot.ul_dci_req->SFN = sfn_tx;
+ pnf_p7->_public.dummy_slot.ul_dci_req->Slot = slot_tx;
+ (pnf_p7->_public.ul_dci_req_fn)(NULL, &(pnf_p7->_public), pnf_p7->_public.dummy_slot.ul_dci_req);
+ }
+ }
+ if(tx_slot_buffer->dl_tti_req != 0)
+ {
+ deallocate_nfapi_dl_tti_request(tx_slot_buffer->dl_tti_req, pnf_p7);
+ tx_slot_buffer->dl_tti_req = 0;
+ }
+
+ if(tx_slot_buffer->tx_data_req != 0)
+ {
+ deallocate_nfapi_tx_data_request(tx_slot_buffer->tx_data_req, pnf_p7);
+ tx_slot_buffer->tx_data_req = 0;
+ }
+
+ if(tx_slot_buffer->ul_dci_req != 0)
+ {
+ deallocate_nfapi_ul_dci_request(tx_slot_buffer->ul_dci_req, pnf_p7);
+ tx_slot_buffer->ul_dci_req = 0;
+ }
+ else
+ {
+ // If we ever need to "send" a dummy ul_config this won't work!!!
+ // send_dummy_subframe(pnf_p7, sfn_sf_tx);
+
+ // send_dummy_slot(pnf_p7, sfn_tx, slot_tx);
+ }
+
+
+
+ if(slot_buffer->sfn == sfn && slot_buffer->slot == slot )
+ {
+
+ if(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), slot_buffer->ul_tti_req);
+ }
+ //deallocate_nfapi_ul_config_request(subframe_buffer->ul_config_req, pnf_p7);
+ }
+ 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;
+ pnf_p7->_public.dummy_slot.ul_tti_req->Slot = slot;
+ (pnf_p7->_public.ul_tti_req_fn)(NULL, &(pnf_p7->_public), pnf_p7->_public.dummy_slot.ul_tti_req);
+ }
+ }
+ //if(subframe_buffer->dl_config_req != 0)
+ //deallocate_nfapi_dl_config_request(subframe_buffer->dl_config_req, pnf_p7);
+ //if(subframe_buffer->tx_req != 0)
+ //deallocate_nfapi_tx_request(subframe_buffer->tx_req, pnf_p7);
+ if(slot_buffer->ul_tti_req != 0)
+ {
+ deallocate_nfapi_ul_tti_request(slot_buffer->ul_tti_req, pnf_p7);
+ slot_buffer->ul_tti_req = 0;
+
+ }
+ #if 0
+ if(slot_buffer->lbt_dl_config_req != 0)
+ {
+ deallocate_nfapi_lbt_dl_config_request(slot_buffer->lbt_dl_config_req, pnf_p7);
+ slot_buffer->lbt_dl_config_req = 0;
+ }
+ #endif
+ } // sfn_slot match
+
+
+ if ( slot_buffer->dl_tti_req == 0 &&
+ slot_buffer->tx_data_req == 0 &&
+ slot_buffer->ul_tti_req == 0)
+ //slot_buffer->lbt_dl_config_req == 0 &&
+ //slot_buffer->ue_release_req == 0)
+ {
+ memset(&(pnf_p7->slot_buffer[buffer_index]), 0, sizeof(nfapi_pnf_p7_slot_buffer_t));
+ pnf_p7->slot_buffer[buffer_index].sfn = -1;
+ pnf_p7->slot_buffer[buffer_index].slot = -1;
+ }
+
+ //printf("pnf_p7->_public.timing_info_mode_periodic:%d pnf_p7->timing_info_period_counter:%d pnf_p7->_public.timing_info_period:%d\n", pnf_p7->_public.timing_info_mode_periodic, pnf_p7->timing_info_period_counter, pnf_p7->_public.timing_info_period);
+ //printf("pnf_p7->_public.timing_info_mode_aperiodic:%d pnf_p7->timing_info_aperiodic_send:%d\n", pnf_p7->_public.timing_info_mode_aperiodic, pnf_p7->timing_info_aperiodic_send);
+ //printf("pnf_p7->timing_info_ms_counter:%d\n", pnf_p7->timing_info_ms_counter);
+
+ // send the periodic timing info if configured
+ if(pnf_p7->_public.timing_info_mode_periodic && (pnf_p7->timing_info_period_counter++) == pnf_p7->_public.timing_info_period)
+ {
+ pnf_nr_pack_and_send_timing_info(pnf_p7);
+
+ pnf_p7->timing_info_period_counter = 0;
+ }
+ else if(pnf_p7->_public.timing_info_mode_aperiodic && pnf_p7->timing_info_aperiodic_send)
+ {
+ pnf_nr_pack_and_send_timing_info(pnf_p7);
+
+ pnf_p7->timing_info_aperiodic_send = 0;
+ }
+ else
+ {
+ pnf_p7->timing_info_ms_counter++;
+ }
+
+ }
+ else
+ {
+ //send_dummy_subframe(pnf_p7, sfn_sf_tx);
+ }
+
+
+ //printf("pnf_p7->tick:%d\n", pnf_p7->tick);
+ // if(pnf_p7->tick == 1000) // why?
+ // {
+ // // TODO: change stats to nr_stats
+ // NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF P7:%d] (ONTIME/LATE) DL:(%d/%d) UL:(%d/%d) HI:(%d/%d) TX:(%d/%d)\n", pnf_p7->_public.phy_id,
+ // pnf_p7->stats.dl_conf_ontime, pnf_p7->stats.dl_conf_late,
+ // pnf_p7->stats.ul_conf_ontime, pnf_p7->stats.ul_conf_late,
+ // pnf_p7->stats.hi_dci0_ontime, pnf_p7->stats.hi_dci0_late,
+ // pnf_p7->stats.tx_ontime, pnf_p7->stats.tx_late);
+ // pnf_p7->tick = 0;
+ // memset(&pnf_p7->stats, 0, sizeof(pnf_p7->stats));
+ // }
+ // pnf_p7->tick++;
+
+
+ if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+
int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf)
{
// We could either send an event to the p7 thread have have it run the
@@ -621,8 +1221,8 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf)
pnf_p7->sf_start_time_hr = pnf_get_current_time_hr();
pnf_p7->sfn_sf = sfn_sf;
- uint32_t sfn_sf_tx = sfnsf_add_sf(sfn_sf, sf_ahead);
- uint32_t tx_sfn_sf_dec = NFAPI_SFNSF2DEC(sfn_sf_tx);
+ uint32_t sfn_sf_tx = sfnsf_add_sf(sfn_sf, sf_ahead);
+ uint32_t tx_sfn_sf_dec = NFAPI_SFNSF2DEC(sfn_sf_tx);
// If the subframe_buffer has been configured
if(pnf_p7->_public.subframe_buffer_size != 0)
@@ -890,6 +1490,82 @@ int pnf_p7_subframe_ind(pnf_p7_t* pnf_p7, uint16_t phy_id, uint16_t sfn_sf)
// return 1 if in window
// return 0 if out of window
+
+uint8_t is_nr_p7_request_in_window(uint16_t sfn,uint16_t slot, const char* name, pnf_p7_t* phy)
+{
+ uint32_t recv_sfn_slot_dec = NFAPI_SFNSLOT2DEC(sfn,slot);
+ uint32_t current_sfn_slot_dec = NFAPI_SFNSLOT2DEC(phy->sfn,phy->slot);
+ printf("p7_msg_sfn: %d, p7_msg_slot: %d, phy_sfn:%d , phy_slot:%d \n",sfn,slot,phy->sfn,phy->slot);
+ uint8_t in_window = 0;
+ uint8_t timing_window = phy->_public.slot_buffer_size;
+
+ // if(recv_sfn_slot_dec <= current_sfn_slot_dec)
+ // {
+ // // Need to check for wrap in window
+ // if(((recv_sfn_slot_dec + timing_window) % NFAPI_MAX_SFNSLOTDEC) < recv_sfn_slot_dec)
+ // {
+ // if(current_sfn_slot_dec > ((recv_sfn_slot_dec + timing_window) % NFAPI_MAX_SFNSLOTDEC))
+ // {
+ // // out of window
+ // NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is late %d (with wrap)\n", current_sfn_slot_dec, name, recv_sfn_slot_dec);
+ // }
+ // else
+ // {
+ // // ok
+ // //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is in window %d (with wrap)\n", current_sfn_sf_dec, name, recv_sfn_sf_dec);
+ // in_window = 1;
+ // }
+ // }
+ // else
+ // {
+ // if((current_sfn_slot_dec - recv_sfn_slot_dec) <= timing_window)
+ // {
+ // // in window
+ // //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is in window %d\n", current_sfn_slot_dec, name, recv_sfn_slot_dec);
+ // in_window = 1;
+ // }
+ // //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is in late %d (delta:%d)\n", current_sfn_slot_dec, name, recv_sfn_slot_dec, (current_sfn_slot_dec - recv_sfn_slot_dec));
+ // }
+
+ // }
+ // else
+ // {
+ // // Need to check it is in window
+ // if((recv_sfn_slot_dec - current_sfn_slot_dec) <= timing_window)
+ // {
+ // // in window
+ // //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is in window %d\n", current_sfn_sf_dec, name, recv_sfn_sf_dec);
+ // in_window = 1;
+ // }
+ // else
+ // {
+ // // too far in the future
+ // NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is out of window %d (delta:%d) [max:%d]\n", current_sfn_slot_dec, name, recv_sfn_slot_dec, (recv_sfn_slot_dec - current_sfn_slot_dec), timing_window);
+ // }
+
+ // }
+ if(current_sfn_slot_dec <= recv_sfn_slot_dec + timing_window){
+ in_window = 1;
+ NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is in window %d\n", current_sfn_slot_dec, name, recv_sfn_slot_dec);
+ }
+ else if(current_sfn_slot_dec + NFAPI_MAX_SFNSLOTDEC <= recv_sfn_slot_dec + timing_window){ //checking for wrap
+ in_window = 1;
+ NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is in window %d\n", current_sfn_slot_dec, name, recv_sfn_slot_dec);
+ }
+
+ else
+ {
+
+ NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] %s is out of window %d (delta:%d) [max:%d]\n", current_sfn_slot_dec, name, recv_sfn_slot_dec, (current_sfn_slot_dec - recv_sfn_slot_dec), timing_window);
+
+ }//Need to add more cases
+
+
+ return in_window;
+}
+
+
+
uint8_t is_p7_request_in_window(uint16_t sfnsf, const char* name, pnf_p7_t* phy)
{
uint32_t recv_sfn_sf_dec = NFAPI_SFNSF2DEC(sfnsf);
@@ -943,8 +1619,97 @@ uint8_t is_p7_request_in_window(uint16_t sfnsf, const char* name, pnf_p7_t* phy)
}
-// P7 messages
-//
+// P7 messages
+void pnf_handle_dl_tti_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7)
+{
+ //NFAPI_TRACE(NFAPI_TRACE_INFO, "DL_CONFIG.req Received\n");
+ nfapi_nr_dl_tti_request_t* req = allocate_nfapi_dl_tti_request(pnf_p7);
+
+ if(req == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to alloced 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));
+
+ if(unpack_result == 0)
+ {
+ if(pthread_mutex_lock(&(pnf_p7->mutex)) != 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n");
+ return;
+ }
+#if 0
+ if (
+ 0 &&
+ (NFAPI_SFNSF2DEC(req->sfn_sf) % 100 ==0 ||
+ NFAPI_SFNSF2DEC(req->sfn_sf) % 105 ==0
+ )
+ )
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "DL_CONFIG.req sfn_sf:%d pdcch:%u dci:%u pdu:%u pdsch_rnti:%u pcfich:%u\n",
+ NFAPI_SFNSF2DEC(req->sfn_sf),
+ req->dl_config_request_body.number_pdcch_ofdm_symbols,
+ req->dl_config_request_body.number_dci,
+ req->dl_config_request_body.number_pdu,
+ req->dl_config_request_body.number_pdsch_rnti,
+ req->dl_config_request_body.transmission_power_pcfich
+ );
+#endif
+
+ if(is_nr_p7_request_in_window(req->SFN,req->Slot, "dl_tti_request", pnf_p7))
+ {
+ uint32_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(req->SFN,req->Slot);
+ uint8_t buffer_index = sfn_slot_dec % pnf_p7->_public.slot_buffer_size;
+
+ struct timespec t;
+ clock_gettime(CLOCK_MONOTONIC, &t);
+
+ //NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() %ld.%09ld POPULATE DL_TTI_REQ sfn_slot:%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, sfn_slot_dec, buffer_index);
+
+ // if there is already an dl_config_req make sure we free it.
+ if(pnf_p7->slot_buffer[buffer_index].dl_tti_req != 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_NOTE, "%s() is_nr_p7_request_in_window()=TRUE buffer_index occupied - free it first sfn_slot:%d buffer_index:%d\n", __FUNCTION__, NFAPI_SFNSLOT2DEC(req->SFN,req->Slot), buffer_index);
+ //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] Freeing dl_config_req at index %d (%d/%d)",
+ // pMyPhyInfo->sfnSf, bufferIdx,
+ // SFNSF2SFN(dreq->sfn_sf), SFNSF2SF(dreq->sfn_sf));
+ deallocate_nfapi_dl_tti_request(pnf_p7->slot_buffer[buffer_index].dl_tti_req, pnf_p7);
+ }
+
+ // saving dl_config_request in subframe buffer
+ pnf_p7->slot_buffer[buffer_index].sfn = req->SFN;
+ pnf_p7->slot_buffer[buffer_index].slot = req->Slot;
+ pnf_p7->slot_buffer[buffer_index].dl_tti_req = req;
+
+ pnf_p7->stats.dl_tti_ontime++;
+ }
+ else
+ {
+ //NFAPI_TRACE(NFAPI_TRACE_NOTE, "NOT storing dl_config_req SFN/SF %d\n", req->sfn_sf);
+ deallocate_nfapi_dl_tti_request(req, pnf_p7);
+
+ if(pnf_p7->_public.timing_info_mode_aperiodic)
+ {
+ pnf_p7->timing_info_aperiodic_send = 1;
+ }
+
+ pnf_p7->stats.dl_tti_late++;
+ }
+ if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n");
+ return;
+ }
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to unpack dl_tti_req");
+ deallocate_nfapi_dl_tti_request(req, pnf_p7);
+ }
+}
+
+
void pnf_handle_dl_config_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7)
{
//NFAPI_TRACE(NFAPI_TRACE_INFO, "DL_CONFIG.req Received\n");
@@ -1035,6 +1800,80 @@ void pnf_handle_dl_config_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_
}
}
+
+void pnf_handle_ul_tti_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7)
+{
+ //NFAPI_TRACE(NFAPI_TRACE_INFO, "UL_CONFIG.req Received\n");
+
+ nfapi_nr_ul_tti_request_t* req = allocate_nfapi_ul_tti_request(pnf_p7);
+
+ if(req == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to alloced nfapi_ul_tti_request structure\n");
+ return;
+ }
+
+ int unpack_result = nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, req, sizeof(nfapi_nr_ul_tti_request_t), &(pnf_p7->_public.codec_config));
+
+ if(unpack_result == 0)
+ {
+ if(pthread_mutex_lock(&(pnf_p7->mutex)) != 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n");
+ return;
+ }
+
+ if(is_nr_p7_request_in_window(req->SFN,req->Slot, "ul_tti_request", pnf_p7))
+ {
+ uint32_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(req->SFN,req->Slot);
+ uint8_t buffer_index = sfn_slot_dec % pnf_p7->_public.slot_buffer_size;
+
+ struct timespec t;
+ clock_gettime(CLOCK_MONOTONIC, &t);
+
+ NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() %ld.%09ld POPULATE UL_TTI_REQ sfn_slot:%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, sfn_slot_dec, buffer_index);
+
+ if(pnf_p7->slot_buffer[buffer_index].ul_tti_req != 0)
+ {
+ //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] Freeing ul_config_req at index %d (%d/%d)",
+ // pMyPhyInfo->sfnSf, bufferIdx,
+ // SFNSF2SFN(dreq->sfn_sf), SFNSF2SF(dreq->sfn_sf));
+
+ deallocate_nfapi_ul_tti_request(pnf_p7->slot_buffer[buffer_index].ul_tti_req, pnf_p7);
+ }
+
+ pnf_p7->slot_buffer[buffer_index].sfn = req->SFN;
+ pnf_p7->slot_buffer[buffer_index].slot = req->Slot;
+ pnf_p7->slot_buffer[buffer_index].ul_tti_req = req;
+
+ pnf_p7->stats.ul_tti_ontime++;
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] NOT storing ul_tti_req OUTSIDE OF TRANSMIT BUFFER WINDOW SFN/SLOT %d\n", NFAPI_SFNSLOT2DEC(pnf_p7->sfn,pnf_p7->slot), NFAPI_SFNSLOT2DEC(req->SFN,req->Slot));
+ deallocate_nfapi_ul_tti_request(req, pnf_p7);
+
+ if(pnf_p7->_public.timing_info_mode_aperiodic)
+ {
+ pnf_p7->timing_info_aperiodic_send = 1;
+ }
+
+ pnf_p7->stats.ul_tti_late++;
+ }
+
+ if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n");
+ return;
+ }
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to unpack ul_tti_req\n");
+ deallocate_nfapi_ul_tti_request(req, pnf_p7);
+ }
+}
+
void pnf_handle_ul_config_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7)
{
//NFAPI_TRACE(NFAPI_TRACE_INFO, "UL_CONFIG.req Received\n");
@@ -1107,7 +1946,79 @@ void pnf_handle_ul_config_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_
}
}
+
+void pnf_handle_ul_dci_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7)
+{
+ //NFAPI_TRACE(NFAPI_TRACE_INFO, "HI_DCI0.req Received\n");
+
+ nfapi_nr_ul_dci_request_t* req = allocate_nfapi_ul_dci_request(pnf_p7);
+
+ if(req == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to allocate nfapi_ul_dci_request structure\n");
+ return;
+ }
+
+ int unpack_result = nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, req, sizeof(nfapi_nr_ul_dci_request_t), &pnf_p7->_public.codec_config);
+
+ if(unpack_result == 0)
+ {
+ if(pthread_mutex_lock(&(pnf_p7->mutex)) != 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n");
+ return;
+ }
+
+ if(is_nr_p7_request_in_window(req->SFN,req->Slot,"ul_dci_request", pnf_p7))
+ {
+ uint32_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(req->SFN,req->Slot);
+ uint8_t buffer_index = sfn_slot_dec % pnf_p7->_public.slot_buffer_size;
+
+ if(pnf_p7->slot_buffer[buffer_index].ul_dci_req!= 0)
+ {
+ //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] Freeing hi_dci0_req at index %d (%d/%d)",
+ // pMyPhyInfo->sfnSf, bufferIdx,
+ // SFNSF2SFN(dreq->sfn_sf), SFNSF2SF(dreq->sfn_sf));
+
+ deallocate_nfapi_ul_dci_request(pnf_p7->slot_buffer[buffer_index].ul_dci_req, pnf_p7);
+ }
+
+ pnf_p7->slot_buffer[buffer_index].sfn = req->SFN;
+ pnf_p7->slot_buffer[buffer_index].ul_dci_req = req;
+
+ pnf_p7->stats.ul_dci_ontime++;
+
+ }
+ else
+ {
+ //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] NOT storing hi_dci0_req SFN/SF %d/%d\n", pMyPhyInfo->sfnSf, SFNSF2SFN(req->sfn_sf), SFNSF2SF(req->sfn_sf));
+ deallocate_nfapi_ul_dci_request(req, pnf_p7);
+
+ if(pnf_p7->_public.timing_info_mode_aperiodic)
+ {
+ pnf_p7->timing_info_aperiodic_send = 1;
+ }
+
+ pnf_p7->stats.ul_dci_late++;
+ }
+
+ if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n");
+ return;
+ }
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to unpack hi_dci0_req\n");
+ deallocate_nfapi_ul_dci_request(req, pnf_p7);
+ }
+}
+
+
+
void pnf_handle_hi_dci0_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7)
+
{
//NFAPI_TRACE(NFAPI_TRACE_INFO, "HI_DCI0.req Received\n");
@@ -1175,6 +2086,87 @@ void pnf_handle_hi_dci0_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7
}
}
+
+void pnf_handle_tx_data_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7)
+{
+ //NFAPI_TRACE(NFAPI_TRACE_INFO, "TX.req Received\n");
+
+ nfapi_nr_tx_data_request_t* req = allocate_nfapi_tx_data_request(pnf_p7);
+
+ if(req == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to alloced nfapi_tx_request structure\n");
+ return;
+ }
+
+ int unpack_result = nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, req, sizeof(nfapi_nr_tx_data_request_t), &pnf_p7->_public.codec_config);
+ if(unpack_result == 0)
+ {
+ if(pthread_mutex_lock(&(pnf_p7->mutex)) != 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n");
+ return;
+ }
+
+ if(is_nr_p7_request_in_window(req->SFN, req->Slot,"tx_request", pnf_p7))
+ {
+ uint32_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(req->SFN,req->Slot);
+ uint8_t buffer_index = sfn_slot_dec % pnf_p7->_public.slot_buffer_size;
+
+ struct timespec t;
+ clock_gettime(CLOCK_MONOTONIC, &t);
+
+ NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() %ld.%09ld POPULATE TX_DATA_REQ sfn_sf:%d buffer_index:%d\n", __FUNCTION__, t.tv_sec, t.tv_nsec, sfn_slot_dec, buffer_index);
+#if 0
+ if (0 && NFAPI_SFNSF2DEC(req->sfn_sf)%100==0) NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() TX_REQ.req sfn_sf:%d pdus:%d - TX_REQ is within window\n",
+ __FUNCTION__,
+ NFAPI_SFNSF2DEC(req->sfn_sf),
+ req->tx_request_body.number_of_pdus);
+#endif
+
+ if(pnf_p7->slot_buffer[buffer_index].tx_data_req != 0)
+ {
+ //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[%d] Freeing tx_req at index %d (%d/%d)",
+ // pMyPhyInfo->sfnSf, bufferIdx,
+ // SFNSF2SFN(dreq->sfn_sf), SFNSF2SF(dreq->sfn_sf));
+
+ deallocate_nfapi_tx_data_request(pnf_p7->slot_buffer[buffer_index].tx_data_req, pnf_p7);
+ }
+
+ pnf_p7->slot_buffer[buffer_index].sfn = req->SFN;
+ pnf_p7->slot_buffer[buffer_index].slot = req->Slot;
+ pnf_p7->slot_buffer[buffer_index].tx_data_req = req;
+
+ pnf_p7->stats.tx_data_ontime++;
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO,"%s() TX_DATA_REQUEST Request is outside of window REQ:SFN_SLOT:%d CURR:SFN_SLOT:%d\n", __FUNCTION__, NFAPI_SFNSLOT2DEC(req->SFN,req->Slot), NFAPI_SFNSLOT2DEC(pnf_p7->sfn,pnf_p7->slot));
+
+ deallocate_nfapi_tx_data_request(req, pnf_p7);
+
+ if(pnf_p7->_public.timing_info_mode_aperiodic)
+ {
+ pnf_p7->timing_info_aperiodic_send = 1;
+ }
+
+ pnf_p7->stats.tx_data_late++;
+ }
+
+ if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n");
+ return;
+ }
+ }
+ else
+ {
+ deallocate_nfapi_tx_data_request(req, pnf_p7);
+ }
+}
+
+
+
void pnf_handle_tx_request(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7)
{
//NFAPI_TRACE(NFAPI_TRACE_INFO, "TX.req Received\n");
@@ -1437,6 +2429,29 @@ uint32_t calculate_t2(uint32_t now_time_hr, uint16_t sfn_sf, uint32_t sf_start_t
return t2;
}
+uint32_t calculate_nr_t2(uint32_t now_time_hr, uint16_t sfn,uint16_t slot, uint32_t slot_start_time_hr)
+{
+ uint32_t slot_time_us = get_slot_time(now_time_hr, slot_start_time_hr);
+ uint32_t t2 = (NFAPI_SFNSLOT2DEC(sfn, slot) * 500) + slot_time_us;
+
+ if (0)
+ {
+ 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",
+ __FUNCTION__,
+ now_time_hr, NFAPI_SFNSLOT2DEC(sfn, slot), slot_start_time_hr,
+ slot_time_us,
+ t2,
+ prev_t2,
+ t2-prev_t2);
+
+ prev_t2 = t2;
+ }
+
+ return t2;
+}
+
uint32_t calculate_t3(uint16_t sfn_sf, uint32_t sf_start_time_hr)
{
uint32_t now_time_hr = pnf_get_current_time_hr();
@@ -1448,6 +2463,17 @@ uint32_t calculate_t3(uint16_t sfn_sf, uint32_t sf_start_time_hr)
return t3;
}
+uint32_t calculate_nr_t3(uint16_t sfn, uint16_t slot, uint32_t slot_start_time_hr)
+{
+ uint32_t now_time_hr = pnf_get_current_time_hr();
+
+ uint32_t slot_time_us = get_slot_time(now_time_hr, slot_start_time_hr);
+
+ uint32_t t3 = (NFAPI_SFNSLOT2DEC(sfn, slot) * 500) + slot_time_us;
+
+ return t3;
+}
+
void pnf_handle_dl_node_sync(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, uint32_t rx_hr_time)
{
nfapi_dl_node_sync_t dl_node_sync;
@@ -1498,6 +2524,60 @@ void pnf_handle_dl_node_sync(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, u
pnf_p7_pack_and_send_p7_message(pnf_p7, &(ul_node_sync.header), sizeof(ul_node_sync));
}
+
+void pnf_nr_handle_dl_node_sync(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, uint32_t rx_hr_time)
+{
+ //printf("Received DL node sync");
+
+ nfapi_nr_dl_node_sync_t dl_node_sync;
+
+ //NFAPI_TRACE(NFAPI_TRACE_INFO, "DL_NODE_SYNC Received\n");
+
+ if (pRecvMsg == NULL || pnf_p7 == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
+ return;
+ }
+
+ // unpack the message
+ if (nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, &dl_node_sync, sizeof(dl_node_sync), &pnf_p7->_public.codec_config) < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
+ return;
+ }
+
+ if(pthread_mutex_lock(&(pnf_p7->mutex)) != 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n");
+ return;
+ }
+
+
+ if (dl_node_sync.delta_sfn_slot != 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "Will shift Slot timing by %d on next slot\n", dl_node_sync.delta_sfn_slot);
+
+ pnf_p7->slot_shift = dl_node_sync.delta_sfn_slot;
+ }
+
+ nfapi_nr_ul_node_sync_t ul_node_sync;
+ memset(&ul_node_sync, 0, sizeof(ul_node_sync));
+ ul_node_sync.header.message_id = NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC;
+ ul_node_sync.header.phy_id = dl_node_sync.header.phy_id;
+ ul_node_sync.t1 = dl_node_sync.t1;
+ ul_node_sync.t2 = calculate_nr_t2(rx_hr_time, pnf_p7->sfn,pnf_p7->slot, pnf_p7->slot_start_time_hr);
+ ul_node_sync.t3 = calculate_nr_t3(pnf_p7->sfn,pnf_p7->slot, pnf_p7->slot_start_time_hr);
+
+ if(pthread_mutex_unlock(&(pnf_p7->mutex)) != 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n");
+ return;
+ }
+
+ pnf_nr_p7_pack_and_send_p7_message(pnf_p7, &(ul_node_sync.header), sizeof(ul_node_sync));
+ //printf("\nSSent UL Node Sync sfn:%d,slot:%d\n",pnf_p7->sfn,pnf_p7->slot);
+}
+
void pnf_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, uint32_t rx_hr_time)
{
nfapi_p7_message_header_t header;
@@ -1528,7 +2608,6 @@ void pnf_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7,
case NFAPI_DL_NODE_SYNC:
pnf_handle_dl_node_sync(pRecvMsg, recvMsgLen, pnf_p7, rx_hr_time);
break;
-
case NFAPI_DL_CONFIG_REQUEST:
pnf_handle_dl_config_request(pRecvMsg, recvMsgLen, pnf_p7);
break;
@@ -1544,7 +2623,7 @@ void pnf_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7,
case NFAPI_TX_REQUEST:
pnf_handle_tx_request(pRecvMsg, recvMsgLen, pnf_p7);
break;
-
+
case NFAPI_LBT_DL_CONFIG_REQUEST:
pnf_handle_lbt_dl_config_request(pRecvMsg, recvMsgLen, pnf_p7);
break;
@@ -1569,6 +2648,66 @@ void pnf_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7,
}
}
+void pnf_nr_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, uint32_t rx_hr_time)
+{
+ nfapi_p7_message_header_t header;
+
+ // validate the input params
+ if(pRecvMsg == NULL || recvMsgLen < 4 || pnf_p7 == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
+ return;
+ }
+
+ // unpack the message header
+ if (nfapi_p7_message_header_unpack(pRecvMsg, recvMsgLen, &header, sizeof(header), &pnf_p7->_public.codec_config) < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n");
+ return;
+ }
+
+ // ensure the message is sensible
+ if (recvMsgLen < 8 || pRecvMsg == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_WARN, "Invalid message size: %d, ignoring\n", recvMsgLen);
+ return;
+ }
+
+ switch (header.message_id)
+ {
+ case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
+ pnf_nr_handle_dl_node_sync(pRecvMsg, recvMsgLen, pnf_p7, rx_hr_time);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
+ //printf("\nEntering pnf_handle_dl_tti_request sfn=%d,slot=%d \n",pnf_p7->sfn,pnf_p7->slot);
+ pnf_handle_dl_tti_request(pRecvMsg, recvMsgLen, pnf_p7);
+ break;
+ case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
+ pnf_handle_ul_tti_request(pRecvMsg, recvMsgLen, pnf_p7);
+ break;
+ case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
+ pnf_handle_ul_dci_request(pRecvMsg, recvMsgLen, pnf_p7);
+ break;
+ case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
+ pnf_handle_tx_data_request(pRecvMsg, recvMsgLen, pnf_p7);
+ break;
+ default:
+ {
+ if(header.message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
+ header.message_id <= NFAPI_VENDOR_EXT_MSG_MAX)
+ {
+ pnf_handle_p7_vendor_extension(pRecvMsg, recvMsgLen, pnf_p7, header.message_id);
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s P7 Unknown message ID %d\n", __FUNCTION__, header.message_id);
+ }
+ }
+ break;
+ }
+}
+
void pnf_handle_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, uint32_t rx_hr_time)
{
nfapi_p7_message_header_t messageHeader;
@@ -1674,6 +2813,114 @@ void pnf_handle_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, ui
pnf_p7_rx_reassembly_queue_remove_old_msgs(pnf_p7, &(pnf_p7->reassembly_queue), rx_hr_time, 1000);
}
+
+void pnf_nr_handle_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, uint32_t rx_hr_time)
+{
+ nfapi_p7_message_header_t messageHeader;
+
+ // 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);
+ return;
+ }
+
+ // unpack the message header
+ if (nfapi_p7_message_header_unpack(pRecvMsg, recvMsgLen, &messageHeader, sizeof(nfapi_p7_message_header_t), &pnf_p7->_public.codec_config) < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n");
+ return;
+ }
+
+ uint8_t m = NFAPI_P7_GET_MORE(messageHeader.m_segment_sequence);
+ uint8_t sequence_num = NFAPI_P7_GET_SEQUENCE(messageHeader.m_segment_sequence);
+ uint8_t segment_num = NFAPI_P7_GET_SEGMENT(messageHeader.m_segment_sequence);
+
+ if(pnf_p7->_public.checksum_enabled)
+ {
+ uint32_t checksum = nfapi_p7_calculate_checksum(pRecvMsg, recvMsgLen);
+ if(checksum != messageHeader.checksum)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "Checksum verification failed %d %d\n", checksum, messageHeader.checksum);
+ return;
+ }
+ }
+
+ if(m == 0 && segment_num == 0)
+ {
+ // we have a complete message
+ // ensure the message is sensible
+ if (recvMsgLen < 8 || pRecvMsg == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_WARN, "Invalid message size: %d, ignoring\n", recvMsgLen);
+ return;
+ }
+
+ pnf_nr_dispatch_p7_message(pRecvMsg, recvMsgLen, pnf_p7, rx_hr_time);
+ }
+ else
+ {
+ pnf_p7_rx_message_t* rx_msg = pnf_p7_rx_reassembly_queue_add_segment(pnf_p7, &(pnf_p7->reassembly_queue), rx_hr_time, sequence_num, segment_num, m, pRecvMsg, recvMsgLen);
+
+ if(rx_msg->num_segments_received == rx_msg->num_segments_expected)
+ {
+ // send the buffer on
+ uint16_t i = 0;
+ uint16_t length = 0;
+ for(i = 0; i < rx_msg->num_segments_expected; ++i)
+ {
+ length += rx_msg->segments[i].length - (i > 0 ? NFAPI_P7_HEADER_LENGTH : 0);
+ }
+
+ if(pnf_p7->reassemby_buffer_size < length)
+ {
+ pnf_p7_free(pnf_p7, pnf_p7->reassemby_buffer);
+ pnf_p7->reassemby_buffer = 0;
+ }
+
+ if(pnf_p7->reassemby_buffer == 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_NOTE, "Resizing PNF_P7 Reassembly buffer %d->%d\n", pnf_p7->reassemby_buffer_size, length);
+ pnf_p7->reassemby_buffer = (uint8_t*)pnf_p7_malloc(pnf_p7, length);
+
+ if(pnf_p7->reassemby_buffer == 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_NOTE, "Failed to allocate PNF_P7 reassemby buffer len:%d\n", length);
+ return;
+ }
+ memset(pnf_p7->reassemby_buffer, 0, length);
+ pnf_p7->reassemby_buffer_size = length;
+ }
+
+ uint16_t offset = 0;
+ for(i = 0; i < rx_msg->num_segments_expected; ++i)
+ {
+ if(i == 0)
+ {
+ memcpy(pnf_p7->reassemby_buffer, rx_msg->segments[i].buffer, rx_msg->segments[i].length);
+ offset += rx_msg->segments[i].length;
+ }
+ else
+ {
+ memcpy(pnf_p7->reassemby_buffer + offset, rx_msg->segments[i].buffer + NFAPI_P7_HEADER_LENGTH, rx_msg->segments[i].length - NFAPI_P7_HEADER_LENGTH);
+ offset += rx_msg->segments[i].length - NFAPI_P7_HEADER_LENGTH;
+ }
+ }
+
+
+ pnf_nr_dispatch_p7_message(pnf_p7->reassemby_buffer, length, pnf_p7, rx_msg->rx_hr_time);
+
+
+ // delete the structure
+ pnf_p7_rx_reassembly_queue_remove_msg(pnf_p7, &(pnf_p7->reassembly_queue), rx_msg);
+ }
+ }
+
+ pnf_p7_rx_reassembly_queue_remove_old_msgs(pnf_p7, &(pnf_p7->reassembly_queue), rx_hr_time, 1000);
+
+}
+
+
void pnf_nfapi_p7_read_dispatch_message(pnf_p7_t* pnf_p7, uint32_t now_hr_time)
{
int recvfrom_result = 0;
@@ -1708,6 +2955,7 @@ void pnf_nfapi_p7_read_dispatch_message(pnf_p7_t* pnf_p7, uint32_t now_hr_time)
if(recvfrom_result > 0)
{
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);
}
}
else if(recvfrom_result == 0)
@@ -1735,6 +2983,70 @@ void pnf_nfapi_p7_read_dispatch_message(pnf_p7_t* pnf_p7, uint32_t now_hr_time)
while(recvfrom_result > 0);
}
+void pnf_nr_nfapi_p7_read_dispatch_message(pnf_p7_t* pnf_p7, uint32_t now_hr_time)
+{
+ int recvfrom_result = 0;
+ struct sockaddr_in remote_addr;
+ socklen_t remote_addr_size = sizeof(remote_addr);
+ remote_addr.sin_family = 2; //hardcoded
+
+ do
+ {
+ // peek the header
+ uint8_t header_buffer[NFAPI_P7_HEADER_LENGTH];
+ recvfrom_result = recvfrom(pnf_p7->p7_sock, header_buffer, NFAPI_P7_HEADER_LENGTH, MSG_DONTWAIT | MSG_PEEK, (struct sockaddr*)&remote_addr, &remote_addr_size);
+
+ if(recvfrom_result > 0)
+ {
+ // get the segment size
+ nfapi_p7_message_header_t header;
+ nfapi_p7_message_header_unpack(header_buffer, NFAPI_P7_HEADER_LENGTH, &header, 34, 0);
+
+ // resize the buffer if we have a large segment
+ if(header.message_length > pnf_p7->rx_message_buffer_size)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_NOTE, "reallocing rx buffer %d\n", header.message_length);
+ pnf_p7->rx_message_buffer = realloc(pnf_p7->rx_message_buffer, header.message_length);
+ pnf_p7->rx_message_buffer_size = header.message_length;
+ }
+
+ // 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);
+
+ now_hr_time = pnf_get_current_time_hr(); //DJP - moved to here - get closer timestamp???
+
+ if(recvfrom_result > 0)
+ {
+ pnf_nr_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);
+ }
+ }
+ else if(recvfrom_result == 0)
+ {
+ // recv zero length message
+ recvfrom_result = recvfrom(pnf_p7->p7_sock, header_buffer, 0, MSG_DONTWAIT, (struct sockaddr*)&remote_addr, &remote_addr_size);
+ }
+
+ if(recvfrom_result == -1)
+ {
+ if(errno == EAGAIN || errno == EWOULDBLOCK)
+ {
+ // return to the select
+ //NFAPI_TRACE(NFAPI_TRACE_WARN, "%s recvfrom would block :%d\n", __FUNCTION__, errno);
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_WARN, "%s recvfrom failed errno:%d\n", __FUNCTION__, errno);
+ }
+ }
+
+ // need to update the time as we would only use the value from the
+ // select
+ }
+ while(recvfrom_result > 0);
+}
+
+
int pnf_p7_message_pump(pnf_p7_t* pnf_p7)
{
@@ -1786,7 +3098,7 @@ int pnf_p7_message_pump(pnf_p7_t* pnf_p7)
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
- addr.sin_port = htons(pnf_p7->_public.local_p7_port);
+ addr.sin_port = pnf_p7->_public.local_p7_port;
if(pnf_p7->_public.local_p7_addr == 0)
{
@@ -1827,6 +3139,9 @@ int pnf_p7_message_pump(pnf_p7_t* pnf_p7)
uint32_t now_hr_time = pnf_get_current_time_hr();
+
+
+
if(selectRetval == 0)
{
// timeout
@@ -1845,7 +3160,8 @@ int pnf_p7_message_pump(pnf_p7_t* pnf_p7)
continue;
}
- if(FD_ISSET(pnf_p7->p7_sock, &rfds))
+ if(FD_ISSET(pnf_p7->p7_sock, &rfds))
+
{
pnf_nfapi_p7_read_dispatch_message(pnf_p7, now_hr_time);
}
@@ -1870,3 +3186,143 @@ int pnf_p7_message_pump(pnf_p7_t* pnf_p7)
return 0;
}
+
+int pnf_nr_p7_message_pump(pnf_p7_t* pnf_p7)
+{
+
+ // initialize the mutex lock
+ if(pthread_mutex_init(&(pnf_p7->mutex), NULL) != 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "After P7 mutex init: %d\n", errno);
+ return -1;
+ }
+
+ if(pthread_mutex_init(&(pnf_p7->pack_mutex), NULL) != 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "After P7 mutex init: %d\n", errno);
+ return -1;
+ }
+
+ // create the pnf p7 socket
+ if ((pnf_p7->p7_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "After P7 socket errno: %d\n", errno);
+ return -1;
+ }
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 socket created (%d)...\n", pnf_p7->p7_sock);
+
+ // configure the UDP socket options
+ int reuseaddr_enable = 1;
+ if (setsockopt(pnf_p7->p7_sock, SOL_SOCKET, SO_REUSEADDR, &reuseaddr_enable, sizeof(int)) < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "PNF P7 setsockopt (SOL_SOCKET, SO_REUSEADDR) failed errno: %d\n", errno);
+ return -1;
+ }
+
+/*
+ int reuseport_enable = 1;
+ if (setsockopt(pnf_p7->p7_sock, SOL_SOCKET, SO_REUSEPORT, &reuseport_enable, sizeof(int)) < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "PNF P7 setsockopt (SOL_SOCKET, SO_REUSEPORT) failed errno: %d\n", errno);
+ return -1;
+ }
+*/
+
+ int iptos_value = FAPI2_IP_DSCP << 2;
+ if (setsockopt(pnf_p7->p7_sock, IPPROTO_IP, IP_TOS, &iptos_value, sizeof(iptos_value)) < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "PNF P7 setsockopt (IPPROTO_IP, IP_TOS) failed errno: %d\n", errno);
+ return -1;
+ }
+
+ struct sockaddr_in addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = pnf_p7->_public.local_p7_port;
+
+ if(pnf_p7->_public.local_p7_addr == 0)
+ {
+ addr.sin_addr.s_addr = INADDR_ANY;
+ }
+ else
+ {
+ //addr.sin_addr.s_addr = inet_addr(pnf_p7->_public.local_p7_addr);
+ if(inet_aton(pnf_p7->_public.local_p7_addr, &addr.sin_addr) == -1)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "inet_aton failed\n");
+ }
+ }
+
+
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 binding %d too %s:%d\n", pnf_p7->p7_sock, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
+ if (bind(pnf_p7->p7_sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "PNF_P7 bind error fd:%d errno: %d\n", pnf_p7->p7_sock, errno);
+ return -1;
+ }
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 bind succeeded...\n");
+
+ while(pnf_p7->terminate == 0)
+ {
+ fd_set rfds;
+ int selectRetval = 0;
+
+ // select on a timeout and then get the message
+ FD_ZERO(&rfds);
+ FD_SET(pnf_p7->p7_sock, &rfds);
+
+ struct timeval timeout;
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+
+ selectRetval = select(pnf_p7->p7_sock+1, &rfds, NULL, NULL, &timeout);
+
+ uint32_t now_hr_time = pnf_get_current_time_hr();
+
+
+
+
+ if(selectRetval == 0)
+ {
+ // timeout
+ continue;
+ }
+ else if (selectRetval == -1 && (errno == EINTR))
+ {
+ // interrupted by signal
+ NFAPI_TRACE(NFAPI_TRACE_WARN, "PNF P7 Signal Interrupt %d\n", errno);
+ continue;
+ }
+ else if (selectRetval == -1)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_WARN, "PNF P7 select() failed\n");
+ sleep(1);
+ continue;
+ }
+
+ if(FD_ISSET(pnf_p7->p7_sock, &rfds))
+
+ {
+ pnf_nr_nfapi_p7_read_dispatch_message(pnf_p7, now_hr_time);
+ }
+ }
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "PNF_P7 Terminating..\n");
+
+ // close the connection and socket
+ if (close(pnf_p7->p7_sock) < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "close failed errno: %d\n", errno);
+ }
+
+ if(pthread_mutex_destroy(&(pnf_p7->pack_mutex)) != 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "mutex destroy failed errno: %d\n", errno);
+ }
+
+ if(pthread_mutex_destroy(&(pnf_p7->mutex)) != 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "mutex destroy failed errno: %d\n", errno);
+ }
+
+ return 0;
+}
diff --git a/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c b/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c
index 24e73ae9b3..efcb60ce96 100644
--- a/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c
+++ b/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c
@@ -31,7 +31,7 @@ nfapi_pnf_p7_config_t* nfapi_pnf_p7_config_create()
_this->_public.segment_size = 1400;
_this->max_num_segments = 8;
- _this->_public.subframe_buffer_size = 8;
+ _this->_public.subframe_buffer_size = 8;// TODO: Initialize the slot_buffer size
_this->_public.timing_info_mode_periodic = 1;
_this->_public.timing_info_period = 32;
_this->_public.timing_info_mode_aperiodic = 1;
@@ -76,6 +76,26 @@ int nfapi_pnf_p7_start(nfapi_pnf_p7_config_t* config)
return 0;
}
+int nfapi_nr_pnf_p7_start(nfapi_pnf_p7_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 = config->trace;
+
+ pnf_p7_t* _this = (pnf_p7_t*)(config);
+
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
+
+ pnf_nr_p7_message_pump(_this);
+
+ return 0;
+}
+
+
int nfapi_pnf_p7_stop(nfapi_pnf_p7_config_t* config)
{
// Verify that config is not null
@@ -88,6 +108,16 @@ int nfapi_pnf_p7_stop(nfapi_pnf_p7_config_t* config)
return 0;
}
+int nfapi_pnf_p7_slot_ind(nfapi_pnf_p7_config_t* config, uint16_t phy_id, uint16_t sfn, uint16_t slot)
+{
+ // Verify that config is not null
+ if(config == 0)
+ return -1;
+
+ pnf_p7_t* _this = (pnf_p7_t*)(config);
+
+ return pnf_p7_slot_ind(_this, phy_id, sfn, slot);
+}
int nfapi_pnf_p7_subframe_ind(nfapi_pnf_p7_config_t* config, uint16_t phy_id, uint16_t sfn_sf)
{
diff --git a/nfapi/open-nFAPI/pnf/tests/pnf_cunit_main.c b/nfapi/open-nFAPI/pnf/tests/pnf_cunit_main.c
index d2ab031ad4..bd6bedbea5 100644
--- a/nfapi/open-nFAPI/pnf/tests/pnf_cunit_main.c
+++ b/nfapi/open-nFAPI/pnf/tests/pnf_cunit_main.c
@@ -48,6 +48,9 @@ typedef struct phy_info
uint8_t enabled;
uint16_t phy_id;
uint16_t sfn_sf;
+ uint16_t sfn;
+ uint16_t slot;
+
pthread_t thread;
@@ -1207,6 +1210,12 @@ void send_dl_subframe_msgs_interleaved(int p7Sock, int phy_id, struct sockaddr_i
//free(req.tx_request_body.tx_pdu_list);
}
+void send_slot_indication(phy_info_t* phy_info)
+{
+ // DONE: add sfn and slot as members in the phy_info
+ nfapi_pnf_p7_slot_ind(phy_info->config, phy_info->phy_id, phy_info->sfn, phy_info->slot);
+}
+
void send_subframe_indication(phy_info_t* phy_info)
{
nfapi_pnf_p7_subframe_ind(phy_info->config, phy_info->phy_id, phy_info->sfn_sf);
diff --git a/nfapi/open-nFAPI/vnf/inc/vnf.h b/nfapi/open-nFAPI/vnf/inc/vnf.h
index 4fd8d2b91d..b16b842606 100644
--- a/nfapi/open-nFAPI/vnf/inc/vnf.h
+++ b/nfapi/open-nFAPI/vnf/inc/vnf.h
@@ -35,9 +35,13 @@ typedef struct
int vnf_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len);
+int vnf_nr_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len);
+
int vnf_pack_and_send_p4_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len);
int vnf_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* pnf);
+int vnf_nr_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* pnf);
+
void nfapi_vnf_phy_info_list_add(nfapi_vnf_config_t* config, nfapi_vnf_phy_info_t* info);
nfapi_vnf_phy_info_t* nfapi_vnf_phy_info_list_find(nfapi_vnf_config_t* config, uint16_t phy_id);
diff --git a/nfapi/open-nFAPI/vnf/inc/vnf_p7.h b/nfapi/open-nFAPI/vnf/inc/vnf_p7.h
index fc2ab4e6b5..ad1c5e7944 100644
--- a/nfapi/open-nFAPI/vnf/inc/vnf_p7.h
+++ b/nfapi/open-nFAPI/vnf/inc/vnf_p7.h
@@ -77,6 +77,9 @@ typedef struct nfapi_vnf_p7_connection_info {
int32_t sf_offset_filtered;
int32_t sf_offset_trend;
int32_t sf_offset;
+ int32_t slot_offset;
+ int32_t slot_offset_trend;
+ int32_t slot_offset_filtered;
uint16_t zero_count;
int32_t adjustment;
int32_t insync_minor_adjustment;
@@ -85,8 +88,10 @@ typedef struct nfapi_vnf_p7_connection_info {
uint32_t previous_t1;
uint32_t previous_t2;
int32_t previous_sf_offset_filtered;
-
+ int32_t previous_slot_offset_filtered;
int sfn_sf;
+ int sfn;
+ int slot;
int socket;
struct sockaddr_in local_addr;
@@ -111,6 +116,7 @@ typedef struct {
nfapi_vnf_p7_connection_info_t* p7_connections;
int socket;
uint32_t sf_start_time_hr;
+ uint32_t slot_start_time_hr;
uint8_t* rx_message_buffer; // would this be better put in the p7 conenction info?
uint16_t rx_message_buffer_size;
@@ -120,14 +126,19 @@ uint32_t vnf_get_current_time_hr(void);
uint16_t increment_sfn_sf(uint16_t sfn_sf);
int vnf_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info);
+int vnf_nr_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info);
+
int send_mac_subframe_indications(vnf_p7_t* config);
+int send_mac_slot_indications(vnf_p7_t* config);
int vnf_p7_read_dispatch_message(vnf_p7_t* vnf_p7 );
+int vnf_nr_p7_read_dispatch_message(vnf_p7_t* vnf_p7 );
void vnf_p7_connection_info_list_add(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* node);
nfapi_vnf_p7_connection_info_t* vnf_p7_connection_info_list_find(vnf_p7_t* vnf_p7, uint16_t phy_id);
nfapi_vnf_p7_connection_info_t* vnf_p7_connection_info_list_delete(vnf_p7_t* vnf_p7, uint16_t phy_id);
int vnf_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* header);
+int vnf_nr_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* header);
void vnf_p7_release_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* header);
void vnf_p7_release_pdu(vnf_p7_t* vnf_p7, void* pdu);
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 5abf6b75c3..518b01864e 100644
--- a/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h
+++ b/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h
@@ -19,6 +19,7 @@
#include "nfapi_interface.h"
#include "nfapi_nr_interface_scf.h"
+#include "nfapi_nr_interface.h"
#include "debug.h"
@@ -120,6 +121,7 @@ typedef struct nfapi_vnf_config
*
* \todo Do we need to send the address information of the PNF?
*/
+ int (*pnf_nr_connection_indication)(nfapi_vnf_config_t* config, int p5_idx);
int (*pnf_connection_indication)(nfapi_vnf_config_t* config, int p5_idx);
/*! \brief Callback indicating that a pnf has lost connection
@@ -160,6 +162,7 @@ typedef struct nfapi_vnf_config
* then the substructure pointers should be set to 0 and then the client should
* use the codec_config.deallocate function to release it at a future point
*/
+ int (*pnf_nr_param_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_pnf_param_response_t* resp);
int (*pnf_param_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_param_response_t* resp);
/*! A callback for the PNF_CONFIG.resp
@@ -182,7 +185,8 @@ typedef struct nfapi_vnf_config
* use the codec_config.deallocate function to release it at a future point
*/
int (*pnf_config_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_config_response_t* resp);
-
+ int (*pnf_nr_config_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_pnf_config_response_t* resp);
+
/*! A callback for the PNF_START.resp
* \param config A pointer to the vnf configuration
* \param p5_idx The p5 index used to indicate a particular pnf p5 connection
@@ -203,7 +207,8 @@ typedef struct nfapi_vnf_config
* use the codec_config.deallocate function to release it at a future point
*/
int (*pnf_start_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_start_response_t* resp);
-
+ int (*pnf_nr_start_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_pnf_start_response_t* resp);
+
/*! A callback for the PNF_STOP.resp
* \param config A pointer to the vnf configuration
* \param p5_idx The p5 index used to indicate a particular pnf p5 connection
@@ -249,6 +254,7 @@ typedef struct nfapi_vnf_config
* use the codec_config.deallocate function to release it at a future point
*/
int (*param_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_response_t* resp);
+ int (*nr_param_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_param_response_scf_t* resp);
/*! A callback for the CONFIG.response
* \param config A pointer to the vnf configuration
@@ -266,8 +272,9 @@ typedef struct nfapi_vnf_config
* then the substructure pointers should be set to 0 and then the client should
* use the codec_config.deallocate function to release it at a future point
*/
+ int (*nr_config_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_config_response_scf_t* resp);
int (*config_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_config_response_t* resp);
-
+
/*! A callback for the START.resp
* \param config A pointer to the vnf configuration
* \param p5_idx The p5 index used to indicate a particular pnf p5 connection
@@ -285,6 +292,7 @@ typedef struct nfapi_vnf_config
* use the codec_config.deallocate function to release it at a future point
*/
int (*start_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_start_response_t* resp);
+ int (*nr_start_resp)(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_start_response_scf_t* resp);
/*! A callback for the STOP.resp
* \param config A pointer to the vnf configuration
@@ -469,6 +477,8 @@ void nfapi_vnf_config_destory(nfapi_vnf_config_t* config);
*
* This function will not return untill nfapi_vnf_stop is called
*/
+int nfapi_nr_vnf_start(nfapi_vnf_config_t* config);
+
int nfapi_vnf_start(nfapi_vnf_config_t* config);
/*! Stop the VNF library.
@@ -500,6 +510,7 @@ int nfapi_vnf_allocate_phy(nfapi_vnf_config_t* config, int p5_idx, uint16_t* phy
* \return 0 means success, -1 failure
*/
int nfapi_vnf_pnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_param_request_t* req);
+int nfapi_nr_vnf_pnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_pnf_param_request_t* req);
/*! Send the PNF_CONFIG.request
* \param config A pointer to a vnf config
@@ -508,6 +519,7 @@ int nfapi_vnf_pnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_pa
* \return 0 means success, -1 failure
*/
int nfapi_vnf_pnf_config_req(nfapi_vnf_config_t* config,int p5_idx, nfapi_pnf_config_request_t* req);
+int nfapi_nr_vnf_pnf_config_req(nfapi_vnf_config_t* config,int p5_idx, nfapi_nr_pnf_config_request_t* req);
/*! Send the PNF_START.request
* \param config A pointer to a vnf config
@@ -516,6 +528,7 @@ int nfapi_vnf_pnf_config_req(nfapi_vnf_config_t* config,int p5_idx, nfapi_pnf_co
* \return 0 means success, -1 failure
*/
int nfapi_vnf_pnf_start_req(nfapi_vnf_config_t* config,int p5_idx, nfapi_pnf_start_request_t* req);
+int nfapi_nr_vnf_pnf_start_req(nfapi_vnf_config_t* config,int p5_idx, nfapi_nr_pnf_start_request_t* req);
/*! Send the PNF_STOP.request
* \param config A pointer to a vnf config
@@ -532,6 +545,7 @@ int nfapi_vnf_pnf_stop_req(nfapi_vnf_config_t* config,int p5_idx, nfapi_pnf_stop
* \return 0 means success, -1 failure
*/
int nfapi_vnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_request_t* req);
+int nfapi_nr_vnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_param_request_scf_t* req);
/*! Send the CONFIG.request
* \param config A pointer to a vnf config
@@ -539,6 +553,7 @@ int nfapi_vnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_requ
* \param req A pointer to a CONFIG.request message structure
* \return 0 means success, -1 failure
*/
+int nfapi_nr_vnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_config_request_scf_t* req);
int nfapi_vnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_config_request_t* req);
/*! Send the START.request
@@ -548,6 +563,7 @@ int nfapi_vnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_config_re
* \return 0 means success, -1 failure
*/
int nfapi_vnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_start_request_t* req);
+int nfapi_nr_vnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_start_request_scf_t* req);
/*! Send the STOP.request
* \param config A pointer to a vnf config
@@ -692,6 +708,7 @@ typedef struct nfapi_vnf_p7_config
*/
int (*subframe_indication)(struct nfapi_vnf_p7_config* config, uint16_t phy_id, uint16_t sfn_sf);
+ int (*slot_indication)(struct nfapi_vnf_p7_config* config, uint16_t phy_id, uint16_t sfn, uint16_t slot);
/*! A callback for the HARQ.indication
* \param config A pointer to the vnf p7 configuration
@@ -885,6 +902,8 @@ void nfapi_vnf_p7_config_destory(nfapi_vnf_p7_config_t* config);
*/
int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config);
+int nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t* config);
+
/*! Stop the VNF P7 library.
* \param config A pointer to an vnf p7 configuration structure
@@ -950,7 +969,7 @@ int nfapi_vnf_p7_nr_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_nr_dl_tti
* may be released after this function call has returned or at a later pointer
*/
int nfapi_vnf_p7_ul_config_req(nfapi_vnf_p7_config_t* config, nfapi_ul_config_request_t* req);
-
+int nfapi_vnf_p7_ul_tti_req(nfapi_vnf_p7_config_t* config, nfapi_nr_ul_tti_request_t* req);
/*! Send the HI_DCI0.request
* \param config A pointer to the vnf p7 configuration
* \param req A data structure for the decoded HI_DCI0.request.
@@ -960,7 +979,7 @@ int nfapi_vnf_p7_ul_config_req(nfapi_vnf_p7_config_t* config, nfapi_ul_config_re
* may be released after this function call has returned or at a later pointer
*/
int nfapi_vnf_p7_hi_dci0_req(nfapi_vnf_p7_config_t* config, nfapi_hi_dci0_request_t* req);
-
+int nfapi_vnf_p7_ul_dci_req(nfapi_vnf_p7_config_t* config, nfapi_nr_ul_dci_request_t* req);
/*! Send the TX.req
* \param config A pointer to the vnf p7 configuration
* \param req A data structure for the decoded HI_DCI0.request.
@@ -970,7 +989,7 @@ int nfapi_vnf_p7_hi_dci0_req(nfapi_vnf_p7_config_t* config, nfapi_hi_dci0_reques
* may be released after this function call has returned or at a later pointer
*/
int nfapi_vnf_p7_tx_req(nfapi_vnf_p7_config_t* config, nfapi_tx_request_t* req);
-
+int nfapi_vnf_p7_tx_data_req(nfapi_vnf_p7_config_t* config, nfapi_nr_tx_data_request_t* req);
/*! Send the LBT_DL_CONFIG.requst
* \param config A pointer to the vnf p7 configuration
* \param req A data structure for the decoded LBT_DL_CONFIG.request.
diff --git a/nfapi/open-nFAPI/vnf/src/vnf.c b/nfapi/open-nFAPI/vnf/src/vnf.c
index 6800ee21d2..7fee47d6d5 100644
--- a/nfapi/open-nFAPI/vnf/src/vnf.c
+++ b/nfapi/open-nFAPI/vnf/src/vnf.c
@@ -21,9 +21,12 @@
#include
#include
#include
+#include
#include
#include "vnf.h"
+#include "nfapi_nr_interface.h"
+#include "nfapi_nr_interface_scf.h"
void* vnf_malloc(nfapi_vnf_config_t* config, size_t size)
@@ -101,6 +104,39 @@ nfapi_vnf_pnf_info_t* nfapi_vnf_pnf_list_find(nfapi_vnf_config_t* config, int p5
return 0;
}
+void vnf_nr_handle_pnf_param_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
+{
+ // ensure it's valid
+ if (pRecvMsg == NULL || config == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s : NULL parameters\n", __FUNCTION__);
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "Received PNF_PARAM.reponse\n");
+
+ nfapi_nr_pnf_param_response_t msg;
+
+ // unpack the message
+ if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0)
+ {
+ // Invoke the call back
+ if(config->pnf_nr_param_resp)
+ {
+ (config->pnf_nr_param_resp)(config, p5_idx, &msg);
+ }
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
+ }
+
+ // make sure to release any dyanmic part of the message
+ if(msg.vendor_extension)
+ config->codec_config.deallocate(msg.vendor_extension);
+ }
+}
+
void vnf_handle_pnf_param_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
{
// ensure it's valid
@@ -134,6 +170,40 @@ void vnf_handle_pnf_param_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_con
}
}
+
+void vnf_nr_handle_pnf_config_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
+{
+ // ensure it's valid
+ if (pRecvMsg == NULL || config == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "Received PNF_CONFIG_RESPONSE\n");
+
+ nfapi_nr_pnf_config_response_t msg;
+
+ // unpack the message
+ if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0)
+ {
+ // Invoke the call back
+ if(config->pnf_nr_config_resp)
+ {
+ (config->pnf_nr_config_resp)(config, p5_idx, &msg);
+ }
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
+ }
+
+ // make sure to release any dyanmic part of the message
+ if(msg.vendor_extension)
+ config->codec_config.deallocate(msg.vendor_extension);
+ }
+}
+
void vnf_handle_pnf_config_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
{
// ensure it's valid
@@ -167,6 +237,38 @@ void vnf_handle_pnf_config_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_co
}
}
+void vnf_nr_handle_pnf_start_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
+{
+ // ensure it's valid
+ if (pRecvMsg == NULL || config == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "Received PNF_START_RESPONSE\n");
+
+ nfapi_nr_pnf_start_response_t msg;
+
+ // unpack the message
+ if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0)
+ {
+ if(config->pnf_nr_start_resp)
+ {
+ (config->pnf_nr_start_resp)(config, p5_idx, &msg);
+ }
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
+ }
+
+ // make sure to release any dyanmic part of the message
+ if(msg.vendor_extension)
+ config->codec_config.deallocate(msg.vendor_extension);
+ }
+}
+
void vnf_handle_pnf_start_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
{
// ensure it's valid
@@ -298,8 +400,113 @@ void vnf_handle_param_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_
}
}
+void vnf_nr_handle_param_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
+{
+
+ // ensure it's valid
+ if (pRecvMsg == NULL || config == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "Received PARAM_RESPONSE\n");
+
+ nfapi_nr_param_response_scf_t msg;
+
+ // unpack the message
+ if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0)
+ {
+
+ if (msg.error_code == NFAPI_NR_PARAM_MSG_OK)
+ {
+ nfapi_vnf_phy_info_t* phy_info = nfapi_vnf_phy_info_list_find(config, msg.header.phy_id);
+
+ if(msg.nfapi_config.p7_pnf_address_ipv4.tl.tag)
+ {
+ struct sockaddr_in sockAddr;
+
+ (void)memcpy(&sockAddr.sin_addr.s_addr, msg.nfapi_config.p7_pnf_address_ipv4.address, NFAPI_IPV4_ADDRESS_LENGTH);
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 IPv4 address: %s\n", inet_ntoa(sockAddr.sin_addr));
+
+ // store address
+ phy_info->p7_pnf_address.sin_addr = sockAddr.sin_addr;
+ }
+
+ if(msg.nfapi_config.p7_pnf_address_ipv6.tl.tag)
+ {
+ struct sockaddr_in6 sockAddr6;
+ char addr6[64];
+ (void)memcpy(&sockAddr6.sin6_addr, msg.nfapi_config.p7_pnf_address_ipv6.address, NFAPI_IPV6_ADDRESS_LENGTH);
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 IPv6 address: %s\n", inet_ntop(AF_INET6, &sockAddr6.sin6_addr, addr6, sizeof(addr6)));
+ }
+
+ if (msg.nfapi_config.p7_pnf_port.tl.tag)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF P7 Port: %d\n", msg.nfapi_config.p7_pnf_port.value);
+
+ // store port
+ phy_info->p7_pnf_address.sin_port = htons(msg.nfapi_config.p7_pnf_port.value);
+ }
+ }
+
+ if(config->nr_param_resp)
+ {
+ (config->nr_param_resp)(config, p5_idx, &msg);
+ }
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
+ }
+
+ // make sure to release any dyanmic part of the message
+ if(msg.vendor_extension)
+ config->codec_config.deallocate(msg.vendor_extension);
+ }
+}
+
+
+void vnf_nr_handle_config_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
+{
+
+ // ensure it's valid
+ if (pRecvMsg == NULL || config == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "Received CONFIG_RESPONSE\n");
+
+ nfapi_nr_config_response_scf_t msg;
+
+ // unpack the message
+ if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >=0 )
+ {
+ // check the error code:
+
+ if (msg.error_code == NFAPI_NR_CONFIG_MSG_OK){
+ if(config->nr_config_resp)
+ {
+ (config->nr_config_resp)(config, p5_idx, &msg);
+ }
+ }
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
+ }
+
+ // make sure to release any dyanmic part of the message
+ if(msg.vendor_extension)
+ config->codec_config.deallocate(msg.vendor_extension);
+ }
+}
+
void vnf_handle_config_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
{
+
// ensure it's valid
if (pRecvMsg == NULL || config == NULL)
{
@@ -314,9 +521,13 @@ void vnf_handle_config_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config
// unpack the message
if (nfapi_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >=0 )
{
- if(config->config_resp)
- {
- (config->config_resp)(config, p5_idx, &msg);
+ // check the error code:
+
+ if (msg.error_code == NFAPI_MSG_OK){
+ if(config->config_resp)
+ {
+ (config->config_resp)(config, p5_idx, &msg);
+ }
}
}
else
@@ -362,6 +573,40 @@ void vnf_handle_start_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_
}
}
+void vnf_nr_handle_start_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
+{
+ // ensure it's valid
+ if (pRecvMsg == NULL || config == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "Received START_RESPONSE\n");
+
+ nfapi_nr_start_response_scf_t msg;
+
+ // unpack the message
+ if (nfapi_nr_p5_message_unpack(pRecvMsg, recvMsgLen, &msg, sizeof(msg), &config->codec_config) >= 0)
+ { // check the error code
+ if (msg.error_code == NFAPI_NR_START_MSG_OK){
+ if(config->nr_start_resp)
+ {
+ (config->nr_start_resp)(config, p5_idx, &msg);
+ }
+ }
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: Unpack message failed, ignoring\n", __FUNCTION__);
+ }
+
+ // make sure to release any dyanmic part of the message
+ if(msg.vendor_extension)
+ config->codec_config.deallocate(msg.vendor_extension);
+ }
+}
+
void vnf_handle_stop_response(void *pRecvMsg, int recvMsgLen, nfapi_vnf_config_t* config, int p5_idx)
{
@@ -811,6 +1056,74 @@ void vnf_handle_vendor_extension(void* pRecvMsg, int recvMsgLen, nfapi_vnf_confi
}
}
+void vnf_nr_handle_p4_p5_message(void *pRecvMsg, int recvMsgLen, int p5_idx, nfapi_vnf_config_t* config)
+{
+ nfapi_p4_p5_message_header_t messageHeader;
+
+ // validate the input params
+ if(pRecvMsg == NULL || recvMsgLen < NFAPI_HEADER_LENGTH || config == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "vnf_handle_p4_p5_message: invalid input params\n");
+ return;
+ }
+
+ // unpack the message header
+ if (nfapi_p5_message_header_unpack(pRecvMsg, recvMsgLen, &messageHeader, sizeof(nfapi_p4_p5_message_header_t), &config->codec_config) < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n");
+ return;
+ }
+
+ switch (messageHeader.message_id)
+ {
+ case NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_RESPONSE:
+ vnf_nr_handle_pnf_param_response(pRecvMsg, recvMsgLen, config, p5_idx);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_RESPONSE:
+ vnf_nr_handle_pnf_config_response(pRecvMsg, recvMsgLen, config, p5_idx);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_PNF_START_RESPONSE:
+ vnf_nr_handle_pnf_start_response(pRecvMsg, recvMsgLen, config, p5_idx);
+ break;
+
+ case NFAPI_PNF_STOP_RESPONSE:
+ vnf_handle_pnf_stop_response(pRecvMsg, recvMsgLen, config, p5_idx);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE:
+ vnf_nr_handle_param_response(pRecvMsg, recvMsgLen, config, p5_idx);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE:
+ vnf_nr_handle_config_response(pRecvMsg, recvMsgLen, config, p5_idx);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE:
+ vnf_nr_handle_start_response(pRecvMsg, recvMsgLen, config, p5_idx);
+ break;
+
+ case NFAPI_NR_PHY_MSG_TYPE_STOP_RESPONSE:
+ vnf_handle_stop_response(pRecvMsg, recvMsgLen, config, p5_idx);
+ break;
+
+ default:
+ {
+ if(messageHeader.message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
+ messageHeader.message_id <= NFAPI_VENDOR_EXT_MSG_MAX)
+ {
+ vnf_handle_vendor_extension(pRecvMsg, recvMsgLen, config, p5_idx, messageHeader.message_id);
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s P5 Unknown message ID %d\n", __FUNCTION__, messageHeader.message_id);
+ }
+ }
+ break;
+ }
+}
+
void vnf_handle_p4_p5_message(void *pRecvMsg, int recvMsgLen, int p5_idx, nfapi_vnf_config_t* config)
{
nfapi_p4_p5_message_header_t messageHeader;
@@ -926,6 +1239,137 @@ void vnf_handle_p4_p5_message(void *pRecvMsg, int recvMsgLen, int p5_idx, nfapi_
break;
}
}
+
+
+int vnf_nr_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* pnf)
+{
+ if(1)
+ {
+ int socket_connected = 1;
+
+ // 1. Peek the message header
+ // 2. If the message is larger than the stack buffer then create a dynamic buffer
+ // 3. Read the buffer
+ // 4. Handle the p5 message
+
+ uint32_t header_buffer_size = NFAPI_HEADER_LENGTH;
+ uint8_t header_buffer[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];
+
+ uint8_t* dynamic_buffer = 0;
+
+ uint8_t* read_buffer = &stack_buffer[0];
+ uint32_t message_size = 0;
+
+ struct sockaddr_in addr;
+ socklen_t addr_len = sizeof(addr);
+
+ struct sctp_sndrcvinfo sndrcvinfo;
+ (void)memset(&sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo));
+
+ {
+ int flags = MSG_PEEK;
+ message_size = sctp_recvmsg(pnf->p5_sock, header_buffer, header_buffer_size, (struct sockaddr*)&addr, &addr_len, &sndrcvinfo, &flags);
+
+ if(message_size == -1)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Failed to peek sctp message size errno:%d\n", errno);
+ return 0;
+ }
+
+ nfapi_p4_p5_message_header_t header;
+ int unpack_result = nfapi_p5_message_header_unpack(header_buffer, header_buffer_size, &header, sizeof(header), 0);
+ if(unpack_result < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Failed to decode message header %d\n", unpack_result);
+ return 0;
+ }
+ message_size = header.message_length;
+
+ // now have the size of the mesage
+ }
+
+ if(message_size > stack_buffer_size)
+ {
+ dynamic_buffer = (uint8_t*)malloc(message_size);
+
+ if(dynamic_buffer == NULL)
+ {
+ // todo : add error mesage
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Failed to allocate dynamic buffer for sctp_recvmsg size:%d\n", message_size);
+ return -1;
+ }
+
+ read_buffer = dynamic_buffer;
+ }
+
+ {
+ int flags = 0;
+ (void)memset(&sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo));
+
+ int recvmsg_result = sctp_recvmsg(pnf->p5_sock, read_buffer, message_size, (struct sockaddr*)&addr, &addr_len, &sndrcvinfo, &flags);
+ if(recvmsg_result == -1)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "Failed to read sctp message size errno:%d\n", errno);
+ }
+ else
+ {
+ if (flags & MSG_NOTIFICATION)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "Notification received from %s:%u\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
+
+ // todo - handle the events
+ }
+ else
+ {
+ /*
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "Received message fd:%d from %s:%u assoc:%d on stream %d, PPID %d, length %d, flags 0x%x\n",
+ pnf->p5_sock,
+ inet_ntoa(addr.sin_addr),
+ ntohs(addr.sin_port),
+ sndrcvinfo.sinfo_assoc_id,
+ sndrcvinfo.sinfo_stream,
+ ntohl(sndrcvinfo.sinfo_ppid),
+ message_size,
+ flags);
+ */
+
+ // handle now if complete message in one or more segments
+ if ((flags & 0x80) == 0x80)
+ {
+ // printf("\nVNF RECEIVES:\n");
+ // for(int i=0; ip5_idx, config);
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_WARN, "sctp_recvmsg: unhandled mode with flags 0x%x\n", flags);
+
+ // assume socket disconnected
+ NFAPI_TRACE(NFAPI_TRACE_WARN, "Disconnected socket\n");
+ socket_connected = 0;
+ }
+
+
+ }
+ }
+ }
+
+ if(dynamic_buffer)
+ {
+ free(dynamic_buffer);
+ }
+
+ return socket_connected;
+ }
+}
+
int vnf_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* pnf)
{
if(1)
@@ -1024,6 +1468,12 @@ int vnf_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t*
// handle now if complete message in one or more segments
if ((flags & 0x80) == 0x80)
{
+ // printf("\nVNF RECEIVES:\n");
+ // for(int i=0; ip5_idx, config);
}
else
@@ -1051,6 +1501,12 @@ int vnf_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t*
static int vnf_send_p5_msg(nfapi_vnf_pnf_info_t* pnf, const void *msg, int len, uint8_t stream)
{
+ // printf("\n MESSAGE SENT: \n");
+ // for(int i=0; ip5_sock, msg, len, (struct sockaddr*)&pnf->p5_pnf_sockaddr, sizeof(pnf->p5_pnf_sockaddr),1, 0, stream, 0, 4);
@@ -1071,6 +1527,29 @@ static int vnf_send_p5_msg(nfapi_vnf_pnf_info_t* pnf, const void *msg, int len,
return 0;
}
+int vnf_nr_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len)
+{
+ nfapi_vnf_pnf_info_t* pnf = nfapi_vnf_pnf_list_find(&(vnf->_public), p5_idx);
+
+ if(pnf)
+ {
+ // pack the message for transmission
+ int packedMessageLength = nfapi_nr_p5_message_pack(msg, msg_len, vnf->tx_message_buffer, sizeof(vnf->tx_message_buffer), &vnf->_public.codec_config);
+
+ if (packedMessageLength < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_p5_message_pack failed with return %d\n", packedMessageLength);
+ return -1;
+ }
+ return vnf_send_p5_msg(pnf, vnf->tx_message_buffer, packedMessageLength, 0);
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() cannot find pnf info for p5_idx:%d\n", __FUNCTION__, p5_idx);
+ return -1;
+ }
+}
+
int vnf_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len)
{
diff --git a/nfapi/open-nFAPI/vnf/src/vnf_interface.c b/nfapi/open-nFAPI/vnf/src/vnf_interface.c
index 59d7f3eb4f..084c4fa485 100644
--- a/nfapi/open-nFAPI/vnf/src/vnf_interface.c
+++ b/nfapi/open-nFAPI/vnf/src/vnf_interface.c
@@ -63,6 +63,418 @@ void nfapi_vnf_config_destory(nfapi_vnf_config_t* config)
free(config);
}
+int nfapi_nr_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;
+
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "%s()\n", __FUNCTION__);
+
+ int p5ListenSock, p5Sock;
+
+ struct sockaddr_in addr;
+ socklen_t addrSize;
+
+ struct sockaddr_in6 addr6;
+
+ struct sctp_event_subscribe events;
+ struct sctp_initmsg initMsg;
+ int noDelay;
+
+ (void)memset(&addr, 0, sizeof(struct sockaddr_in));
+ (void)memset(&addr6, 0, sizeof(struct sockaddr_in6));
+ (void)memset(&events, 0, sizeof(struct sctp_event_subscribe));
+ (void)memset(&initMsg, 0, sizeof(struct sctp_initmsg));
+
+ vnf_t* vnf = (vnf_t*)(config);
+
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "Starting P5 VNF connection on port %u\n", config->vnf_p5_port);
+
+ /*
+ char * host = 0;
+ char * port = "4242";
+ struct addrinfo hints;
+ bzero(&hints, sizeof(struct addrinfo));
+ //hints.ai_flags=AI_PASSIVE;
+ //hints.ai_flags=AI_DEFAULT;
+ hints.ai_family=AF_UNSPEC;
+ //hints.ai_family=AF_INET6;
+ hints.ai_socktype=SOCK_STREAM;
+ //hints.ai_protocol=IPPROTO_SCTP
+
+ struct addrinfo *aiHead = 0;
+
+
+
+ int result = getaddrinfo(host, port, &hints, &aiHead);
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "getaddrinfo return %d %d\n", result, errno);
+
+ while(aiHead->ai_next != NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "addr info %d (IP %d UDP %d SCTP %d)\n %d (%d)\n",
+ aiHead->ai_protocol, IPPROTO_IP, IPPROTO_UDP, IPPROTO_SCTP,
+ aiHead->ai_flags, AI_PASSIVE);
+
+ char hostBfr[ NI_MAXHOST ];
+ char servBfr[ NI_MAXSERV ];
+
+ getnameinfo(aiHead->ai_addr,
+ aiHead->ai_addrlen,
+ hostBfr,
+ sizeof( hostBfr ),
+ servBfr,
+ sizeof( servBfr ),
+ NI_NUMERICHOST | NI_NUMERICSERV );
+
+ switch(aiHead->ai_family)
+ {
+ case PF_INET:
+ {
+ struct sockaddr_in *pSadrIn = (struct sockaddr_in*) aiHead->ai_addr;
+ printf(
+ " ai_addr = sin_family: %d (AF_INET = %d, "
+ "AF_INET6 = %d)\n"
+ " sin_addr: %s\n"
+ " sin_port: %s\n",
+ pSadrIn->sin_family,
+ AF_INET,
+ AF_INET6,
+ hostBfr,
+ servBfr );
+ }
+ break;
+ case PF_INET6:
+ {
+ struct sockaddr_in6 *pSadrIn6 = (struct sockaddr_in6*) aiHead->ai_addr;
+ fprintf( stderr,
+ " ai_addr = sin6_family: %d (AF_INET = %d, "
+ "AF_INET6 = %d) \n"
+ " sin6_addr: %s\n"
+ " sin6_port: %s\n"
+ " sin6_flowinfo: %d\n"
+ " sin6_scope_id: %d\n",
+ pSadrIn6->sin6_family,
+ AF_INET,
+ AF_INET6,
+ hostBfr,
+ servBfr,
+ pSadrIn6->sin6_flowinfo,
+ pSadrIn6->sin6_scope_id);
+ }
+ break;
+ default:
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "Not ment to be here\n");
+ break;
+ }
+
+ aiHead = aiHead->ai_next;
+ }
+ */
+
+ {
+ int protocol;
+ int domain;
+
+ if (vnf->sctp)
+ protocol = IPPROTO_SCTP;
+ else
+ protocol = IPPROTO_IP;
+
+ if(config->vnf_ipv6)
+ {
+ domain = PF_INET6;
+ }
+ else
+ {
+ domain = AF_INET;
+ }
+
+ // open the SCTP socket
+ if ((p5ListenSock = socket(domain, SOCK_STREAM, protocol)) < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "After P5 socket errno: %d\n", errno);
+ return 0;
+ }
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "P5 socket created... %d\n", p5ListenSock);
+ }
+
+ if (vnf->sctp)
+ {
+ // configure for MSG_NOTIFICATION
+ if (setsockopt(p5ListenSock, IPPROTO_SCTP, SCTP_EVENTS, &events, sizeof(struct sctp_event_subscribe)) < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt (SCTP_EVENTS) errno: %d\n", errno);
+ close(p5ListenSock);
+ return 0;
+ }
+ NFAPI_TRACE(NFAPI_TRACE_NOTE, "VNF Setting the SCTP_INITMSG\n");
+ // configure the SCTP socket options
+ initMsg.sinit_num_ostreams = 5; //MAX_SCTP_STREAMS; // number of output streams can be greater
+ 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)
+ close(p5ListenSock);
+ return 0;
+ }
+ noDelay = 1;
+ if (setsockopt(p5ListenSock, IPPROTO_SCTP, SCTP_NODELAY, &noDelay, sizeof(noDelay)) < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt (STCP_NODELAY) errno: %d\n", errno);
+ close(p5ListenSock);
+ return 0;
+ }
+ struct sctp_event_subscribe events;
+ memset( (void *)&events, 0, sizeof(events) );
+ events.sctp_data_io_event = 1;
+
+ if(setsockopt(p5ListenSock, SOL_SCTP, SCTP_EVENTS, (const void *)&events, sizeof(events)) < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt errno: %d\n", errno);
+ close(p5ListenSock);
+ return -1;
+ }
+
+ }
+
+
+ if(config->vnf_ipv6)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "IPV6 binding to port %d %d\n", config->vnf_p5_port, p5ListenSock);
+ addr6.sin6_family = AF_INET6;
+ addr6.sin6_port = htons(config->vnf_p5_port);
+ addr6.sin6_addr = in6addr_any;
+
+ // bind to the configured address and port
+ if (bind(p5ListenSock, (struct sockaddr *)&addr6, sizeof(struct sockaddr_in6)) < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "After bind errno: %d\n", errno);
+ close(p5ListenSock);
+ return 0;
+ }
+ }
+ else if(config->vnf_ipv4)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "IPV4 binding to port %d\n", config->vnf_p5_port);
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(config->vnf_p5_port);
+ addr.sin_addr.s_addr = INADDR_ANY;
+
+ // bind to the configured address and port
+ if (bind(p5ListenSock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0)
+ //if (sctp_bindx(p5ListenSock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in), SCTP_BINDX_ADD_ADDR) < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "After bind errno: %d\n", errno);
+ close(p5ListenSock);
+ return 0;
+ }
+ }
+
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "bind succeeded..%d.\n", p5ListenSock);
+
+ // put the socket into listen mode
+ if (listen(p5ListenSock, 2) < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "After listen errno: %d\n", errno);
+ close(p5ListenSock);
+ return 0;
+ }
+
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "listen succeeded...\n");
+
+ struct timeval tv;
+ fd_set read_fd_set;
+
+
+ int p5_idx = 0;
+ while(vnf->terminate == 0)
+ {
+ FD_ZERO(&read_fd_set);
+
+ FD_SET(p5ListenSock, &read_fd_set);
+ int max_fd = p5ListenSock;
+
+ tv.tv_sec = 5;
+ tv.tv_usec = 0;
+
+ nfapi_vnf_pnf_info_t* pnf = config->pnf_list;
+ while(pnf != 0)
+ {
+ if(pnf->connected)
+ {
+ FD_SET(pnf->p5_sock, &read_fd_set);
+ if (pnf->p5_sock > max_fd)
+ {
+ max_fd = pnf->p5_sock;
+ }
+ }
+
+ pnf = pnf->next;
+ }
+
+ int select_result = select(max_fd + 1, &read_fd_set, 0, 0, &tv);
+
+ if(select_result == -1)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "select result %d errno %d\n", select_result, errno);
+ close(p5ListenSock);
+ return 0;
+ }
+ else if(select_result)
+ {
+ if(FD_ISSET(p5ListenSock, &read_fd_set))
+ {
+ addrSize = sizeof(struct sockaddr_in);
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "Accepting connection from PNF...\n");
+
+ p5Sock = accept(p5ListenSock, (struct sockaddr *)&addr, &addrSize);
+
+ if (p5Sock < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to accept PNF connection reason:%d\n", errno);
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF connection (fd:%d) accepted from %s:%d \n", p5Sock, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
+ nfapi_vnf_pnf_info_t* pnf = (nfapi_vnf_pnf_info_t*)malloc(sizeof(nfapi_vnf_pnf_info_t));
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "MALLOC nfapi_vnf_pnf_info_t for pnf_list pnf:%p\n", pnf);
+ memset(pnf, 0, sizeof(nfapi_vnf_pnf_info_t));
+ pnf->p5_sock = p5Sock;
+ pnf->p5_idx = p5_idx++;
+ pnf->p5_pnf_sockaddr = addr;
+ pnf->connected = 1;
+
+ nfapi_vnf_pnf_list_add(config, pnf);
+
+ // Inform mac that a pnf connection has been established
+ // todo : allow mac to 'accept' the connection. i.e. to
+ // reject it.
+ if(config->pnf_nr_connection_indication != 0)
+ {
+ (config->pnf_nr_connection_indication)(config, pnf->p5_idx);
+ }
+
+
+ // check the connection status
+ {
+ struct sctp_status status;
+ (void)memset(&status, 0, sizeof(struct sctp_status));
+ socklen_t optLen = (socklen_t) sizeof(struct sctp_status);
+ if (getsockopt(p5Sock, IPPROTO_SCTP, SCTP_STATUS, &status, &optLen) < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "After getsockopt errno: %d\n", errno);
+ return -1;
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Association ID = %d\n", status.sstat_assoc_id);
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Receiver window size = %d\n", status.sstat_rwnd);
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF In Streams = %d\n", status.sstat_instrms);
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Out Streams = %d\n", status.sstat_outstrms);
+
+ }
+ }
+ }
+ }
+ else
+ {
+ uint8_t delete_pnfs = 0;
+
+ nfapi_vnf_pnf_info_t* pnf = config->pnf_list;
+ while(pnf != 0)
+ {
+ if(FD_ISSET(pnf->p5_sock, &read_fd_set))
+ {
+ if(vnf_nr_read_dispatch_message(config, pnf) == 0)
+ {
+ if(config->pnf_disconnect_indication != 0)
+ {
+ (config->pnf_disconnect_indication)(config, pnf->p5_idx);
+ }
+
+ close(pnf->p5_sock);
+
+ pnf->to_delete = 1;
+ delete_pnfs = 1;
+ }
+ }
+
+ pnf = pnf->next;
+ }
+
+ if(delete_pnfs)
+ {
+ nfapi_vnf_pnf_info_t* pnf = config->pnf_list;
+ nfapi_vnf_pnf_info_t* prev = 0;
+ while(pnf != 0)
+ {
+ nfapi_vnf_pnf_info_t* curr = pnf;
+
+ if(pnf->to_delete == 1)
+ {
+ if(prev == 0)
+ {
+ config->pnf_list = pnf->next;
+ }
+ else
+ {
+ prev->next = pnf->next;
+ }
+
+ pnf = pnf->next;
+
+ free(curr);
+ }
+ else
+ {
+ prev = pnf;
+ pnf = pnf->next;
+ }
+
+ }
+
+ }
+ }
+
+ continue;
+ }
+ else
+ {
+ // timeout
+
+ // Should we test for socket closure here every second?
+
+ continue;
+ }
+ }
+
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "Closing p5Sock socket's\n");
+ {
+ nfapi_vnf_pnf_info_t* curr = config->pnf_list;
+ while(curr != NULL)
+ {
+ if(config->pnf_disconnect_indication)
+ {
+ (config->pnf_disconnect_indication)(config, curr->p5_idx);
+ }
+
+ close(curr->p5_sock);
+ curr = curr->next;
+ }
+ }
+
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "Closing p5Listen socket\n");
+ close(p5ListenSock);
+
+ return 0;
+
+}
+
int nfapi_vnf_start(nfapi_vnf_config_t* config)
{
// Verify that config is not null
@@ -486,6 +898,16 @@ int nfapi_vnf_stop(nfapi_vnf_config_t* config)
return 0;
}
+int nfapi_nr_vnf_pnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_pnf_param_request_t* req)
+{
+ if(config == 0 || req == 0)
+ return -1;
+
+ vnf_t* _this = (vnf_t*)(config);
+
+ return vnf_nr_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_nr_pnf_param_request_t));
+}
+
int nfapi_vnf_pnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_param_request_t* req)
{
if(config == 0 || req == 0)
@@ -496,6 +918,17 @@ int nfapi_vnf_pnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_pa
return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_pnf_param_request_t));
}
+int nfapi_nr_vnf_pnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_pnf_config_request_t* req)
+{
+ if(config == 0 || req == 0)
+ return -1;
+
+ vnf_t* _this = (vnf_t*)(config);
+
+ return vnf_nr_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_nr_pnf_config_request_t));
+}
+
+
int nfapi_vnf_pnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_config_request_t* req)
{
if(config == 0 || req == 0)
@@ -516,6 +949,16 @@ int nfapi_vnf_pnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_st
return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_pnf_start_request_t));
}
+int nfapi_nr_vnf_pnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_pnf_start_request_t* req)
+{
+ if(config == 0 || req == 0)
+ return -1;
+
+ vnf_t* _this = (vnf_t*)(config);
+
+ return vnf_nr_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_nr_pnf_start_request_t));
+}
+
int nfapi_vnf_pnf_stop_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_stop_request_t* req)
{
if(config == 0 || req == 0)
@@ -526,6 +969,16 @@ int nfapi_vnf_pnf_stop_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_sto
return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_pnf_stop_request_t));
}
+int nfapi_nr_vnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_param_request_scf_t* req)
+{
+ if(config == 0 || req == 0)
+ return -1;
+
+ vnf_t* _this = (vnf_t*)(config);
+
+ return vnf_nr_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_nr_param_request_scf_t));
+}
+
int nfapi_vnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_request_t* req)
{
if(config == 0 || req == 0)
@@ -535,6 +988,38 @@ int nfapi_vnf_param_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_param_requ
return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_param_request_t));
}
+
+int nfapi_nr_vnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_config_request_scf_t* req)
+{
+ if(config == 0 || req == 0)
+ return -1;
+
+ vnf_t* _this = (vnf_t*)(config);
+
+ nfapi_vnf_phy_info_t* phy = nfapi_vnf_phy_info_list_find(config, req->header.phy_id);
+
+ if(phy == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_WARN, "%s failed to find phy information phy_id:%d\n", __FUNCTION__, req->header.phy_id);
+ return -1;
+ }
+
+ // set the timing parameters
+ req->nfapi_config.timing_window.tl.tag = NFAPI_NR_NFAPI_TIMING_WINDOW_TAG;
+ req->nfapi_config.timing_window.value = phy->timing_window;
+ req->num_tlv++;
+
+ req->nfapi_config.timing_info_mode.tl.tag = NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG;
+ req->nfapi_config.timing_info_mode.value = phy->timing_info_mode;
+ req->num_tlv++;
+
+ req->nfapi_config.timing_info_period.tl.tag = NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG;
+ req->nfapi_config.timing_info_period.value = phy->timing_info_period;
+ req->num_tlv++;
+
+ return vnf_nr_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_nr_config_request_scf_t));
+}
+
int nfapi_vnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_config_request_t* req)
{
if(config == 0 || req == 0)
@@ -565,7 +1050,8 @@ int nfapi_vnf_config_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_config_re
return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_config_request_t));
}
-int nfapi_vnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_start_request_t* req)
+
+int nfapi_vnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_start_request_t * req)
{
if(config == 0 || req == 0)
return -1;
@@ -574,6 +1060,18 @@ int nfapi_vnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_start_requ
return vnf_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_start_request_t));
}
+
+int nfapi_nr_vnf_start_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_nr_start_request_scf_t * req)
+{
+ if(config == 0 || req == 0)
+ return -1;
+
+ vnf_t* _this = (vnf_t*)(config);
+
+ return vnf_nr_pack_and_send_p5_message(_this, p5_idx, &req->header, sizeof(nfapi_nr_start_request_scf_t));
+}
+
+
int nfapi_vnf_stop_req(nfapi_vnf_config_t* config, int p5_idx, nfapi_stop_request_t* req)
{
if(config == 0 || req == 0)
@@ -664,7 +1162,7 @@ int nfapi_vnf_allocate_phy(nfapi_vnf_config_t* config, int p5_idx, uint16_t* phy
info->p5_idx = p5_idx;
info->phy_id = vnf->next_phy_id++;
- info->timing_window = 30; // This seems to override what gets set by the user - why???
+ 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;
diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7.c b/nfapi/open-nFAPI/vnf/src/vnf_p7.c
index cff24500b6..ffbc5819bc 100644
--- a/nfapi/open-nFAPI/vnf/src/vnf_p7.c
+++ b/nfapi/open-nFAPI/vnf/src/vnf_p7.c
@@ -303,7 +303,7 @@ static uint32_t get_sf_time(uint32_t now_hr, uint32_t sf_start_hr)
{
if(now_hr < sf_start_hr)
{
- NFAPI_TRACE(NFAPI_TRACE_INFO, "now is earlier that start of subframe\n");
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "now is earlier than start of subframe\n");
return 0;
}
else
@@ -321,6 +321,28 @@ static uint32_t get_sf_time(uint32_t now_hr, uint32_t sf_start_hr)
}
}
+static uint32_t get_slot_time(uint32_t now_hr, uint32_t slot_start_hr)
+{
+ if(now_hr < slot_start_hr)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "now is earlier than start of slot\n");
+ return 0;
+ }
+ else
+ {
+ uint32_t now_us = TIMEHR_USEC(now_hr);
+ uint32_t slot_start_us = TIMEHR_USEC(slot_start_hr);
+
+ // if the us have wrapped adjust for it
+ if(now_hr < slot_start_us)
+ {
+ now_us += 1000000;
+ }
+
+ return now_us - slot_start_us;
+ }
+}
+
uint32_t calculate_t1(uint16_t sfn_sf, uint32_t sf_start_time_hr)
{
uint32_t now_time_hr = vnf_get_current_time_hr();
@@ -332,6 +354,17 @@ uint32_t calculate_t1(uint16_t sfn_sf, uint32_t sf_start_time_hr)
return t1;
}
+uint32_t calculate_nr_t1(uint16_t sfn, uint16_t slot, uint32_t slot_start_time_hr)
+{
+ uint32_t now_time_hr = vnf_get_current_time_hr();
+
+ uint32_t slot_time_us = get_slot_time(now_time_hr, slot_start_time_hr);
+
+ uint32_t t1 = (NFAPI_SFNSLOT2DEC(sfn,slot) * 500) + slot_time_us;
+
+ return t1;
+}
+
uint32_t calculate_t4(uint32_t now_time_hr, uint16_t sfn_sf, uint32_t sf_start_time_hr)
{
@@ -343,15 +376,25 @@ uint32_t calculate_t4(uint32_t now_time_hr, uint16_t sfn_sf, uint32_t sf_start_t
}
+uint32_t calculate_nr_t4(uint32_t now_time_hr, uint16_t sfn, uint16_t slot, uint32_t slot_start_time_hr)
+{
+ uint32_t slot_time_us = get_slot_time(now_time_hr, slot_start_time_hr);
-uint32_t calculate_transmit_timestamp(uint16_t sfn_sf, uint32_t sf_start_time_hr)
+ uint32_t t4 = (NFAPI_SFNSLOT2DEC(sfn,slot) * 500) + slot_time_us;
+
+ return t4;
+
+}
+
+
+uint32_t calculate_transmit_timestamp(uint16_t sfn, uint16_t slot, uint32_t slot_start_time_hr)
{
uint32_t now_time_hr = vnf_get_current_time_hr();
- uint32_t sf_time_us = get_sf_time(now_time_hr, sf_start_time_hr);
-
- uint32_t tt = (NFAPI_SFNSF2DEC(sfn_sf) * 1000) + sf_time_us;
+ uint32_t slot_time_us = get_slot_time(now_time_hr, slot_start_time_hr);
+ uint32_t tt = (NFAPI_SFNSLOT2DEC(sfn, slot) * 500) + slot_time_us;
+
return tt;
}
@@ -367,6 +410,27 @@ uint16_t increment_sfn_sf_by(uint16_t sfn_sf, uint8_t increment)
return sfn_sf;
}
+int send_mac_slot_indications(vnf_p7_t* vnf_p7)
+{
+ nfapi_vnf_p7_connection_info_t* curr = vnf_p7->p7_connections;
+ while(curr != 0)
+ {
+ if(curr->in_sync == 1)
+ {
+ // ask for subframes in the future
+ //uint16_t sfn_sf_adv = increment_sfn_sf_by(curr->sfn_sf, 2);
+
+ //vnf_p7->_public.subframe_indication(&(vnf_p7->_public), curr->phy_id, sfn_sf_adv);
+ // suggestion fix by Haruki NAOI
+ //printf("\nsfn:%d, slot:%d\n",curr->sfn,curr->slot);
+ vnf_p7->_public.slot_indication(&(vnf_p7->_public), curr->phy_id, curr->sfn,curr->slot);
+ }
+
+ curr = curr->next;
+ }
+
+ return 0;
+}
int send_mac_subframe_indications(vnf_p7_t* vnf_p7)
{
@@ -392,7 +456,7 @@ int send_mac_subframe_indications(vnf_p7_t* vnf_p7)
int vnf_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info, uint8_t* msg, const uint32_t len)
{
int sendto_result = sendto(vnf_p7->socket, msg, len, 0, (struct sockaddr*)&(p7_info->remote_addr), sizeof(p7_info->remote_addr));
-
+ //printf("\nSending p7 message sfn=%d,slot=%d\n",vnf_p7->p7_connections->sfn,vnf_p7->p7_connections->slot);
if(sendto_result != len)
{
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() sendto_result %d %d\n", __FUNCTION__, sendto_result, errno);
@@ -401,6 +465,100 @@ int vnf_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info, u
return 0;
}
+int vnf_nr_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* header)
+{
+
+ nfapi_vnf_p7_connection_info_t* p7_connection = vnf_p7_connection_info_list_find(vnf_p7, header->phy_id);
+ if(p7_connection)
+ {
+ int send_result = 0;
+ uint8_t buffer[1024 * 32];
+
+ header->m_segment_sequence = NFAPI_P7_SET_MSS(0, 0, p7_connection->sequence_number);
+
+ int len = nfapi_nr_p7_message_pack(header, buffer, sizeof(buffer), &vnf_p7->_public.codec_config);
+
+ //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() phy_id:%d nfapi_p7_message_pack()=len=%d vnf_p7->_public.segment_size:%u\n", __FUNCTION__, header->phy_id, len, vnf_p7->_public.segment_size);
+
+ if(len < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() failed to pack p7 message phy_id:%d\n", __FUNCTION__, header->phy_id);
+ return -1;
+ }
+
+ if(len > vnf_p7->_public.segment_size)
+ {
+ // todo : consider replacing with the sendmmsg call
+ // todo : worry about blocking writes?
+
+ // segmenting the transmit
+ int msg_body_len = len - NFAPI_P7_HEADER_LENGTH ;
+ int seg_body_len = vnf_p7->_public.segment_size - NFAPI_P7_HEADER_LENGTH ;
+ int segment_count = (msg_body_len / (seg_body_len)) + ((msg_body_len % seg_body_len) ? 1 : 0);
+
+ int segment = 0;
+ int offset = NFAPI_P7_HEADER_LENGTH;
+ uint8_t tx_buffer[vnf_p7->_public.segment_size];
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() MORE THAN ONE SEGMENT phy_id:%d nfapi_p7_message_pack()=len=%d vnf_p7->_public.segment_size:%u\n", __FUNCTION__, header->phy_id, len, vnf_p7->_public.segment_size);
+ for(segment = 0; segment < segment_count; ++segment)
+ {
+ uint8_t last = 0;
+ uint16_t size = vnf_p7->_public.segment_size - NFAPI_P7_HEADER_LENGTH;
+ if(segment + 1 == segment_count)
+ {
+ last = 1;
+ size = (msg_body_len) - (seg_body_len * segment);
+ }
+
+ uint16_t segment_size = size + NFAPI_P7_HEADER_LENGTH;
+
+ // Update the header with the m and segement
+ memcpy(&tx_buffer[0], buffer, NFAPI_P7_HEADER_LENGTH);
+
+ // set the segment length
+ tx_buffer[4] = (segment_size & 0xFF00) >> 8;
+ tx_buffer[5] = (segment_size & 0xFF);
+
+ // set the m & segment number
+ tx_buffer[6] = ((!last) << 7) + segment;
+
+ memcpy(&tx_buffer[NFAPI_P7_HEADER_LENGTH], &buffer[0] + offset, size);
+ offset += size;
+
+ if(vnf_p7->_public.checksum_enabled)
+ {
+ nfapi_p7_update_checksum(tx_buffer, segment_size);
+ }
+
+ nfapi_p7_update_transmit_timestamp(buffer, calculate_transmit_timestamp(p7_connection->sfn, p7_connection->slot, vnf_p7->slot_start_time_hr));
+
+ send_result = vnf_send_p7_msg(vnf_p7, p7_connection, &tx_buffer[0], segment_size);
+ }
+ }
+ else
+ {
+ if(vnf_p7->_public.checksum_enabled)
+ {
+ nfapi_p7_update_checksum(buffer, len);
+ }
+
+ nfapi_p7_update_transmit_timestamp(buffer, calculate_transmit_timestamp(p7_connection->sfn, p7_connection->slot, vnf_p7->slot_start_time_hr));
+
+ // simple case that the message fits in a single segement
+ send_result = vnf_send_p7_msg(vnf_p7, p7_connection, &buffer[0], len);
+ }
+
+ p7_connection->sequence_number++;
+
+ return send_result;
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() cannot find p7 connection info for phy_id:%d\n", __FUNCTION__, header->phy_id);
+ return -1;
+ }
+}
+
int vnf_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* header)
{
@@ -466,7 +624,7 @@ int vnf_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* hea
nfapi_p7_update_checksum(tx_buffer, segment_size);
}
- nfapi_p7_update_transmit_timestamp(buffer, calculate_transmit_timestamp(p7_connection->sfn_sf, vnf_p7->sf_start_time_hr));
+ nfapi_p7_update_transmit_timestamp(buffer, calculate_transmit_timestamp(p7_connection->sfn, p7_connection->slot, vnf_p7->slot_start_time_hr));
send_result = vnf_send_p7_msg(vnf_p7, p7_connection, &tx_buffer[0], segment_size);
}
@@ -478,7 +636,7 @@ int vnf_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* hea
nfapi_p7_update_checksum(buffer, len);
}
- nfapi_p7_update_transmit_timestamp(buffer, calculate_transmit_timestamp(p7_connection->sfn_sf, vnf_p7->sf_start_time_hr));
+ nfapi_p7_update_transmit_timestamp(buffer, calculate_transmit_timestamp(p7_connection->sfn, p7_connection->slot, vnf_p7->slot_start_time_hr));
// simple case that the message fits in a single segement
send_result = vnf_send_p7_msg(vnf_p7, p7_connection, &buffer[0], len);
@@ -494,7 +652,6 @@ int vnf_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* hea
return -1;
}
}
-
int vnf_build_send_dl_node_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info)
{
nfapi_dl_node_sync_t dl_node_sync;
@@ -508,6 +665,52 @@ int vnf_build_send_dl_node_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t
return vnf_p7_pack_and_send_p7_msg(vnf_p7, &dl_node_sync.header);
}
+int vnf_nr_build_send_dl_node_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info)
+{
+
+ nfapi_nr_dl_node_sync_t dl_node_sync;
+ memset(&dl_node_sync, 0, sizeof(dl_node_sync));
+
+ dl_node_sync.header.phy_id = p7_info->phy_id;
+ dl_node_sync.header.message_id = NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC;
+ //dl_node_sync.t1 = calculate_t1(p7_info->sfn_sf, vnf_p7->sf_start_time_hr);
+ dl_node_sync.t1 = calculate_nr_t1(p7_info->sfn,p7_info->slot, vnf_p7->slot_start_time_hr);
+ dl_node_sync.delta_sfn_slot = 0;
+
+ return vnf_nr_p7_pack_and_send_p7_msg(vnf_p7, &dl_node_sync.header);
+}
+
+int vnf_nr_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info)
+{
+
+ if(p7_info->in_sync == 1)
+ {
+ uint16_t dl_sync_period_mask = p7_info->dl_in_sync_period-1;
+ // uint16_t sfn_sf_dec = NFAPI_SFNSF2DEC(p7_info->sfn_sf);
+ uint16_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(p7_info->sfn,p7_info->slot);
+
+ //if ((((sfn_sf_dec + p7_info->dl_in_sync_offset) % NFAPI_MAX_SFNSFDEC) & dl_sync_period_mask) == 0)
+ if ((((sfn_slot_dec + p7_info->dl_in_sync_offset) % NFAPI_MAX_SFNSLOTDEC) & dl_sync_period_mask) == 0)
+ {
+ vnf_nr_build_send_dl_node_sync(vnf_p7, p7_info);
+ }
+ }
+ else
+ {
+ uint16_t dl_sync_period_mask = p7_info->dl_out_sync_period-1;
+ //uint16_t sfn_sf_dec = NFAPI_SFNSF2DEC(p7_info->sfn_sf);
+ uint16_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(p7_info->sfn, p7_info->slot);
+
+ //if ((((sfn_sf_dec + p7_info->dl_out_sync_offset) % NFAPI_MAX_SFNSFDEC) & dl_sync_period_mask) == 0)
+ if ((((sfn_slot_dec + p7_info->dl_out_sync_offset) % NFAPI_MAX_SFNSLOTDEC) & dl_sync_period_mask) == 0)
+ {
+ vnf_nr_build_send_dl_node_sync(vnf_p7, p7_info);
+ }
+ }
+ return 0;
+}
+
+
int vnf_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info)
{
@@ -1251,6 +1454,389 @@ void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
}
}
+void vnf_nr_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
+{
+ //printf("received UL Node sync");
+
+ uint32_t now_time_hr = vnf_get_current_time_hr();
+
+ if (pRecvMsg == NULL || vnf_p7 == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "vnf_handle_ul_node_sync: NULL parameters\n");
+ return;
+ }
+
+ nfapi_nr_ul_node_sync_t ind;
+ if(nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(nfapi_nr_ul_node_sync_t), &vnf_p7->_public.codec_config) < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to unpack ul_node_sync\n");
+ return;
+ }
+
+ //NFAPI_TRACE(NFAPI_TRACE_INFO, "Received UL_NODE_SYNC phy_id:%d t1:%d t2:%d t3:%d\n", ind.header.phy_id, ind.t1, ind.t2, ind.t3);
+
+ nfapi_vnf_p7_connection_info_t* phy = vnf_p7_connection_info_list_find(vnf_p7, ind.header.phy_id);
+ uint32_t t4 = calculate_nr_t4(now_time_hr, phy->sfn, phy->slot, vnf_p7->slot_start_time_hr);
+
+ uint32_t tx_2_rx = t4>ind.t1 ? t4 - ind.t1 : t4 + NFAPI_MAX_SFNSLOTDEC - ind.t1 ; //time taken to receive ul node sync - time taken to send dl node sync
+ uint32_t pnf_proc_time = ind.t3 - ind.t2;
+
+ // divide by 2 using shift operator
+ uint32_t latency = (tx_2_rx - pnf_proc_time) >> 1;
+
+ if(!(phy->filtered_adjust))
+ {
+ phy->latency[phy->min_sync_cycle_count] = latency;
+
+ //NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%d) PNF to VNF !sync phy_id:%d (t1/2/3/4:%8u, %8u, %8u, %8u) txrx:%4u procT:%3u latency(us):%4d\n",
+ // phy->sfn, phy->slot, ind.header.phy_id, ind.t1, ind.t2, ind.t3, t4,
+ // tx_2_rx, pnf_proc_time, latency);
+ }
+ else
+ {
+ phy->latency[phy->min_sync_cycle_count] = latency;
+
+ //if(phy->min_sync_cycle_count != SYNC_CYCLE_COUNT)
+ {
+ if (ind.t2 < phy->previous_t2 && ind.t1 > phy->previous_t1)
+ {
+ // Only t2 wrap has occurred!!!
+ phy->slot_offset = (NFAPI_MAX_SFNSLOTDEC + ind.t2) - ind.t1 - latency;
+ }
+ else if (ind.t2 > phy->previous_t2 && ind.t1 < phy->previous_t1)
+ {
+ // Only t1 wrap has occurred
+ phy->slot_offset = ind.t2 - ( ind.t1 + NFAPI_MAX_SFNSLOTDEC) - latency;
+ }
+ else
+ {
+ // Either no wrap or both have wrapped
+ phy->slot_offset = ind.t2 - ind.t1 - latency;
+ }
+
+ if (phy->slot_offset_filtered == 0)
+ {
+ phy->slot_offset_filtered = phy->slot_offset;
+ }
+ else
+ {
+ int32_t oldFilteredValueShifted = phy->slot_offset_filtered << 5;
+ int32_t newOffsetShifted = phy->slot_offset << 5;
+
+ // 1/8 of new and 7/8 of old
+ phy->slot_offset_filtered = ((newOffsetShifted >> 3) + ((oldFilteredValueShifted * 7) >> 3)) >> 5;
+ }
+ }
+
+ if(1)
+ {
+ 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));
+ }
+
+ }
+
+ if (phy->filtered_adjust && (phy->slot_offset_filtered > 1e6 || phy->slot_offset_filtered < -1e6))
+ {
+ phy->filtered_adjust = 0;
+ phy->zero_count=0;
+ phy->min_sync_cycle_count = 2;
+ phy->in_sync = 0;
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s - ADJUST TOO BAD - go out of filtered phy->slot_offset_filtered:%d\n", __FUNCTION__, phy->slot_offset_filtered);
+ }
+
+ if(phy->min_sync_cycle_count)
+ phy->min_sync_cycle_count--;
+
+ if(phy->min_sync_cycle_count == 0)
+ {
+ uint32_t curr_sfn = phy->sfn;
+ uint32_t curr_slot = phy->slot;
+ int32_t sfn_slot_dec = NFAPI_SFNSLOT2DEC(phy->sfn,phy->slot);
+
+ if(!phy->filtered_adjust)
+ {
+ int i = 0;
+ //phy->average_latency = 0;
+ for(i = 0; i < SYNC_CYCLE_COUNT; ++i)
+ {
+ phy->average_latency += phy->latency[i];
+
+ }
+ phy->average_latency /= SYNC_CYCLE_COUNT;
+
+ phy->slot_offset = ind.t2 - (ind.t1 - phy->average_latency);
+
+ 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) );
+
+
+ }
+ else
+ {
+ sfn_slot_dec += ((phy->slot_offset_filtered + 250) / 500); //Round up to go from microsecond to slot
+
+ }
+
+ if(sfn_slot_dec < 0)
+ {
+ sfn_slot_dec += NFAPI_MAX_SFNSLOTDEC;
+ }
+ else if( sfn_slot_dec >= NFAPI_MAX_SFNSLOTDEC)
+ {
+ sfn_slot_dec -= NFAPI_MAX_SFNSLOTDEC;
+ }
+
+
+ uint16_t new_sfn = NFAPI_SFNSLOTDEC2SFN(sfn_slot_dec);
+ uint16_t new_slot = NFAPI_SFNSLOTDEC2SLOT(sfn_slot_dec);
+
+ {
+ phy->adjustment = NFAPI_SFNSLOT2DEC(new_sfn, new_slot) - NFAPI_SFNSLOT2DEC(curr_sfn, curr_slot);
+
+ //NFAPI_TRACE(NFAPI_TRACE_NOTE, "PNF to VNF phy_id:%d adjustment%d phy->previous_slot_offset_filtered:%d phy->previous_slot_offset_filtered:%d phy->slot_offset_trend:%d\n", ind.header.phy_id, phy->adjustment, phy->previous_slot_offset_filtered, phy->previous_slot_offset_filtered, phy->slot_offset_trend);
+
+ phy->previous_t1 = 0;
+ phy->previous_t2 = 0;
+
+ if(phy->previous_slot_offset_filtered > 0)
+ {
+ if( phy->slot_offset_filtered > phy->previous_slot_offset_filtered)
+ {
+ // pnf is getting futher ahead of vnf
+ //phy->sf_offset_trend = phy->sf_offset_filtered - phy->previous_sf_offset_filtered;
+ phy->slot_offset_trend = (phy->slot_offset_filtered + phy->previous_slot_offset_filtered)/2;
+ }
+ else
+ {
+ // pnf is getting back in sync
+ }
+ }
+ else if(phy->previous_slot_offset_filtered < 0)
+ {
+ if(phy->slot_offset_filtered < phy->previous_slot_offset_filtered)
+ {
+ // vnf is getting future ahead of pnf
+ //phy->sf_offset_trend = -(phy->sf_offset_filtered - phy->previous_sf_offset_filtered);
+ phy->slot_offset_trend = (-(phy->slot_offset_filtered + phy->previous_slot_offset_filtered)) /2;
+ }
+ else
+ {
+ // vnf is getting back in sync
+ }
+ }
+
+
+ int insync_minor_adjustment_1 = phy->slot_offset_trend / 6;
+ int insync_minor_adjustment_2 = phy->slot_offset_trend / 2;
+
+
+ if(insync_minor_adjustment_1 == 0)
+ insync_minor_adjustment_1 = 2;
+
+ if(insync_minor_adjustment_2 == 0)
+ insync_minor_adjustment_2 = 10;
+
+ if(!phy->filtered_adjust)
+ {
+ if(phy->adjustment < 10)
+ {
+ phy->zero_count++;
+
+ if(phy->zero_count >= 10)
+ {
+ phy->filtered_adjust = 1;
+ phy->zero_count = 0;
+
+ NFAPI_TRACE(NFAPI_TRACE_NOTE, "***** Adjusting VNF SFN/SF switching to filtered mode\n");
+ }
+ }
+ else
+ {
+ phy->zero_count = 0;
+ }
+ }
+ else
+ {
+ // Fine level of adjustment
+ if (phy->adjustment == 0)
+ {
+ if (phy->zero_count >= 10)
+ {
+ if(phy->in_sync == 0)
+ {
+ 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);
+ }
+
+ phy->in_sync = 1;
+ }
+ else
+ {
+ phy->zero_count++;
+ }
+
+ if(phy->in_sync)
+ {
+ // in sync
+ if(phy->slot_offset_filtered > 250)
+ {
+ // VNF is slow
+ phy->insync_minor_adjustment = insync_minor_adjustment_1; //25;
+ phy->insync_minor_adjustment_duration = ((phy->slot_offset_filtered) / insync_minor_adjustment_1);
+ }
+ else if(phy->slot_offset_filtered < -250)
+ {
+ // VNF is fast
+ phy->insync_minor_adjustment = -(insync_minor_adjustment_1); //25;
+ phy->insync_minor_adjustment_duration = (((phy->slot_offset_filtered) / -(insync_minor_adjustment_1)));
+ }
+ else
+ {
+ phy->insync_minor_adjustment = 0;
+ }
+
+ if(phy->insync_minor_adjustment != 0)
+ {
+ // NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%d) VNF phy_id:%d Apply minor insync adjustment %dus for %d slots (slot_offset_filtered:%d) %d %d %d NEW:%d CURR:%d adjustment:%d\n",
+ // phy->sfn, phy->slot, ind.header.phy_id,
+ // phy->insync_minor_adjustment, phy->insync_minor_adjustment_duration,
+ // phy->slot_offset_filtered,
+ // insync_minor_adjustment_1, insync_minor_adjustment_2, phy->slot_offset_trend,
+ // NFAPI_SFNSLOT2DEC(new_sfn, new_slot),
+ // NFAPI_SFNSLOT2DEC(curr_sfn, curr_slot),
+ // phy->adjustment);
+ }
+ }
+ }
+ else
+ {
+ if (phy->in_sync)
+ {
+ if(phy->adjustment == 0)
+ {
+ }
+ else if(phy->adjustment > 0)
+ {
+ // VNF is slow
+ //if(phy->adjustment == 1)
+ {
+ //
+ if(phy->slot_offset_filtered > 250)
+ {
+ // VNF is slow
+ phy->insync_minor_adjustment = insync_minor_adjustment_2;
+ phy->insync_minor_adjustment_duration = 2 * ((phy->slot_offset_filtered - 250) / insync_minor_adjustment_2);
+ }
+ else if(phy->slot_offset_filtered < -250)
+ {
+ // VNF is fast
+ phy->insync_minor_adjustment = -(insync_minor_adjustment_2);
+ phy->insync_minor_adjustment_duration = 2 * ((phy->slot_offset_filtered + 250) / -(insync_minor_adjustment_2));
+ }
+
+ }
+ //else
+ {
+ // out of sync?
+ }
+
+ // NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%4d/%d) VNF phy_id:%d Apply minor insync adjustment %dus for %d slots (adjustment:%d slot_offset_filtered:%d) %d %d %d NEW:%d CURR:%d adj:%d\n",
+ // phy->sfn, phy->slot, ind.header.phy_id,
+ // phy->insync_minor_adjustment, phy->insync_minor_adjustment_duration, phy->adjustment, phy->slot_offset_filtered,
+ // insync_minor_adjustment_1, insync_minor_adjustment_2, phy->slot_offset_trend,
+ // NFAPI_SFNSLOT2DEC(new_sfn, new_slot),
+ // NFAPI_SFNSLOT2DEC(curr_sfn, curr_slot),
+ // phy->adjustment);
+
+ }
+ else if(phy->adjustment < 0)
+ {
+ // VNF is fast
+ //if(phy->adjustment == -1)
+ {
+ //
+ if(phy->slot_offset_filtered > 250)
+ {
+ // VNF is slow
+ phy->insync_minor_adjustment = insync_minor_adjustment_2;
+ phy->insync_minor_adjustment_duration = 2 * ((phy->slot_offset_filtered - 250) / insync_minor_adjustment_2);
+ }
+ else if(phy->slot_offset_filtered < -250)
+ {
+ // VNF is fast
+ phy->insync_minor_adjustment = -(insync_minor_adjustment_2);
+ phy->insync_minor_adjustment_duration = 2 * ((phy->slot_offset_filtered + 250) / -(insync_minor_adjustment_2));
+ }
+ }
+ //else
+ {
+ // out of sync?
+ }
+
+ // NFAPI_TRACE(NFAPI_TRACE_NOTE, "(%d/%d) VNF phy_id:%d Apply minor insync adjustment %dus for %d slots (adjustment:%d slot_offset_filtered:%d) %d %d %d\n",
+ // phy->sfn, phy->slot, ind.header.phy_id,
+ // phy->insync_minor_adjustment, phy->insync_minor_adjustment_duration, phy->adjustment, phy->slot_offset_filtered,
+ // insync_minor_adjustment_1, insync_minor_adjustment_2, phy->slot_offset_trend);
+ }
+
+ /*
+ if (phy->adjustment > 10 || phy->adjustment < -10)
+ {
+ phy->zero_count++; // Add one to the getting out of sync counter
+ }
+ else
+ {
+ phy->zero_count = 0; // Small error - zero the out of sync counter
+ }
+
+ if (phy->zero_count >= 10) // If we have had 10 consecutive large errors - drop out of sync
+ {
+ NFAPI_TRACE(NFAPI_TRACE_NOTE, "we have fallen out of sync...\n");
+ //pP7SockInfo->syncAchieved = 0;
+ }
+ */
+ }
+ }
+ }
+
+
+ if(phy->in_sync == 0)
+ {
+ /*NFAPI_TRACE(NFAPI_TRACE_NOTE, "***** Adjusting VNF phy_id:%d SFN/SF (%s) from %d to %d (%d) mode:%s zeroCount:%u sync:%s\n",
+ ind.header.phy_id, (phy->in_sync ? "via sfn" : "now"),
+ NFAPI_SFNSF2DEC(curr_sfn_sf), NFAPI_SFNSF2DEC(new_sfn_sf), phy->adjustment,
+ phy->filtered_adjust ? "FILTERED" : "ABSOLUTE",
+ phy->zero_count,
+ phy->in_sync ? "IN_SYNC" : "OUT_OF_SYNC");*/
+
+ phy->sfn = new_sfn;
+ phy->slot = new_slot;
+ }
+ }
+
+ // reset for next cycle
+ phy->previous_slot_offset_filtered = phy->slot_offset_filtered;
+ phy->min_sync_cycle_count = 2;
+ phy->slot_offset_filtered = 0;
+ phy->slot_offset = 0;
+ }
+ else
+ {
+ phy->previous_t1 = ind.t1;
+ phy->previous_t2 = ind.t2;
+ }
+}
+
void vnf_handle_timing_info(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
{
if (pRecvMsg == NULL || vnf_p7 == NULL)
@@ -1283,6 +1869,41 @@ void vnf_handle_timing_info(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
}
}
+
+void vnf_nr_handle_timing_info(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
+{
+ if (pRecvMsg == NULL || vnf_p7 == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "vnf_handle_timing_info: NULL parameters\n");
+ return;
+ }
+
+ nfapi_nr_timing_info_t ind;
+ if(nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, &ind, sizeof(nfapi_timing_info_t), &vnf_p7->_public.codec_config) < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "Failed to unpack timing_info\n");
+ return;
+ }
+
+ 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);
+ //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)
+ {
+ 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)) ;
+ // 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;
+ }
+ }
+}
+
void vnf_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
{
nfapi_p7_message_header_t header;
@@ -1378,6 +1999,101 @@ void vnf_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
}
}
+void vnf_nr_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
+{
+ nfapi_p7_message_header_t header;
+
+ // validate the input params
+ if(pRecvMsg == NULL || recvMsgLen < 4 || vnf_p7 == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
+ return;
+ }
+
+ // unpack the message header
+ if (nfapi_p7_message_header_unpack(pRecvMsg, recvMsgLen, &header, sizeof(header), &vnf_p7->_public.codec_config) < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n");
+ return;
+ }
+
+ // ensure the message is sensible
+ if (recvMsgLen < 8 || pRecvMsg == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_WARN, "Invalid message size: %d, ignoring\n", recvMsgLen);
+ return;
+ }
+
+ switch (header.message_id)
+ {
+ case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC:
+ vnf_nr_handle_ul_node_sync(pRecvMsg, recvMsgLen, vnf_p7);
+ break;
+
+ case NFAPI_TIMING_INFO:
+ vnf_nr_handle_timing_info(pRecvMsg, recvMsgLen, vnf_p7);
+ break;
+
+ case NFAPI_HARQ_INDICATION:
+ vnf_handle_harq_indication(pRecvMsg, recvMsgLen, vnf_p7);
+ break;
+
+ case NFAPI_CRC_INDICATION:
+ vnf_handle_crc_indication(pRecvMsg, recvMsgLen, vnf_p7);
+ break;
+
+ case NFAPI_RX_ULSCH_INDICATION:
+ vnf_handle_rx_ulsch_indication(pRecvMsg, recvMsgLen, vnf_p7);
+ break;
+
+ case NFAPI_RACH_INDICATION:
+ vnf_handle_rach_indication(pRecvMsg, recvMsgLen, vnf_p7);
+ break;
+
+ case NFAPI_SRS_INDICATION:
+ vnf_handle_srs_indication(pRecvMsg, recvMsgLen, vnf_p7);
+ break;
+
+ case NFAPI_RX_SR_INDICATION:
+ vnf_handle_rx_sr_indication(pRecvMsg, recvMsgLen, vnf_p7);
+ break;
+
+ case NFAPI_RX_CQI_INDICATION:
+ vnf_handle_rx_cqi_indication(pRecvMsg, recvMsgLen, vnf_p7);
+ break;
+
+ case NFAPI_LBT_DL_INDICATION:
+ vnf_handle_lbt_dl_indication(pRecvMsg, recvMsgLen, vnf_p7);
+ break;
+
+ case NFAPI_NB_HARQ_INDICATION:
+ vnf_handle_nb_harq_indication(pRecvMsg, recvMsgLen, vnf_p7);
+ break;
+
+ case NFAPI_NRACH_INDICATION:
+ vnf_handle_nrach_indication(pRecvMsg, recvMsgLen, vnf_p7);
+ break;
+
+ case NFAPI_UE_RELEASE_RESPONSE:
+ vnf_handle_ue_release_resp(pRecvMsg, recvMsgLen, vnf_p7);
+ break;
+
+ default:
+ {
+ if(header.message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
+ header.message_id <= NFAPI_VENDOR_EXT_MSG_MAX)
+ {
+ vnf_handle_p7_vendor_extension(pRecvMsg, recvMsgLen, vnf_p7, header.message_id);
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Unknown message ID %d\n", header.message_id);
+ }
+ }
+ break;
+ }
+}
+
void vnf_handle_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
{
nfapi_p7_message_header_t messageHeader;
@@ -1496,6 +2212,200 @@ void vnf_handle_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
}
}
+void vnf_nr_handle_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
+{
+ nfapi_p7_message_header_t messageHeader;
+
+ // 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);
+ return;
+ }
+
+ // unpack the message header
+ if (nfapi_p7_message_header_unpack(pRecvMsg, recvMsgLen, &messageHeader, sizeof(nfapi_p7_message_header_t), &vnf_p7->_public.codec_config) < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n");
+ return;
+ }
+
+ if(vnf_p7->_public.checksum_enabled)
+ {
+ uint32_t checksum = nfapi_p7_calculate_checksum(pRecvMsg, recvMsgLen);
+ if(checksum != messageHeader.checksum)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "Checksum verification failed %d %d msg:%d len:%d\n", checksum, messageHeader.checksum, messageHeader.message_id, recvMsgLen);
+ return;
+ }
+ }
+
+ uint8_t m = NFAPI_P7_GET_MORE(messageHeader.m_segment_sequence);
+ uint8_t segment_num = NFAPI_P7_GET_SEGMENT(messageHeader.m_segment_sequence);
+ uint8_t sequence_num = NFAPI_P7_GET_SEQUENCE(messageHeader.m_segment_sequence);
+
+
+ if(m == 0 && segment_num == 0)
+ {
+ // we have a complete message
+ // ensure the message is sensible
+ if (recvMsgLen < 8 || pRecvMsg == NULL)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_WARN, "Invalid message size: %d, ignoring\n", recvMsgLen);
+ return;
+ }
+
+ //vnf_dispatch_p7_message(&messageHeader, pRecvMsg, recvMsgLen, vnf_p7);
+ vnf_nr_dispatch_p7_message(pRecvMsg, recvMsgLen, vnf_p7);
+ }
+ else
+ {
+ nfapi_vnf_p7_connection_info_t* phy = vnf_p7_connection_info_list_find(vnf_p7, messageHeader.phy_id);
+
+ if(phy)
+ {
+ vnf_p7_rx_message_t* rx_msg = vnf_p7_rx_reassembly_queue_add_segment(vnf_p7, &(phy->reassembly_queue), sequence_num, segment_num, m, pRecvMsg, recvMsgLen);
+
+ if(rx_msg->num_segments_received == rx_msg->num_segments_expected)
+ {
+ // send the buffer on
+ uint16_t i = 0;
+ uint16_t length = 0;
+ for(i = 0; i < rx_msg->num_segments_expected; ++i)
+ {
+ length += rx_msg->segments[i].length - (i > 0 ? NFAPI_P7_HEADER_LENGTH : 0);
+ }
+
+ if(phy->reassembly_buffer_size < length)
+ {
+ vnf_p7_free(vnf_p7, phy->reassembly_buffer);
+ phy->reassembly_buffer = 0;
+ }
+
+ if(phy->reassembly_buffer == 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_NOTE, "Resizing VNF_P7 Reassembly buffer %d->%d\n", phy->reassembly_buffer_size, length);
+ phy->reassembly_buffer = (uint8_t*)vnf_p7_malloc(vnf_p7, length);
+
+ if(phy->reassembly_buffer == 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_NOTE, "Failed to allocate VNF_P7 reassemby buffer len:%d\n", length);
+ return;
+ }
+ memset(phy->reassembly_buffer, 0, length);
+ phy->reassembly_buffer_size = length;
+ }
+
+ uint16_t offset = 0;
+ for(i = 0; i < rx_msg->num_segments_expected; ++i)
+ {
+ if(i == 0)
+ {
+ memcpy(phy->reassembly_buffer, rx_msg->segments[i].buffer, rx_msg->segments[i].length);
+ offset += rx_msg->segments[i].length;
+ }
+ else
+ {
+ memcpy(phy->reassembly_buffer + offset, rx_msg->segments[i].buffer + NFAPI_P7_HEADER_LENGTH, rx_msg->segments[i].length - NFAPI_P7_HEADER_LENGTH);
+ offset += rx_msg->segments[i].length - NFAPI_P7_HEADER_LENGTH;
+ }
+ }
+
+
+ //pnf_dispatch_p7_message(pnf_p7->reassemby_buffer, length, pnf_p7, rx_msg->rx_hr_time);
+ vnf_nr_dispatch_p7_message(phy->reassembly_buffer, length , vnf_p7);
+
+
+ // delete the structure
+ vnf_p7_rx_reassembly_queue_remove_msg(vnf_p7, &(phy->reassembly_queue), rx_msg);
+ }
+
+ vnf_p7_rx_reassembly_queue_remove_old_msgs(vnf_p7, &(phy->reassembly_queue), 1000);
+ }
+ else
+ {
+
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "Unknown phy id %d\n", messageHeader.phy_id);
+ }
+ }
+}
+
+int vnf_nr_p7_read_dispatch_message(vnf_p7_t* vnf_p7)
+{
+ int recvfrom_result = 0;
+ struct sockaddr_in remote_addr;
+ socklen_t remote_addr_size = sizeof(remote_addr);
+
+ do
+ {
+ // peek the header
+ uint8_t header_buffer[NFAPI_P7_HEADER_LENGTH];
+ recvfrom_result = recvfrom(vnf_p7->socket, header_buffer, NFAPI_P7_HEADER_LENGTH, MSG_DONTWAIT | MSG_PEEK, (struct sockaddr*)&remote_addr, &remote_addr_size);
+
+ if(recvfrom_result > 0)
+ {
+ // get the segment size
+ nfapi_p7_message_header_t header;
+ if(nfapi_p7_message_header_unpack(header_buffer, NFAPI_P7_HEADER_LENGTH, &header, sizeof(header), 0) < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n");
+ return -1;
+ }
+
+ // resize the buffer if we have a large segment
+ if(header.message_length > vnf_p7->rx_message_buffer_size)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_NOTE, "reallocing rx buffer %d\n", header.message_length);
+ vnf_p7->rx_message_buffer = realloc(vnf_p7->rx_message_buffer, header.message_length);
+ vnf_p7->rx_message_buffer_size = header.message_length;
+ }
+
+ // 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);
+
+ // 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)
+ {
+ vnf_nr_handle_p7_message(vnf_p7->rx_message_buffer, recvfrom_result, vnf_p7);
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "recvfrom failed %d %d\n", recvfrom_result, errno);
+ }
+ }
+
+ if(recvfrom_result == -1)
+ {
+ if(errno == EAGAIN || errno == EWOULDBLOCK)
+ {
+ // return to the select
+ //NFAPI_TRACE(NFAPI_TRACE_WARN, "%s recvfrom would block :%d\n", __FUNCTION__, errno);
+ }
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_WARN, "%s recvfrom failed errno:%d\n", __FUNCTION__, errno);
+ }
+ }
+ }
+ while(recvfrom_result > 0);
+
+ return 0;
+}
+
int vnf_p7_read_dispatch_message(vnf_p7_t* vnf_p7)
{
int recvfrom_result = 0;
diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c b/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c
index a0efeeb5f4..3fa1f035fd 100644
--- a/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c
+++ b/nfapi/open-nFAPI/vnf/src/vnf_p7_interface.c
@@ -28,6 +28,7 @@
#define FAPI2_IP_DSCP 0
+
nfapi_vnf_p7_config_t* nfapi_vnf_p7_config_create()
{
vnf_p7_t* _this = (vnf_p7_t*)calloc(1, sizeof(vnf_p7_t));
@@ -90,6 +91,368 @@ struct timespec timespec_sub(struct timespec lhs, struct timespec rhs)
// 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)
+{
+ if(config == 0)
+ return -1;
+
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "%s()\n", __FUNCTION__);
+
+ vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
+
+ // 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
+ if ((vnf_p7->socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "After P7 socket errno: %d\n", errno);
+ return -1;
+ }
+
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 socket created...\n");
+
+ // configure the UDP socket options
+ int iptos_value = FAPI2_IP_DSCP << 2;
+ if (setsockopt(vnf_p7->socket, IPPROTO_IP, IP_TOS, &iptos_value, sizeof(iptos_value)) < 0)
+ {
+ 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
+ struct sockaddr_in addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(config->port);
+ addr.sin_addr.s_addr = INADDR_ANY;
+
+ // bind to the configured port
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 binding too %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
+ if (bind(vnf_p7->socket, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0)
+ //if (sctp_bindx(config->socket, (struct sockaddr *)&addr, sizeof(struct sockaddr_in), 0) < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "After bind errno: %d\n", errno);
+ return -1;
+ }
+
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 bind succeeded...\n");
+
+
+ //struct timespec original_pselect_timeout;
+ struct timespec pselect_timeout;
+ pselect_timeout.tv_sec = 0;
+ pselect_timeout.tv_nsec = 500000; // ns in a 0.5 ms
+ //pselect_timeout.tv_nsec = 500000;
+
+ struct timespec pselect_start;
+ struct timespec pselect_stop;
+
+ //struct timespec sf_end;
+
+ long last_millisecond = -1;
+
+
+// struct timespec sf_duration; //Change to slot_duration?
+// sf_duration.tv_sec = 0;
+// sf_duration.tv_nsec = 0.5e6; // We want 1ms pause //We want 0.5 ms pause for NR
+ struct timespec slot_duration;
+ slot_duration.tv_sec = 0;
+ //slot_duration.tv_nsec = 0.5e6;
+ slot_duration.tv_nsec = 0.5e6;
+
+
+// struct timespec sf_start; //Change to slot_start?
+ struct timespec slot_start;
+// clock_gettime(CLOCK_MONOTONIC, &sf_start);
+ clock_gettime(CLOCK_MONOTONIC, &slot_start);
+ long millisecond = slot_start.tv_nsec / 1e6; //Check if we have to change
+ //long millisecond = slot_start.tv_nsec / 0.5e6;
+// sf_start = timespec_add(sf_start, sf_duration);
+ slot_start = timespec_add(slot_start, slot_duration);
+
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "next slot will start at %d.%d\n", slot_start.tv_sec, slot_start.tv_nsec);
+
+ while(vnf_p7->terminate == 0)
+ {
+ fd_set rfds;
+ int maxSock = 0;
+ FD_ZERO(&rfds);
+ int selectRetval = 0;
+
+ // 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;
+
+ if((last_millisecond == -1) || (millisecond == last_millisecond) || (millisecond == (last_millisecond + 1) % 1000) )
+ {
+ //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) ||
+ // ((pselect_start.tv_sec == sf_start.tv_sec) && (pselect_start.tv_nsec > sf_start.tv_nsec)))
+ 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
+ pselect_timeout.tv_sec = 0;
+ pselect_timeout.tv_nsec = 0;
+
+ //struct timespec overrun = 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
+ //pselect_timeout = timespec_sub(sf_start, pselect_start);
+ pselect_timeout = timespec_sub(slot_start, pselect_start);
+ }
+
+//original_pselect_timeout = pselect_timeout;
+
+ // detemine how long to sleep in ns before the start of the next 1ms
+ //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;
+ /*
+ {
+ nfapi_vnf_p7_connection_info_t* phy = vnf_p7->p7_connections;
+ 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))
+ if(phy->insync_minor_adjustment > 0)
+ {
+ // todo check we don't go below 0
+ if((phy->insync_minor_adjustment * 1000) > pselect_timeout.tv_nsec)
+ pselect_timeout.tv_nsec = 0;
+ else
+ pselect_timeout.tv_nsec = pselect_timeout.tv_nsec - (phy->insync_minor_adjustment * 1000);
+
+
+ //underrun_possible = 1;
+ }
+ else if(phy->insync_minor_adjustment < 0)
+ {
+ // todo check we don't go below 0
+ pselect_timeout.tv_nsec = pselect_timeout.tv_nsec - (phy->insync_minor_adjustment * 1000);
+
+
+ //phy->insync_minor_adjustment = 0;
+ phy->insync_minor_adjustment_duration--;
+ }
+ }
+ */
+
+
+//long wraps = pselect_timeout.tv_nsec % 1e9;
+
+
+ selectRetval = pselect(maxSock+1, &rfds, NULL, NULL, &pselect_timeout, NULL);
+ // selectRetval = pselect(120, &rfds, NULL, NULL, &pselect_timeout, NULL);
+
+ clock_gettime(CLOCK_MONOTONIC, &pselect_stop);
+
+ nfapi_vnf_p7_connection_info_t* phy = vnf_p7->p7_connections;
+
+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,
+// sf_duration.tv_sec, sf_duration.tv_nsec);
+
+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,
+ slot_duration.tv_sec, slot_duration.tv_nsec);
+
+}
+ if(selectRetval == 0)
+ {
+ // calculate the start of the next slot
+ //sf_start = timespec_add(sf_start, sf_duration);
+ slot_start = timespec_add(slot_start, slot_duration);
+ //NFAPI_TRACE(NFAPI_TRACE_INFO, "next subframe will start at %d.%d\n", sf_start.tv_sec, sf_start.tv_nsec);
+
+ if(phy && phy->in_sync && phy->insync_minor_adjustment != 0 && phy->insync_minor_adjustment_duration > 0)
+ {
+ long insync_minor_adjustment_ns = (phy->insync_minor_adjustment * 1000);
+
+ //sf_start.tv_nsec -= insync_minor_adjustment_ns;
+ slot_start.tv_nsec -= insync_minor_adjustment_ns;
+
+#if 1
+/* if (sf_start.tv_nsec > 1e9) //Change to 0.5e6?
+ {
+ sf_start.tv_sec++;
+ sf_start.tv_nsec-=1e9;
+ }
+ else if (sf_start.tv_nsec < 0)
+ {
+ sf_start.tv_sec--;
+ sf_start.tv_nsec+=1e9;
+ }*/
+ if (slot_start.tv_nsec > 1e9)
+ {
+ slot_start.tv_sec++;
+ slot_start.tv_nsec-=1e9;
+ }
+ else if (slot_start.tv_nsec < 0)
+ {
+ slot_start.tv_sec--;
+ slot_start.tv_nsec+=1e9;
+ }
+#else
+ //NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] BEFORE adjustment - Subframe minor adjustment %dus sf_start.tv_nsec:%d\n", phy->insync_minor_adjustment, sf_start.tv_nsec);
+ if(phy->insync_minor_adjustment > 0)
+ {
+ // decrease the subframe duration a little
+ if (sf_start.tv_nsec > insync_minor_adjustment_ns)
+ sf_start.tv_nsec -= insync_minor_adjustment_ns;
+ else
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "[VNF] Adjustment would make it negative sf:%d.%ld adjust:%ld\n\n\n", sf_start.tv_sec, sf_start.tv_nsec, insync_minor_adjustment_ns);
+ sf_start.tv_sec--;
+ sf_start.tv_nsec += 1e9 - insync_minor_adjustment_ns;
+ }
+ }
+ else if(phy->insync_minor_adjustment < 0)
+ {
+ // todo check we don't go below 0
+ // increase the subframe duration a little
+ sf_start.tv_nsec += insync_minor_adjustment_ns;
+
+ if (sf_start.tv_nsec < 0)
+ {
+ NFAPI_TRACE(NFAPI_TRACE_ERROR, "[VNF] OVERFLOW %d.%ld\n\n\n\n", sf_start.tv_sec, sf_start.tv_nsec);
+ sf_start.tv_sec++;
+ sf_start.tv_nsec += 1e9;
+ }
+ }
+#endif
+
+ //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",
+// phy->insync_minor_adjustment, sf_start.tv_nsec, phy->insync_minor_adjustment_duration);
+ // NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] AFTER adjustment - Slot minor adjustment %dus slot_start.tv_nsec:%d duration:%u\n",
+ // phy->insync_minor_adjustment, slot_start.tv_nsec, phy->insync_minor_adjustment_duration);
+
+ if (phy->insync_minor_adjustment_duration==0)
+ {
+ phy->insync_minor_adjustment = 0;
+ }
+ }
+ /*
+ long pselect_stop_millisecond = pselect_stop.tv_nsec / 1e6;
+ if(millisecond == pselect_stop_millisecond)
+ {
+ // we have woke up in the same subframe
+ if(underrun_possible == 0)
+ NFAPI_TRACE(NFAPI_TRACE_WARN, "subframe pselect underrun %ld (%d.%d)\n", millisecond, pselect_stop.tv_sec, pselect_stop.tv_nsec);
+ }
+ else if(((millisecond + 1) % 1000) != pselect_stop_millisecond)
+ {
+ // we have overrun the subframe
+ NFAPI_TRACE(NFAPI_TRACE_WARN, "subframe pselect overrun %ld %ld\n", millisecond, pselect_stop_millisecond);
+ NFAPI_TRACE(NFAPI_TRACE_WARN, "subframe underrun %ld\n", millisecond);
+ }
+ last_millisecond = millisecond;
+ */
+
+ //millisecond ++;
+ millisecond = millisecond + 1;
+
+ }
+ }
+ else
+ {
+ // we have overrun the subframe advance to go and collect $200
+
+ if((millisecond - last_millisecond) > 3)
+ NFAPI_TRACE(NFAPI_TRACE_WARN, "subframe overrun %ld %ld (%ld)\n", millisecond, last_millisecond, millisecond - last_millisecond + 1);
+
+ last_millisecond = ( last_millisecond + 1 ) % 1000;
+ selectRetval = 0;
+ }
+
+ if(selectRetval == 0)
+ {
+ //vnf_p7->sf_start_time_hr = vnf_get_current_time_hr();
+ vnf_p7->slot_start_time_hr = vnf_get_current_time_hr();
+struct timespec current_time;
+ clock_gettime(CLOCK_MONOTONIC, ¤t_time);
+ // pselect timed out
+ nfapi_vnf_p7_connection_info_t* curr = vnf_p7->p7_connections;
+ while(curr != 0)
+ {
+ if (curr->slot == 19)
+ { //curr->slot = 0;
+ if(curr->sfn == 1023)
+ curr->sfn=0;
+ else
+ curr->sfn++;
+ curr->slot=0;
+ }
+ else
+ {
+ curr->slot++;
+ }
+ vnf_nr_sync(vnf_p7, curr);
+ curr = curr->next;
+ }
+ send_mac_slot_indications(vnf_p7);
+ }
+ else if(selectRetval > 0)
+ {
+ // have a p7 message
+ if(FD_ISSET(vnf_p7->socket, &rfds))
+ {
+ vnf_nr_p7_read_dispatch_message(vnf_p7);
+ }
+ }
+ else
+ {
+ // pselect error
+ if(selectRetval == -1 && errno == EINTR)
+ {
+ // a sigal was received.
+ }
+ 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);
+ // should we exit now?
+ if (selectRetval == -1 && errno == 22) // invalid argument??? not sure about timeout duration
+ {
+ usleep(100000);
+ }
+ }
+ }
+
+ }
+
+
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "Closing p7 socket\n");
+ close(vnf_p7->socket);
+
+ NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() returning\n", __FUNCTION__);
+
+ return 0;
+}
+
+
int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config)
{
if(config == 0)
@@ -408,6 +771,7 @@ if (selectRetval==-1 && errno == 22)
return 0;
}
+
int nfapi_vnf_p7_stop(nfapi_vnf_p7_config_t* config)
{
if(config == 0)
@@ -434,17 +798,18 @@ int nfapi_vnf_p7_add_pnf(nfapi_vnf_p7_config_t* config, const char* pnf_p7_addr,
memset(node, 0, sizeof(nfapi_vnf_p7_connection_info_t));
node->phy_id = phy_id;
node->in_sync = 0;
- node->dl_out_sync_offset = 30;
+ node->dl_out_sync_offset = 30;//TODO: Values need to be changed for NR,How to set the values
node->dl_out_sync_period = 10;
node->dl_in_sync_offset = 30;
node->dl_in_sync_period = 512;
- node->sfn_sf = 0;
-
+ //node->sfn_sf = 0;
+ node->sfn = 0;
+ node->slot = 0;
node->min_sync_cycle_count = 8;
// save the remote endpoint information
node->remote_addr.sin_family = AF_INET;
- node->remote_addr.sin_port = htons(pnf_p7_port);
+ node->remote_addr.sin_port = pnf_p7_port;//htons(pnf_p7_port);
node->remote_addr.sin_addr.s_addr = inet_addr(pnf_p7_addr);
vnf_p7_connection_info_list_add(vnf_p7, node);
@@ -490,7 +855,16 @@ int nfapi_vnf_p7_nr_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_nr_dl_tti
return -1;
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
- return vnf_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
+ return vnf_nr_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
+}
+
+int nfapi_vnf_p7_ul_tti_req(nfapi_vnf_p7_config_t* config, nfapi_nr_ul_tti_request_t* req)
+{
+ if(config == 0 || req == 0)
+ return -1;
+
+ vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
+ return vnf_nr_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
}
int nfapi_vnf_p7_ul_config_req(nfapi_vnf_p7_config_t* config, nfapi_ul_config_request_t* req)
@@ -501,6 +875,14 @@ int nfapi_vnf_p7_ul_config_req(nfapi_vnf_p7_config_t* config, nfapi_ul_config_re
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
return vnf_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
}
+int nfapi_vnf_p7_ul_dci_req(nfapi_vnf_p7_config_t* config, nfapi_nr_ul_dci_request_t* req)
+{
+ if(config == 0 || req == 0)
+ return -1;
+
+ vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
+ return vnf_nr_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
+}
int nfapi_vnf_p7_hi_dci0_req(nfapi_vnf_p7_config_t* config, nfapi_hi_dci0_request_t* req)
{
if(config == 0 || req == 0)
@@ -509,6 +891,14 @@ int nfapi_vnf_p7_hi_dci0_req(nfapi_vnf_p7_config_t* config, nfapi_hi_dci0_reques
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
return vnf_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
}
+int nfapi_vnf_p7_tx_data_req(nfapi_vnf_p7_config_t* config, nfapi_nr_tx_data_request_t* req)
+{
+ if(config == 0 || req == 0)
+ return -1;
+
+ vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
+ return vnf_nr_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
+}
int nfapi_vnf_p7_tx_req(nfapi_vnf_p7_config_t* config, nfapi_tx_request_t* req)
{
if(config == 0 || req == 0)
diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c
index bd6b944fef..ab363fcae4 100644
--- a/openair1/PHY/INIT/nr_init.c
+++ b/openair1/PHY/INIT/nr_init.c
@@ -20,6 +20,7 @@
*/
#include "executables/nr-softmodem-common.h"
+#include "common/utils/nr/nr_common.h"
#include "PHY/defs_gNB.h"
#include "PHY/phy_extern.h"
#include "PHY/NR_REFSIG/nr_refsig.h"
@@ -45,10 +46,42 @@
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
-/*
-extern uint32_t from_nrarfcn(int nr_bandP,uint32_t dl_nrarfcn);
-extern openair0_config_t openair0_cfg[MAX_CARDS];
-*/
+static
+uint16_t get_band(uint64_t downlink_frequency, int32_t delta_duplex)
+{
+ const uint64_t dl_freq_khz = downlink_frequency / 1000;
+ const int32_t delta_duplex_khz = delta_duplex / 1000;
+
+ uint64_t center_freq_diff_khz = 999999999999999999; // 2^64
+ uint16_t current_band = 0;
+
+ for (int ind = 0; ind < nr_bandtable_size; ind++) {
+
+ LOG_D(PHY, "Scanning band %d, dl_min %"PRIu64", ul_min %"PRIu64"\n", nr_bandtable[ind].band, nr_bandtable[ind].dl_min, nr_bandtable[ind].ul_min);
+
+ if (dl_freq_khz < nr_bandtable[ind].dl_min || dl_freq_khz > nr_bandtable[ind].dl_max)
+ continue;
+
+ int32_t current_offset_khz = nr_bandtable[ind].ul_min - nr_bandtable[ind].dl_min;
+
+ if (current_offset_khz != delta_duplex_khz)
+ continue;
+
+ uint64_t center_frequency_khz = (nr_bandtable[ind].dl_max + nr_bandtable[ind].dl_min) / 2;
+
+ if (abs(dl_freq_khz - center_frequency_khz) < center_freq_diff_khz){
+ current_band = nr_bandtable[ind].band;
+ center_freq_diff_khz = abs(dl_freq_khz - center_frequency_khz);
+ }
+ }
+
+ LOG_I(PHY, "DL frequency %"PRIu64": band %d, UL frequency %"PRIu64"\n",
+ downlink_frequency, current_band, downlink_frequency+delta_duplex);
+
+ AssertFatal(current_band != 0, "Can't find EUTRA band for frequency %"PRIu64" and duplex_spacing %u\n", downlink_frequency, delta_duplex);
+
+ return current_band;
+}
int l1_north_init_gNB() {
@@ -381,6 +414,13 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
}
+
+//Adding nr_schedule_handler
+void install_nr_schedule_handlers(NR_IF_Module_t *if_inst)
+{
+ if_inst->NR_PHY_config_req = nr_phy_config_request;
+ if_inst->NR_Schedule_response = nr_schedule_response;
+}
/*
void install_schedule_handlers(IF_Module_t *if_inst)
{
@@ -448,7 +488,6 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
uint8_t short_sequence, num_sequences, rootSequenceIndex, fd_occasion;
NR_DL_FRAME_PARMS *fp = &RC.gNB[Mod_id]->frame_parms;
nfapi_nr_config_request_scf_t *gNB_config = &RC.gNB[Mod_id]->gNB_config;
- int32_t dlul_offset = 0;
memcpy((void*)gNB_config,phy_config->cfg,sizeof(*phy_config->cfg));
RC.gNB[Mod_id]->mac_enabled = 1;
@@ -459,13 +498,9 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
uint64_t ul_bw_khz = (12*gNB_config->carrier_config.ul_grid_size[gNB_config->ssb_config.scs_common.value].value)*(15<ssb_config.scs_common.value);
fp->ul_CarrierFreq = ((ul_bw_khz>>1) + gNB_config->carrier_config.uplink_frequency.value)*1000 ;
- fp->nr_band = *RC.nrmac[Mod_id]->common_channels[0].ServingCellConfigCommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
+ int32_t dlul_offset = fp->ul_CarrierFreq - fp->dl_CarrierFreq;
+ fp->nr_band = get_band(fp->dl_CarrierFreq, dlul_offset);
- get_delta_duplex(fp->nr_band, gNB_config->ssb_config.scs_common.value, &dlul_offset);
- dlul_offset *= 1000;
-
- AssertFatal(fp->ul_CarrierFreq == (fp->dl_CarrierFreq + dlul_offset), "Disagreement in uplink frequency for band %d: ul_CarrierFreq = %lu Hz vs expected %lu Hz\n", fp->nr_band, fp->ul_CarrierFreq, fp->dl_CarrierFreq + dlul_offset);
-
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;
@@ -494,11 +529,12 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) {
// }
RC.gNB[Mod_id]->configured = 1;
- init_symbol_rotation(fp,fp->dl_CarrierFreq);
+ init_symbol_rotation(fp);
LOG_I(PHY,"gNB %d configured\n",Mod_id);
}
+
void init_nr_transport(PHY_VARS_gNB *gNB) {
int i;
int j;
diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c
index 7c4b342ed8..2d3ca4d5e4 100644
--- a/openair1/PHY/INIT/nr_init_ue.c
+++ b/openair1/PHY/INIT/nr_init_ue.c
@@ -335,7 +335,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
ue->pdsch_vars[th_id][gNB_id]->llr[1] = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) );
ue->pdsch_vars[th_id][gNB_id]->layer_llr[1] = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) );
ue->pdsch_vars[th_id][gNB_id]->llr128_2ndstream = (int16_t **)malloc16_clear( sizeof(int16_t *) );
- ue->pdsch_vars[th_id][gNB_id]->rho = (int32_t **)malloc16_clear( 4*fp->nb_antennas_rx*sizeof(int32_t *) );
}
@@ -350,7 +349,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue,
for (th_id=0; th_idpdsch_vars[th_id][gNB_id]->dl_ch_rho2_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
- ue->pdsch_vars[th_id][gNB_id]->rho[idx] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
}
}
diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c
index 814177a86c..a61a476429 100644
--- a/openair1/PHY/INIT/nr_parms.c
+++ b/openair1/PHY/INIT/nr_parms.c
@@ -357,9 +357,8 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
fp->N_RB_UL = config->carrier_config.ul_grid_size[fp->numerology_index];
fp->N_RB_DL = config->carrier_config.dl_grid_size[fp->numerology_index];
- int32_t uplink_frequency_offset = 0;
- get_delta_duplex(fp->nr_band, fp->numerology_index, &uplink_frequency_offset);
- get_frame_type(fp->nr_band, fp->numerology_index, &fp->frame_type);
+ fp->frame_type = get_frame_type(fp->nr_band, fp->numerology_index);
+ int32_t uplink_frequency_offset = get_delta_duplex(fp->nr_band, fp->numerology_index);
uplink_frequency_offset *= 1000;
LOG_I(PHY, "Initializing frame parms: DL frequency %lu Hz, UL frequency %lu Hz: band %d, uldl offset %d Hz\n", fp->dl_CarrierFreq, fp->ul_CarrierFreq, fp->nr_band, uplink_frequency_offset);
diff --git a/openair1/PHY/MODULATION/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c
index b41007f0e1..e32f6bf575 100644
--- a/openair1/PHY/MODULATION/nr_modulation.c
+++ b/openair1/PHY/MODULATION/nr_modulation.c
@@ -418,10 +418,10 @@ void nr_ue_layer_mapping(NR_UE_ULSCH_t **ulsch_ue,
void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH)
{
-#if defined(__x86_64__) || defined(__i386__)
- __m128i dft_in128[1][1200], dft_out128[1][1200];
+#if defined(__x86_64__) || +defined(__i386__)
+ __m128i dft_in128[1][3240], dft_out128[1][3240];
#elif defined(__arm__)
- int16x8_t dft_in128[1][1200], dft_out128[1][1200];
+ int16x8_t dft_in128[1][3240], dft_out128[1][3240];
#endif
uint32_t *dft_in0 = (uint32_t*)dft_in128[0], *dft_out0 = (uint32_t*)dft_out128[0];
@@ -433,8 +433,10 @@ void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH)
int16x8_t norm128;
#endif
- for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) {
- dft_in0[ip] = d[i];
+ if ((Msc_PUSCH % 1536) > 0) {
+ for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) {
+ dft_in0[ip] = d[i];
+ }
}
switch (Msc_PUSCH) {
@@ -573,7 +575,7 @@ void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH)
break;
case 972:
- dft(DFT_960,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ dft(DFT_972,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
case 1080:
@@ -587,44 +589,159 @@ void nr_dft(int32_t *z, int32_t *d, uint32_t Msc_PUSCH)
case 1200:
dft(DFT_1200,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
break;
+
+ case 1296:
+ dft(DFT_1296,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ case 1440:
+ dft(DFT_1440,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ case 1500:
+ dft(DFT_1500,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ case 1536:
+ //dft(DFT_1536,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ dft(DFT_1536,(int16_t*)d, (int16_t*)z, 1);
+ break;
+
+ case 1620:
+ dft(DFT_1620,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ case 1728:
+ dft(DFT_1728,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ case 1800:
+ dft(DFT_1800,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ case 1920:
+ dft(DFT_1920,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ case 1944:
+ dft(DFT_1944,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ case 2160:
+ dft(DFT_2160,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ case 2304:
+ dft(DFT_2304,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ case 2400:
+ dft(DFT_2400,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ case 2592:
+ dft(DFT_2592,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ case 2700:
+ dft(DFT_2700,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ case 2880:
+ dft(DFT_2880,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ case 2916:
+ dft(DFT_2916,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ case 3000:
+ dft(DFT_3000,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ case 3072:
+ //dft(DFT_3072,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ dft(DFT_3072,(int16_t*)d, (int16_t*)z, 1);
+ break;
+
+ case 3240:
+ dft(DFT_3240,(int16_t*)dft_in0, (int16_t*)dft_out0, 1);
+ break;
+
+ default:
+ // should not be reached
+ LOG_E( PHY, "Unsupported Msc_PUSCH value of %"PRIu16"\n", Msc_PUSCH );
+ return;
+
}
- for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) {
- z[i] = dft_out0[ip];
+
+ if ((Msc_PUSCH % 1536) > 0) {
+ for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4)
+ z[i] = dft_out0[ip];
}
+
}
-void init_symbol_rotation(NR_DL_FRAME_PARMS *fp,uint64_t CarrierFreq)
-{
+void init_symbol_rotation(NR_DL_FRAME_PARMS *fp) {
+
+ uint64_t dl_CarrierFreq = fp->dl_CarrierFreq;
+ uint64_t ul_CarrierFreq = fp->ul_CarrierFreq;
+ double f[2] = {(double)dl_CarrierFreq, (double)ul_CarrierFreq};
+
const int nsymb = fp->symbols_per_slot * fp->slots_per_frame/10;
const double Tc=(1/480e3/4096);
const double Nu=2048*64*(1/(float)(1<numerology_index));
- const double f0= (double)CarrierFreq;
const double Ncp0=16*64 + (144*64*(1/(float)(1<numerology_index)));
const double Ncp1=(144*64*(1/(float)(1<numerology_index)));
- double tl=0,poff,exp_re,exp_im;
- double Ncp,Ncpm1=Ncp0;
- poff = 2*M_PI*((Ncp0*Tc))*f0;
- exp_re = cos(poff);
- exp_im = sin(-poff);
- fp->symbol_rotation[0]=(int16_t)floor(exp_re*32767);
- fp->symbol_rotation[1]=(int16_t)floor(exp_im*32767);
- LOG_I(PHY,"Doing symbol rotation calculation for gNB TX/RX, f0 %f Hz, Nsymb %d\n",f0,nsymb);
- LOG_I(PHY,"Symbol rotation %d/%d => (%d,%d)\n",0,nsymb,fp->symbol_rotation[0],fp->symbol_rotation[1]);
+ for (uint8_t ll = 0; ll < 2; ll++){
- for (int l=1; lnumerology_index))) Ncp=Ncp0;
- else Ncp=Ncp1;
- tl += (Nu+Ncpm1)*Tc;
- poff = 2*M_PI*(tl + (Ncp*Tc))*f0;
- exp_re = cos(poff);
- exp_im = sin(-poff);
- fp->symbol_rotation[l<<1]=(int16_t)floor(exp_re*32767);
- fp->symbol_rotation[1+(l<<1)]=(int16_t)floor(exp_im*32767);
- LOG_I(PHY,"Symbol rotation %d/%d => tl %f (%d,%d) (%f)\n", l, nsymb, tl, fp->symbol_rotation[l<<1], fp->symbol_rotation[1+(l<<1)], (poff/2/M_PI)-floor(poff/2/M_PI));
- Ncpm1=Ncp;
+ double f0 = f[ll];
+ double Ncpm1 = Ncp0;
+ int16_t *symbol_rotation = fp->symbol_rotation[ll];
+
+ double tl = 0;
+ double poff = 2 * M_PI * ((Ncp0 * Tc)) * f0;
+ double exp_re = cos(poff);
+ double exp_im = sin(-poff);
+ symbol_rotation[0] = (int16_t)floor(exp_re * 32767);
+ symbol_rotation[1] = (int16_t)floor(exp_im * 32767);
+ LOG_I(PHY, "Doing symbol rotation calculation for gNB TX/RX, f0 %f Hz, Nsymb %d\n", f0, nsymb);
+ LOG_I(PHY, "Symbol rotation %d/%d => (%d,%d)\n",
+ 0,
+ nsymb,
+ symbol_rotation[0],
+ symbol_rotation[1]);
+
+ for (int l = 1; l < nsymb; l++) {
+
+ double Ncp;
+ if (l == (7 * (1 << fp->numerology_index))) {
+ Ncp = Ncp0;
+ } else {
+ Ncp = Ncp1;
+ }
+
+ tl += (Nu + Ncpm1) * Tc;
+ poff = 2 * M_PI * (tl + (Ncp * Tc)) * f0;
+ exp_re = cos(poff);
+ exp_im = sin(-poff);
+ symbol_rotation[l<<1] = (int16_t)floor(exp_re * 32767);
+ symbol_rotation[1 + (l<<1)] = (int16_t)floor(exp_im * 32767);
+
+ LOG_I(PHY, "Symbol rotation %d/%d => tl %f (%d,%d) (%f)\n",
+ l,
+ nsymb,
+ tl,
+ symbol_rotation[l<<1],
+ symbol_rotation[1 + (l<<1)],
+ (poff / 2 / M_PI) - floor(poff / 2 / M_PI));
+
+ Ncpm1 = Ncp;
+
+ }
}
}
diff --git a/openair1/PHY/MODULATION/nr_modulation.h b/openair1/PHY/MODULATION/nr_modulation.h
index d81fd0f2c8..9c80b35718 100644
--- a/openair1/PHY/MODULATION/nr_modulation.h
+++ b/openair1/PHY/MODULATION/nr_modulation.h
@@ -117,7 +117,7 @@ void apply_nr_rotation(NR_DL_FRAME_PARMS *fp,
int nsymb,
int length);
-void init_symbol_rotation(NR_DL_FRAME_PARMS *fp,uint64_t CarrierFreq);
+void init_symbol_rotation(NR_DL_FRAME_PARMS *fp);
void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms,
int32_t *rxdataF,
diff --git a/openair1/PHY/MODULATION/ofdm_mod.c b/openair1/PHY/MODULATION/ofdm_mod.c
index 2d86b46742..8cf9f05b9b 100644
--- a/openair1/PHY/MODULATION/ofdm_mod.c
+++ b/openair1/PHY/MODULATION/ofdm_mod.c
@@ -306,15 +306,23 @@ void apply_nr_rotation(NR_DL_FRAME_PARMS *fp,
int length) {
int symb_offset = (slot%fp->slots_per_subframe)*fp->symbols_per_slot;
+ int16_t *symbol_rotation = fp->symbol_rotation[0];
+
for (int sidx=0;sidxsymbol_rotation[2*(sidx+first_symbol+symb_offset)],fp->symbol_rotation[1+2*(sidx+first_symbol+symb_offset)]);
- rotate_cpx_vector(trxdata+(sidx*length*2),
- &fp->symbol_rotation[2*(sidx+first_symbol+symb_offset)],
- trxdata+(sidx*length*2),
- length,
- 15);
+ first_symbol + sidx,
+ slot,
+ sidx + first_symbol + symb_offset,
+ length,
+ symbol_rotation[2 * (sidx + first_symbol + symb_offset)],
+ symbol_rotation[1 + 2 * (sidx + first_symbol + symb_offset)]);
+
+ rotate_cpx_vector(trxdata + (sidx * length * 2),
+ &symbol_rotation[2 * (sidx + first_symbol + symb_offset)],
+ trxdata + (sidx * length * 2),
+ length,
+ 15);
}
}
diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c
index 60b28d4ad1..7b5ddb230a 100644
--- a/openair1/PHY/MODULATION/slot_fep_nr.c
+++ b/openair1/PHY/MODULATION/slot_fep_nr.c
@@ -205,7 +205,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
#endif
int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot;
- int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation)[symbol+symb_offset];
+ int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation[0])[symbol + symb_offset];
((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1];
rotate_cpx_vector((int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
(int16_t*)&rot2,
@@ -386,7 +386,7 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
}
int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot;
- int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation)[symbol+symb_offset];
+ int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation[0])[symbol + symb_offset];
((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1];
#ifdef DEBUG_FEP
@@ -513,7 +513,7 @@ void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms,
for (int symbol=0;symbolsymbol_rotation)[symbol+symb_offset];
+ uint32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation[1])[symbol + symb_offset];
((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1];
LOG_D(PHY,"slot %d, symb_offset %d rotating by %d.%d\n",slot,symb_offset,((int16_t*)&rot2)[0],((int16_t*)&rot2)[1]);
rotate_cpx_vector((int16_t *)&rxdataF[frame_parms->ofdm_symbol_size*symbol],
diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
index a0fc83d183..967868f803 100644
--- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
+++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
@@ -61,8 +61,6 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
debug_ch_est = fopen("debug_ch_est.txt","w");
#endif
- //uint16_t Nid_cell = (eNB_offset == 0) ? gNB->frame_parms.Nid_cell : gNB->measurements.adj_cell_id[eNB_offset-1];
-
uint8_t nushift;
int **ul_ch_estimates = gNB->pusch_vars[ul_id]->ul_ch_estimates;
int **rxdataF = gNB->common_vars.rxdataF;
@@ -79,12 +77,17 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
uint16_t nb_rb_pusch = pusch_pdu->rb_size;
-/*
#ifdef DEBUG_CH
- printf("PUSCH Channel Estimation : ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d symbol %d\n", ,ch_offset,symbol_offset,gNB->frame_parms.ofdm_symbol_size,
- gNB->frame_parms.Ncp,l,Ns,k, symbol);
+ LOG_D(PHY, "In %s: ch_offset %d, symbol_offset %d OFDM size %d, Ns = %d, k = %d symbol %d\n",
+ __FUNCTION__,
+ ch_offset,
+ symbol_offset,
+ gNB->frame_parms.ofdm_symbol_size,
+ Ns,
+ k,
+ symbol);
#endif
-*/
+
switch (nushift) {
case 0:
fl = filt8_l0;
@@ -124,9 +127,9 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
//------------------generate DMRS------------------//
- if (pusch_pdu->transform_precoding == transform_precoder_disabled)
+ if (pusch_pdu->transform_precoding == transform_precoder_disabled) {
nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], 1000, 0, nb_rb_pusch, pusch_pdu->rb_start*NR_NB_SC_PER_RB, pusch_pdu->dmrs_config_type);
-
+ }
else { // if transform precoding or SC-FDMA is enabled in Uplink
// NR_SC_FDMA supports type1 DMRS so only 6 DMRS REs per RB possible
@@ -151,13 +154,19 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
//------------------------------------------------//
-
#ifdef DEBUG_PUSCH
- for (int i=0;i<(6*nb_rb_pusch);i++)
- printf("%d+j*(%d)\n",((int16_t*)pilot)[2*i],((int16_t*)pilot)[1+(2*i)]);
+ for (int i = 0; i < (6 * nb_rb_pusch); i++) {
+ LOG_I(PHY, "In %s: %d + j*(%d)\n",
+ __FUNCTION__,
+ ((int16_t*)pilot)[2 * i],
+ ((int16_t*)pilot)[1 + (2 * i)]);
+ }
#endif
+
for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) {
+ re_offset = k; /* Initializing the Resource element offset for each Rx antenna */
+
pil = (int16_t *)&pilot[0];
rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+nushift)];
ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset];
@@ -166,11 +175,11 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
memset(ul_ch,0,4*(gNB->frame_parms.ofdm_symbol_size));
#ifdef DEBUG_PUSCH
- printf("symbol_offset %d, nushift %d\n",symbol_offset,nushift);
- printf("ch est pilot addr %p RB_DL %d\n",&pilot[0], gNB->frame_parms.N_RB_UL);
- printf("bwp_start_subcarrier %d, k %d, first_carrier %d, nb_rb_pusch %d\n",bwp_start_subcarrier,k,gNB->frame_parms.first_carrier_offset,nb_rb_pusch);
- printf("rxF addr %p p %d\n", rxF,p);
- printf("ul_ch addr %p nushift %d\n",ul_ch,nushift);
+ LOG_I(PHY, "In %s symbol_offset %d, nushift %d\n", __FUNCTION__, symbol_offset, nushift);
+ LOG_I(PHY, "In %s ch est pilot addr %p, N_RB_UL %d\n", __FUNCTION__, &pilot[0], gNB->frame_parms.N_RB_UL);
+ LOG_I(PHY, "In %s bwp_start_subcarrier %d, k %d, first_carrier %d, nb_rb_pusch %d\n", __FUNCTION__, bwp_start_subcarrier, k, gNB->frame_parms.first_carrier_offset, nb_rb_pusch);
+ LOG_I(PHY, "In %s rxF addr %p p %d\n", __FUNCTION__, rxF, p);
+ LOG_I(PHY, "In %s ul_ch addr %p nushift %d\n", __FUNCTION__, ul_ch, nushift);
#endif
//if ((gNB->frame_parms.N_RB_UL&1)==0) {
@@ -181,9 +190,18 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_PUSCH
- printf("ch 0 %d\n",((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
- printf("pilot 0 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",rxF[0],rxF[1],dBc(rxF[0],rxF[1]),ch[0],ch[1],dBc(ch[0],ch[1]),pil[0],pil[1]);
- printf("data 0 : rxF - > (%d,%d) (%d)\n",rxF[2],rxF[3],dBc(rxF[2],rxF[3]));
+ LOG_I(PHY, "In %s ch 0 %d\n", __FUNCTION__, ((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1]));
+ LOG_I(PHY, "In %s pilot 0 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",
+ __FUNCTION__,
+ rxF[0],
+ rxF[1],
+ dBc(rxF[0],rxF[1]),
+ ch[0],
+ ch[1],
+ dBc(ch[0],ch[1]),
+ pil[0],
+ pil[1]);
+ LOG_I(PHY, "In %s data 0 : rxF - > (%d,%d) (%d)\n", __FUNCTION__, rxF[2], rxF[3], dBc(rxF[2],rxF[3]));
#endif
multadd_real_vector_complex_scalar(fl,
@@ -200,9 +218,23 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_PUSCH
- printf("pilot 1 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",rxF[0],rxF[1],dBc(rxF[0],rxF[1]),ch[0],ch[1],dBc(ch[0],ch[1]),pil[0],pil[1]);
- printf("data 1 : rxF - > (%d,%d) (%d)\n",rxF[2],rxF[3],dBc(rxF[2],rxF[3]));
+ LOG_I(PHY, "In %s pilot 1 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",
+ __FUNCTION__,
+ rxF[0],
+ rxF[1],
+ dBc(rxF[0],rxF[1]),
+ ch[0],
+ ch[1],
+ dBc(ch[0],ch[1]),
+ pil[0],
+ pil[1]);
+ LOG_I(PHY, "In %s data 1 : rxF - > (%d,%d) (%d)\n",
+ __FUNCTION__,
+ rxF[2],
+ rxF[3],
+ dBc(rxF[2],rxF[3]));
#endif
+
multadd_real_vector_complex_scalar(fml,
ch,
ul_ch,
@@ -216,9 +248,23 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15);
#ifdef DEBUG_PUSCH
- printf("pilot 2 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",rxF[0],rxF[1],dBc(rxF[0],rxF[1]),ch[0],ch[1],dBc(ch[0],ch[1]),pil[0],pil[1]);
- printf("data 2 : rxF - > (%d,%d) (%d)\n",rxF[2],rxF[3],dBc(rxF[2],rxF[3]));
+ LOG_I(PHY, "In %s pilot 2 : rxF - > (%d,%d) (%d) ch -> (%d,%d) (%d), pil -> (%d,%d) \n",
+ __FUNCTION__,
+ rxF[0],
+ rxF[1],
+ dBc(rxF[0],rxF[1]),
+ ch[0],
+ ch[1],
+ dBc(ch[0],ch[1]),
+ pil[0],
+ pil[1]);
+ LOG_I(PHY, "In %s data 2 : rxF - > (%d,%d) (%d)\n",
+ __FUNCTION__,
+ rxF[2],
+ rxF[3],
+ dBc(rxF[2],rxF[3]));
#endif
+
multadd_real_vector_complex_scalar(fmm,
ch,
ul_ch,
diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c
index 5d62f9dbb9..5a4b1adbb8 100644
--- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c
+++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c
@@ -40,9 +40,9 @@
#include "PHY/defs_gNB.h"
/*Table 7.4.1.1.2-1/2 from 38.211 */
-int wf1[8][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,1}};
+int wf1[8][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1}};
int wt1[8][2] = {{1,1},{1,1},{1,1},{1,1},{1,-1},{1,-1},{1,-1},{1,-1}};
-int wf2[12][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,1},{1,1},{1,-1},{1,1},{1,1}};
+int wf2[12][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1}};
int wt2[12][2] = {{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,-1},{1,-1},{1,-1},{1,-1},{1,-1},{1,-1}};
// complex conjugate of mod table
diff --git a/openair1/PHY/NR_REFSIG/scrambling_luts.c b/openair1/PHY/NR_REFSIG/scrambling_luts.c
index 3509291e42..2a37a12539 100644
--- a/openair1/PHY/NR_REFSIG/scrambling_luts.c
+++ b/openair1/PHY/NR_REFSIG/scrambling_luts.c
@@ -51,7 +51,7 @@ void init_byte2m64(void) {
((int16_t*)&byte2m64_re[s])[0],((int16_t*)&byte2m64_im[s])[0],
((int16_t*)&byte2m64_re[s])[1],((int16_t*)&byte2m64_im[s])[1],
((int16_t*)&byte2m64_re[s])[2],((int16_t*)&byte2m64_im[s])[2],
- ((int16_t*)&byte2m64_re[s])[3],((int16_t*)&byte2m64_im[s])[3]);
+ ((int16_t*)&byte2m64_re[s])[3],((int16_t*)&byte2m64_im[s])[3]);
}
}
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
index e92ebadd08..088f6393de 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
@@ -148,19 +148,18 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
uint16_t n_dmrs;
if (rel15->dmrsConfigType==NFAPI_NR_DMRS_TYPE1) {
nb_re_dmrs = 6*rel15->numDmrsCdmGrpsNoData;
- n_dmrs = ((rel15->rbSize+rel15->rbStart)*6)<<1;
}
else {
nb_re_dmrs = 4*rel15->numDmrsCdmGrpsNoData;
- n_dmrs = ((rel15->rbSize+rel15->rbStart)*4)<<1;
}
+ n_dmrs = (rel15->rbSize+rel15->rbStart)*nb_re_dmrs;
uint16_t dmrs_symbol_map = rel15->dlDmrsSymbPos;//single DMRS: 010000100 Double DMRS 110001100
uint8_t dmrs_len = get_num_dmrs(rel15->dlDmrsSymbPos);
uint16_t nb_re = ((12*rel15->NrOfSymbols)-nb_re_dmrs*dmrs_len-xOverhead)*rel15->rbSize*rel15->nrOfLayers;
uint8_t Qm = rel15->qamModOrder[0];
uint32_t encoded_length = nb_re*Qm;
- int16_t mod_dmrs[14][n_dmrs] __attribute__ ((aligned(16)));
+ int16_t mod_dmrs[14][n_dmrs<<1] __attribute__ ((aligned(16)));
/* PTRS */
uint16_t beta_ptrs = 1;
@@ -269,10 +268,10 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
/// DMRS QPSK modulation
for (int l=rel15->StartSymbolIndex; lStartSymbolIndex+rel15->NrOfSymbols; l++) {
if (rel15->dlDmrsSymbPos & (1 << l)) {
- nr_modulation(pdsch_dmrs[l][0], n_dmrs, DMRS_MOD_ORDER, mod_dmrs[l]); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
+ nr_modulation(pdsch_dmrs[l][0], n_dmrs*2, DMRS_MOD_ORDER, mod_dmrs[l]); // currently only codeword 0 is modulated. Qm = 2 as DMRS is QPSK modulated
#ifdef DEBUG_DLSCH
- printf("DMRS modulation (symbol %d, %d symbols, type %d):\n", l, n_dmrs>>1, dmrs_Type);
+ printf("DMRS modulation (symbol %d, %d symbols, type %d):\n", l, n_dmrs, dmrs_Type);
for (int i=0; i>4; i++) {
for (int j=0; j<8; j++) {
printf("%d %d\t", mod_dmrs[l][((i<<3)+j)<<1], mod_dmrs[l][(((i<<3)+j)<<1)+1]);
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
index b8cd71d846..f25aef8813 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
@@ -16,10 +16,10 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH)
{
#if defined(__x86_64__) || defined(__i386__)
- __m128i idft_in128[1][1200], idft_out128[1][1200];
+ __m128i idft_in128[1][3240], idft_out128[1][3240];
__m128i norm128;
#elif defined(__arm__)
- int16x8_t idft_in128[1][1200], idft_out128[1][1200];
+ int16x8_t idft_in128[1][3240], idft_out128[1][3240];
int16x8_t norm128;
#endif
int16_t *idft_in0 = (int16_t*)idft_in128[0], *idft_out0 = (int16_t*)idft_out128[0];
@@ -28,20 +28,19 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH)
LOG_T(PHY,"Doing lte_idft for Msc_PUSCH %d\n",Msc_PUSCH);
- // conjugate input
- for (i = 0; i < (Msc_PUSCH>>2); i++) {
+ if ((Msc_PUSCH % 1536) > 0) {
+ // conjugate input
+ for (i = 0; i < (Msc_PUSCH>>2); i++) {
#if defined(__x86_64__)||defined(__i386__)
- *&(((__m128i*)z)[i]) = _mm_sign_epi16(*&(((__m128i*)z)[i]), *(__m128i*)&conjugate2[0]);
+ *&(((__m128i*)z)[i]) = _mm_sign_epi16(*&(((__m128i*)z)[i]), *(__m128i*)&conjugate2[0]);
#elif defined(__arm__)
- *&(((int16x8_t*)z)[i]) = vmulq_s16(*&(((int16x8_t*)z)[i]), *(int16x8_t*)&conjugate2[0]);
+ *&(((int16x8_t*)z)[i]) = vmulq_s16(*&(((int16x8_t*)z)[i]), *(int16x8_t*)&conjugate2[0]);
#endif
+ }
+ for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4)
+ ((uint32_t*)idft_in0)[ip+0] = z[i];
}
- for (i=0,ip=0; i 0) {
+ for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4)
+ z[i] = ((uint32_t*)idft_out0)[ip];
-
- for (i = 0, ip = 0; i < Msc_PUSCH; i++, ip+=4) {
- z[i] = ((int32_t*)idft_out0)[ip];
- }
-
- // conjugate output
- for (i = 0; i < (Msc_PUSCH>>2); i++) {
+ // conjugate output
+ for (i = 0; i < (Msc_PUSCH>>2); i++) {
#if defined(__x86_64__) || defined(__i386__)
- ((__m128i*)z)[i] = _mm_sign_epi16(((__m128i*)z)[i], *(__m128i*)&conjugate2[0]);
+ ((__m128i*)z)[i] = _mm_sign_epi16(((__m128i*)z)[i], *(__m128i*)&conjugate2[0]);
#elif defined(__arm__)
- *&(((int16x8_t*)z)[i]) = vmulq_s16(*&(((int16x8_t*)z)[i]), *(int16x8_t*)&conjugate2[0]);
+ *&(((int16x8_t*)z)[i]) = vmulq_s16(*&(((int16x8_t*)z)[i]), *(int16x8_t*)&conjugate2[0]);
#endif
+ }
}
#if defined(__x86_64__) || defined(__i386__)
@@ -222,6 +298,7 @@ void nr_idft(int32_t *z, uint32_t Msc_PUSCH)
}
+
void nr_ulsch_extract_rbs_single(int32_t **rxdataF,
NR_gNB_PUSCH *pusch_vars,
unsigned char symbol,
diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
index bfec64820b..abc944bc00 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
@@ -158,7 +158,6 @@ void nr_pdcch_demapping_deinterleaving(uint32_t *llr,
if ((reg % reg_bundle_size_L) == 0) r++;
}
-
// Get cce_list indices by reg_idx in ascending order
int f_bundle_j_list_id = 0;
int f_bundle_j_list_ord[NR_MAX_PDCCH_AGG_LEVEL] = {};
@@ -175,7 +174,6 @@ void nr_pdcch_demapping_deinterleaving(uint32_t *llr,
}
}
-
for(int reg=0; reg<((coreset_nbr_rb*coreset_time_dur)); reg++) {
f_reg = (f_bundle_j_list_ord[reg/6]*reg_bundle_size_L)+(reg%reg_bundle_size_L);
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
index b3f3888c9c..35c4a6e8cb 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
@@ -975,8 +975,8 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
//rho[aarx][nb_aatx*nb_aatx] = [cov(H_aarx_0,H_aarx_0) cov(H_aarx_0,H_aarx_1)
// cov(H_aarx_1,H_aarx_0) cov(H_aarx_1,H_aarx_1)], aarx=0,...,nb_antennas_rx-1
- int avg_rho_re[frame_parms->nb_antennas_rx][nb_aatx];
- int avg_rho_im[frame_parms->nb_antennas_rx][nb_aatx];
+ int avg_rho_re[frame_parms->nb_antennas_rx][nb_aatx*nb_aatx];
+ int avg_rho_im[frame_parms->nb_antennas_rx][nb_aatx*nb_aatx];
for (aarx=0; aarxnb_antennas_rx; aarx++) {
@@ -1085,7 +1085,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext,
//measurements->rx_correlation[0][0][aarx] = signal_energy(&rho[aarx][aatx*nb_aatx+atx][symbol*nb_rb*12],rb*12);
avg_rho_re[aarx][aatx*nb_aatx+atx] = 16*avg_rho_re[aarx][aatx*nb_aatx+atx]/(nb_rb*12);
avg_rho_im[aarx][aatx*nb_aatx+atx] = 16*avg_rho_im[aarx][aatx*nb_aatx+atx]/(nb_rb*12);
- printf("rho[rx]%d tx%d tx%d = Re: %d Im: %d\n",aarx, aatx,atx, avg_rho_re[aatx*nb_aatx+atx], avg_rho_im[aatx*nb_aatx+atx]);
+ printf("rho[rx]%d tx%d tx%d = Re: %d Im: %d\n",aarx, aatx,atx, avg_rho_re[aarx][aatx*nb_aatx+atx], avg_rho_im[aarx][aatx*nb_aatx+atx]);
}
}
}
@@ -2247,7 +2247,7 @@ unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF,
}
void nr_dlsch_detection_mrc(int **rxdataF_comp,
- int **rho,
+ int ***rho,
int **dl_ch_mag,
int **dl_ch_magb,
short n_tx,
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
index 2723ac0b05..1e7e10def7 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
@@ -891,7 +891,7 @@ void nr_dlsch_channel_level_median(int **dl_ch_estimates_ext,
int start_point);
void nr_dlsch_detection_mrc(int **rxdataF_comp,
- int **rho,
+ int ***rho,
int **dl_ch_mag,
int **dl_ch_magb,
short n_tx,
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
index 464bcfcfba..aa32ecc8c9 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
@@ -105,6 +105,8 @@ typedef struct {
uint8_t O_ACK;
/// Index of current HARQ round for this ULSCH
uint8_t round;
+ /// Last Ndi for this harq process
+ uint8_t ndi;
/// pointer to pdu from MAC interface (TS 36.212 V15.4.0, Sec 5.1 p. 8)
unsigned char *a;
/// Pointer to the payload + CRC
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c
index 7cf64b28bb..76fc5f298f 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ue_rf_helpers.c
@@ -78,13 +78,15 @@ void nr_rf_card_config(openair0_config_t *openair0_cfg,
openair0_cfg->autocal[i] = 1;
- LOG_I(PHY, "HW: Configuring channel %d (rf_chain %d): setting tx_gain %f, rx_gain %f, tx_freq %f Hz, rx_freq %f Hz\n",
- i,
- rf_chain,
- openair0_cfg->tx_gain[i],
- openair0_cfg->rx_gain[i],
- openair0_cfg->tx_freq[i],
- openair0_cfg->rx_freq[i]);
+ if (i < openair0_cfg->rx_num_channels) {
+ LOG_I(PHY, "HW: Configuring channel %d (rf_chain %d): setting tx_gain %f, rx_gain %f, tx_freq %f Hz, rx_freq %f Hz\n",
+ i,
+ rf_chain,
+ openair0_cfg->tx_gain[i],
+ openair0_cfg->rx_gain[i],
+ openair0_cfg->tx_freq[i],
+ openair0_cfg->rx_freq[i]);
+ }
}
}
\ No newline at end of file
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
index d9bea8a3ac..1a39def26b 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c
@@ -202,7 +202,6 @@ NR_UE_ULSCH_t *new_nr_ue_ulsch(uint16_t N_RB_UL,
for (i=0; iharq_processes[i]->round=0;
}
-
return(ulsch);
}
}
@@ -257,7 +256,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
Ilbrm = 0;
Tbslbrm = 950984; //max tbs
Coderate = 0.0;
- harq_process->round = nr_rv_round_map_ue[harq_process->pusch_pdu.pusch_data.rv_index];
///////////
/////////////////////////////////////////////////////////////////////////////////////////
@@ -267,8 +265,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
LOG_D(PHY,"ulsch coding nb_rb %d, Nl = %d\n", nb_rb, harq_process->pusch_pdu.nrOfLayers);
LOG_D(PHY,"ulsch coding A %d G %d mod_order %d\n", A,G, mod_order);
- // if (harq_process->Ndi == 1) { // this is a new packet
- if (harq_process->round == 0) { // this is a new packet
+ if (harq_process->ndi != harq_process->pusch_pdu.pusch_data.new_data_indicator) { // this is a new packet
#ifdef DEBUG_ULSCH_CODING
printf("encoding thinks this is a new packet \n");
#endif
@@ -415,7 +412,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
///////////
///////////////////////////////////////////////////////////////////////////////
-
+ harq_process->ndi = harq_process->pusch_pdu.pusch_data.new_data_indicator;
}
F = harq_process->F;
Kr = harq_process->K;
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
index 208901f289..3d8c975a5c 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
@@ -496,13 +496,19 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
int symb_offset = (slot%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot;
for(ap = 0; ap < Nl; ap++) {
for (int s=0;s (%d.%d)\n",
- s,s+symb_offset,frame_parms->symbol_rotation[2*(s+symb_offset)],frame_parms->symbol_rotation[1+(2*(s+symb_offset))]);
- rotate_cpx_vector((int16_t *)&txdataF[ap][frame_parms->ofdm_symbol_size*s],
- &frame_parms->symbol_rotation[2*(s+symb_offset)],
- (int16_t *)&txdataF[ap][frame_parms->ofdm_symbol_size*s],
- frame_parms->ofdm_symbol_size,
- 15);
+
+ LOG_D(PHY,"In %s: rotating txdataF symbol %d (%d) => (%d.%d)\n",
+ __FUNCTION__,
+ s,
+ s + symb_offset,
+ frame_parms->symbol_rotation[1][2 * (s + symb_offset)],
+ frame_parms->symbol_rotation[1][1 + (2 * (s + symb_offset))]);
+
+ rotate_cpx_vector((int16_t *)&txdataF[ap][frame_parms->ofdm_symbol_size * s],
+ &frame_parms->symbol_rotation[1][2 * (s + symb_offset)],
+ (int16_t *)&txdataF[ap][frame_parms->ofdm_symbol_size * s],
+ frame_parms->ofdm_symbol_size,
+ 15);
}
}
diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c
index f6cb93ed03..b45c1abf0b 100644
--- a/openair1/PHY/TOOLS/nr_phy_scope.c
+++ b/openair1/PHY/TOOLS/nr_phy_scope.c
@@ -225,6 +225,8 @@ static void oai_xygraph(OAIgraph_t *graph, float *x, float *y, int len, int laye
}
static void genericWaterFall (OAIgraph_t *graph, scopeSample_t *values, const int datasize, const int divisions, const char *label) {
+ if ( values == NULL )
+ return;
fl_winset(FL_ObjWin(graph->graph));
const int samplesPerPixel=datasize/graph->w;
int displayPart=graph->waterFallh-ScaleZone;
@@ -280,30 +282,6 @@ static void genericWaterFall (OAIgraph_t *graph, scopeSample_t *values, const in
graph->iteration++;
}
-static void genericLogPowerPerAntena(OAIgraph_t *graph, const int nb_ant, const scopeSample_t **data, const int len) {
- float *values, *time;
- oai_xygraph_getbuff(graph, &time, &values, len, 0);
-
- for (int ant=0; antmodule_id;
@@ -169,6 +175,7 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
case NFAPI_NR_DL_TTI_SSB_PDU_TYPE:
gNB->pbch_configured=1;
+ if(NFAPI_MODE != NFAPI_MODE_VNF)
handle_nr_nfapi_ssb_pdu(gNB,frame,slot,
dl_tti_pdu);
@@ -176,7 +183,7 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE:
AssertFatal(pdcch_received == 0, "pdcch_received is not 0, we can only handle one PDCCH PDU per slot\n");
- LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE for %d.%d\n",frame,slot,DL_req->SFN,DL_req->Slot);
+ if(NFAPI_MODE != NFAPI_MODE_VNF)
handle_nfapi_nr_pdcch_pdu(gNB,
frame, slot,
&dl_tti_pdu->pdcch_pdu);
@@ -193,33 +200,61 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
AssertFatal(TX_req->pdu_list[pduIndex].num_TLV == 1, "TX_req->pdu_list[%d].num_TLV %d != 1\n",
pduIndex,TX_req->pdu_list[pduIndex].num_TLV);
uint8_t *sdu = (uint8_t *)TX_req->pdu_list[pduIndex].TLVs[0].value.direct;
+ if(NFAPI_MODE != NFAPI_MODE_VNF)
handle_nr_nfapi_pdsch_pdu(gNB,frame,slot,&dl_tti_pdu->pdsch_pdu, sdu);
}
}
}
// if (UL_tti_req!=NULL) memcpy(&gNB->UL_tti_req,UL_tti_req,sizeof(nfapi_nr_ul_tti_request_t));
+ if(NFAPI_MODE != NFAPI_MODE_VNF)
+ for (int i=0;iul_dci_pdu_list[i]);
+ }
+
+ if(NFAPI_MODE != NFAPI_MODE_VNF)
+ for (int i = 0; i < number_ul_tti_pdu; i++) {
+ switch (UL_tti_req->pdus_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);
+ nr_fill_ulsch(gNB,UL_tti_req->SFN, UL_tti_req->Slot, &UL_tti_req->pdus_list[i].pusch_pdu);
+ break;
+ case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE:
+ LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PUCCH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot);
+ nr_fill_pucch(gNB,UL_tti_req->SFN, UL_tti_req->Slot, &UL_tti_req->pdus_list[i].pucch_pdu);
+ break;
+ case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE:
+ LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PRACH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot);
+ nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[i].prach_pdu;
+ nr_fill_prach(gNB, UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu);
+ if (gNB->RU_list[0]->if_south == LOCAL_RF) nr_fill_prach_ru(gNB->RU_list[0], UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu);
+ break;
+ }
+ }
+
+ if(NFAPI_MODE != NFAPI_MONOLITHIC && number_ul_tti_pdu>0)
+ {
+ oai_nfapi_ul_tti_req(UL_tti_req);
+ }
- for (int i=0;iul_dci_pdu_list[i]);
+ if (NFAPI_MODE != NFAPI_MONOLITHIC && Sched_INFO->UL_dci_req->numPdus!=0)
+ {
+ oai_nfapi_ul_dci_req(Sched_INFO->UL_dci_req);
+ }
+
+ if (NFAPI_MODE != NFAPI_MONOLITHIC)
+ {
+ if(Sched_INFO->DL_req->dl_tti_request_body.nPDUs>0)
+ {
+ Sched_INFO->DL_req->SFN = frame;
+ Sched_INFO->DL_req->Slot = slot;
+ oai_nfapi_dl_tti_req(Sched_INFO->DL_req);
+ }
+ if (Sched_INFO->TX_req->Number_of_PDUs > 0)
+ {
+ oai_nfapi_tx_data_req(Sched_INFO->TX_req);
+ }
+
}
- for (int i = 0; i < number_ul_tti_pdu; i++) {
- switch (UL_tti_req->pdus_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);
- nr_fill_ulsch(gNB,UL_tti_req->SFN, UL_tti_req->Slot, &UL_tti_req->pdus_list[i].pusch_pdu);
- break;
- case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE:
- LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PUCCH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot);
- nr_fill_pucch(gNB,UL_tti_req->SFN, UL_tti_req->Slot, &UL_tti_req->pdus_list[i].pucch_pdu);
- break;
- case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE:
- LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PRACH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot);
- nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[i].prach_pdu;
- nr_fill_prach(gNB, UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu);
- if (gNB->RU_list[0]->if_south == LOCAL_RF) nr_fill_prach_ru(gNB->RU_list[0], UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu);
- break;
- }
- }
-}
+}
\ No newline at end of file
diff --git a/openair1/SCHED_NR/fapi_nr_l1.h b/openair1/SCHED_NR/fapi_nr_l1.h
index d66d6e7b24..ed90b9870b 100644
--- a/openair1/SCHED_NR/fapi_nr_l1.h
+++ b/openair1/SCHED_NR/fapi_nr_l1.h
@@ -36,6 +36,11 @@
#include "nfapi_nr_interface.h"
#include "nfapi_nr_interface_scf.h"
+// added
+void handle_nr_nfapi_ssb_pdu(PHY_VARS_gNB *gNB,
+ int frame,int slot,
+ nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu);
+
void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO);
void handle_nfapi_nr_pdcch_pdu(PHY_VARS_gNB *gNB,
@@ -48,3 +53,8 @@ void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int UE_id, uint8_t harq_pid, uint8_t crc_flag);
+//added
+
+void handle_nfapi_nr_ul_dci_pdu(PHY_VARS_gNB *gNB,
+ int frame, int slot,
+ nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu);
diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
index 3aa69c5326..6efbe35b1e 100644
--- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c
+++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
@@ -161,7 +161,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
}
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,1);
- if (nfapi_mode == 0 || nfapi_mode == 1) {
+ if (NFAPI_MODE == NFAPI_MONOLITHIC || NFAPI_MODE == NFAPI_MODE_PNF) {
if ((!(frame%ssb_frame_periodicity))) // generate SSB only for given frames according to SSB periodicity
nr_common_signal_procedures(gNB,frame, slot);
}
@@ -544,6 +544,9 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
}
void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
+ /* those variables to log T_GNB_PHY_PUCCH_PUSCH_IQ only when we try to decode */
+ int pucch_decode_done = 0;
+ int pusch_decode_done = 0;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,1);
LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d\n",frame_rx,slot_rx);
@@ -553,6 +556,11 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
gNB_I0_measurements(gNB);
+ // measure enegry in SS=10 L=4, nb_rb = 18, first_rb = 0 (corresponds to msg3)
+ int offset = 10*gNB->frame_parms.ofdm_symbol_size + gNB->frame_parms.first_carrier_offset;
+ int power_rxF = signal_energy_nodc(&gNB->common_vars.rxdataF[0][offset],12*18);
+ LOG_D(PHY,"frame %d, slot %d: UL signal energy %d\n",frame_rx,slot_rx,power_rxF);
+
for (int i=0;ipucch[i];
if (pucch) {
@@ -560,6 +568,8 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
(pucch->frame == frame_rx) &&
(pucch->slot == slot_rx) ) {
+ pucch_decode_done = 1;
+
nfapi_nr_pucch_pdu_t *pucch_pdu = &pucch->pucch_pdu;
uint16_t num_ucis;
switch (pucch_pdu->format_type) {
@@ -648,6 +658,8 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
}
#endif
+ pusch_decode_done = 1;
+
uint8_t symbol_start = ulsch_harq->ulsch_pdu.start_symbol_index;
uint8_t symbol_end = symbol_start + ulsch_harq->ulsch_pdu.nr_of_symbols;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RX_PUSCH,1);
@@ -675,5 +687,9 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
// figure out a better way to choose slot_rx, 19 is ok for a particular TDD configuration with 30kHz SCS
if ((frame_rx&127) == 0 && slot_rx==19) dump_pusch_stats(gNB);
+ if (pucch_decode_done || pusch_decode_done) {
+ T(T_GNB_PHY_PUCCH_PUSCH_IQ, T_INT(frame_rx), T_INT(slot_rx), T_BUFFER(&gNB->common_vars.rxdataF[0][0], gNB->frame_parms.symbols_per_slot * gNB->frame_parms.ofdm_symbol_size * 4));
+ }
+
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,0);
}
diff --git a/openair1/SCHED_NR_UE/harq_nr.c b/openair1/SCHED_NR_UE/harq_nr.c
index f3e5f91285..85f6d90bbe 100644
--- a/openair1/SCHED_NR_UE/harq_nr.c
+++ b/openair1/SCHED_NR_UE/harq_nr.c
@@ -295,7 +295,7 @@ harq_result_t uplink_harq_process(NR_UE_ULSCH_t *ulsch, int harq_pid, int ndi, u
/* 38.321 5.4.2.1 2> if the uplink grant was received on PDCCH for the C-RNTI and the HARQ buffer of the identified process is empty */
if ((ulsch->harq_processes[harq_pid]->first_tx == 1) && (rnti_type == _C_RNTI_)) { /* no transmission yet on this process so consider its harq buffer as empty */
- ulsch->harq_processes[harq_pid]->first_tx = 0;
+ ulsch->harq_processes[harq_pid]->first_tx = 0;
ulsch->harq_processes[harq_pid]->pusch_pdu.pusch_data.new_data_indicator = ndi; /* store first value of ndi */
ulsch->harq_processes[harq_pid]->round = 0;
ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
index 02ed0a1b55..33cf421b03 100644
--- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
@@ -132,6 +132,7 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
}
switch (pdu_type){
+ case FAPI_NR_RX_PDU_TYPE_SIB:
case FAPI_NR_RX_PDU_TYPE_DLSCH:
case FAPI_NR_RX_PDU_TYPE_RAR:
harq_pid = dlsch0->current_harq_pid;
@@ -238,33 +239,15 @@ void ue_ta_procedures(PHY_VARS_NR_UE *ue, int slot_tx, int frame_tx){
int factor_mu = 1 << numerology;
uint16_t bw_scaling = get_bw_scaling(bwp_ul_NB_RB);
- LOG_D(PHY, "In %s: applying timing advance -- frame %d -- slot %d -- UE_mode %d\n", __FUNCTION__, frame_tx, slot_tx, ue->UE_mode[gNB_id]);
+ ue->timing_advance += (ul_time_alignment->ta_command - 31) * bw_scaling / factor_mu;
- if (ue->UE_mode[gNB_id] == RA_RESPONSE){
-
- ue->timing_advance = ul_time_alignment->ta_command * bw_scaling / factor_mu;
-
- LOG_D(PHY, "In %s: [UE %d] [%d.%d] Received (RAR) timing advance command %d new value is %u \n",
- __FUNCTION__,
- ue->Mod_id,
- frame_tx,
- slot_tx,
- ul_time_alignment->ta_command,
- ue->timing_advance);
-
- } else if (ue->UE_mode[gNB_id] == PUSCH){
-
- ue->timing_advance += (ul_time_alignment->ta_command - 31) * bw_scaling / factor_mu;
-
- LOG_D(PHY, "In %s: [UE %d] [%d.%d] Got timing advance command %u from MAC, new value is %d\n",
- __FUNCTION__,
- ue->Mod_id,
- frame_tx,
- slot_tx,
- ul_time_alignment->ta_command,
- ue->timing_advance);
-
- }
+ LOG_I(PHY, "In %s: [UE %d] [%d.%d] Got timing advance command %u from MAC, new value is %d\n",
+ __FUNCTION__,
+ ue->Mod_id,
+ frame_tx,
+ slot_tx,
+ ul_time_alignment->ta_command,
+ ue->timing_advance);
ul_time_alignment->ta_frame = -1;
ul_time_alignment->ta_slot = -1;
@@ -1188,7 +1171,8 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_DLSCH, eNB_id, ue, dlsch0, number_pdus);
break;
case SI_PDSCH:
- rx_ind.rx_indication_body[0].pdu_type = FAPI_NR_RX_PDU_TYPE_SIB;
+ nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, eNB_id);
+ nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SIB, eNB_id, ue, dlsch0, number_pdus);
break;
default:
break;
diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c
index 061866b12c..00983553d8 100644
--- a/openair1/SIMULATION/NR_PHY/dlschsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlschsim.c
@@ -56,7 +56,7 @@ UE_nr_rxtx_proc_t proc;
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
double cpuf;
-uint8_t nfapi_mode = 0;
+//uint8_t nfapi_mode = 0;
uint16_t NB_UE_INST = 1;
uint8_t const nr_rv_round_map[4] = {0, 2, 1, 3};
diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c
index eba7c868e0..423f6bfa9d 100644
--- a/openair1/SIMULATION/NR_PHY/dlsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlsim.c
@@ -79,9 +79,9 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
double cpuf;
-int sf_ahead=4 ;
-int sl_ahead=0;
-uint8_t nfapi_mode = 0;
+uint16_t sf_ahead=4 ;
+uint16_t sl_ahead=0;
+//uint8_t nfapi_mode = 0;
uint64_t downlink_frequency[MAX_NUM_CCs][4];
// dummy functions
@@ -97,6 +97,21 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id,
return 0;
}
+void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index)
+{
+ return;
+}
+
+int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP,
+ const int CC_id,
+ const uint8_t gNB_id,
+ const frame_t frameP,
+ const rb_id_t Srb_id,
+ uint8_t *buffer_pP)
+{
+ return 0;
+}
+
void
rrc_data_ind(
const protocol_ctxt_t *const ctxt_pP,
@@ -151,6 +166,12 @@ nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
return 0;
}
+int nr_derive_key(int alg_type, uint8_t alg_id,
+ const uint8_t key[32], uint8_t **out)
+{
+ return 0;
+}
+
void config_common(int Mod_idP,
int pdsch_AntennaPorts,
int pusch_AntennaPorts,
@@ -173,9 +194,12 @@ int is_x2ap_enabled(void)
return 0;
}
-int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len) {
- return 0;
-}
+//nFAPI P7 dummy functions
+
+int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) { return(0); }
+int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req){ return(0); }
+int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req){ return(0); }
+int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req){ return(0); }
// needed for some functions
openair0_config_t openair0_cfg[MAX_CARDS];
@@ -236,7 +260,10 @@ int main(int argc, char **argv)
int i,aa;//,l;
double sigma2, sigma2_dB=10, SNR, snr0=-2.0, snr1=2.0;
uint8_t snr1set=0;
- float roundStats[50];
+ double roundStats[500] = {0};
+ double blerStats[500] = {0};
+ double berStats[500] = {0};
+ double snrStats[500] = {0};
float effRate;
//float psnr;
float eff_tp_check = 0.7;
@@ -1122,7 +1149,9 @@ int main(int argc, char **argv)
if (UE_harq_process->harq_ack.ack==1) effRate += ((float)TBS)/round;
} // noise trials
+ blerStats[snrRun] = (float) n_errors / (float) n_trials;
roundStats[snrRun]/=((float)n_trials);
+ berStats[snrRun] = (double)errors_scrambling/available_bits/n_trials;
effRate /= n_trials;
printf("*****************************************\n");
printf("SNR %f, (false positive %f)\n", SNR,
@@ -1130,7 +1159,7 @@ int main(int argc, char **argv)
printf("*****************************************\n");
printf("\n");
dump_pdsch_stats(gNB);
- printf("SNR %f : n_errors (negative CRC) = %d/%d, Avg round %.2f, Channel BER %e, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %u bits/slot\n", SNR, n_errors, n_trials,roundStats[snrRun],(double)errors_scrambling/available_bits/n_trials,effRate,effRate/TBS*100,TBS);
+ printf("SNR %f : n_errors (negative CRC) = %d/%d, Avg round %.2f, Channel BER %e, BLER %.2f, Eff Rate %.4f bits/slot, Eff Throughput %.2f, TBS %u bits/slot\n", SNR, n_errors, n_trials,roundStats[snrRun],berStats[snrRun],blerStats[snrRun],effRate,effRate/TBS*100,TBS);
printf("\n");
if (print_perf==1) {
@@ -1195,15 +1224,19 @@ int main(int argc, char **argv)
break;
}
- //if ((float)n_errors/(float)n_trials <= target_error_rate) {
if (effRate > (eff_tp_check*TBS)) {
printf("PDSCH test OK\n");
break;
}
+ snrStats[snrRun] = SNR;
snrRun++;
} // NSR
+ LOG_M("dlsimStats.m","SNR",snrStats,snrRun,1,7);
+ LOG_MM("dlsimStats.m","BLER",blerStats,snrRun,1,7);
+ LOG_MM("dlsimStats.m","BER",berStats,snrRun,1,7);
+ LOG_MM("dlsimStats.m","rounds",roundStats,snrRun,1,7);
/*if (n_trials>1) {
printf("HARQ stats:\nSNR\tRounds\n");
psnr = snr0;
diff --git a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c
index 2673ca0524..32b6b10412 100644
--- a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c
+++ b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c
@@ -2,9 +2,16 @@ int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { re
int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { return(0); }
int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { return(0); }
//int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); }
-//int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req) { return(0); }
+int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) { return(0); }
+int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req){ return(0); }
+int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req){ return(0); }
+int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req){ return(0); }
int32_t get_uldl_offset(int nr_bandP) { return(0); }
NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {return(NULL);}
+nfapi_mode_t nfapi_mod;
+nfapi_mode_t nfapi_getmode(void) {
+ return nfapi_mod;
+}
int dummy_nr_ue_dl_indication(nr_downlink_indication_t *dl_info) { return(0); }
int dummy_nr_ue_ul_indication(nr_uplink_indication_t *ul_info) { return(0); }
void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind,
diff --git a/openair1/SIMULATION/NR_PHY/nr_dummy_functions_prach.c b/openair1/SIMULATION/NR_PHY/nr_dummy_functions_prach.c
index 57b540f699..a930c96a75 100644
--- a/openair1/SIMULATION/NR_PHY/nr_dummy_functions_prach.c
+++ b/openair1/SIMULATION/NR_PHY/nr_dummy_functions_prach.c
@@ -2,7 +2,10 @@ int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { re
int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { return(0); }
int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { return(0); }
int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); }
-//int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req) { return(0); }
+int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) { return(0); }
+ int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req){ return(0); }
+ int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req){ return(0); }
+ int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req){ return(0); }
int32_t get_uldl_offset(int nr_bandP) { return(0); }
NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {return(NULL);}
int dummy_nr_ue_dl_indication(nr_downlink_indication_t *dl_info) { return(0); }
diff --git a/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h b/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h
index a7150fb2f9..906636d56f 100644
--- a/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h
+++ b/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h
@@ -55,19 +55,6 @@ signed char quantize(double D, double x, unsigned char B) {
return ((char) qxd);
}
-
-int8_t
-mac_rrc_data_req_ue(
- const module_id_t Mod_idP,
- const int CC_id,
- const frame_t frameP,
- const rb_id_t Srb_id,
- const uint8_t Nb_tb,
- uint8_t *const buffer_pP,
- const mac_enb_index_t eNB_indexP,
- const uint8_t mbsfn_sync_area
- ) { return(0);}
-
int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind) {return(0);}
//NR_IF_Module_t *NR_IF_Module_init(int Mod_id){return(NULL);}
int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); }
@@ -239,6 +226,7 @@ ngap_gNB_config_t ngap_config;
uint32_t ngap_generate_gNB_id(void) {return 0;}
void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port) { return;}
void configure_nfapi_vnf(char *vnf_addr, int vnf_p5_port) { return;}
-
+void configure_nr_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port) { return;}
+void configure_nr_nfapi_vnf(char *vnf_addr, int vnf_p5_port) { return;}
#endif
diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c
index 2ff89364d3..7b845c5bd3 100644
--- a/openair1/SIMULATION/NR_PHY/pbchsim.c
+++ b/openair1/SIMULATION/NR_PHY/pbchsim.c
@@ -56,7 +56,7 @@ RAN_CONTEXT_t RC;
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
double cpuf;
-uint8_t nfapi_mode = 0;
+//uint8_t nfapi_mode = 0;
uint16_t NB_UE_INST = 1;
// needed for some functions
@@ -111,7 +111,7 @@ void nr_phy_config_request_sim_pbchsim(PHY_VARS_gNB *gNB,
nr_init_frame_parms(gNB_config, fp);
- init_symbol_rotation(fp,fp->dl_CarrierFreq);
+ init_symbol_rotation(fp);
gNB->configured = 1;
LOG_I(PHY,"gNB configured\n");
@@ -540,7 +540,7 @@ int main(int argc, char **argv)
if (input_fd==NULL) {
gNB->pbch_configured = 1;
- gNB->ssb_pdu.ssb_pdu_rel15.bchPayload = 0;
+ gNB->ssb_pdu.ssb_pdu_rel15.bchPayload = 0x55dd33;
for (int slot=0;slotslots_per_frame;slot++) {
for (aa=0; aaframe_parms.nb_antennas_tx; aa++)
@@ -718,9 +718,9 @@ int main(int argc, char **argv)
payload_ret = (UE->pbch_vars[0]->xtra_byte == gNB_xtra_byte);
for (i=0;i<3;i++){
- payload_ret += (UE->pbch_vars[0]->decoded_output[i] == (gNB->ssb_pdu.ssb_pdu_rel15.bchPayload>>(8*i)));
+ payload_ret += (UE->pbch_vars[0]->decoded_output[i] == ((gNB->ssb_pdu.ssb_pdu_rel15.bchPayload>>(8*i)) & 0xff));
}
- //printf("xtra byte gNB: 0x%02x UE: 0x%02x\n",gNB_xtra_byte, UE->rx_ind.rx_indication_body->mib_pdu.additional_bits);
+ //printf("xtra byte gNB: 0x%02x UE: 0x%02x\n",gNB_xtra_byte, UE->pbch_vars[0]->xtra_byte);
//printf("ret %d\n", payload_ret);
if (payload_ret!=4)
n_errors_payload++;
diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c
index 941a06128f..8bd54ec345 100644
--- a/openair1/SIMULATION/NR_PHY/prachsim.c
+++ b/openair1/SIMULATION/NR_PHY/prachsim.c
@@ -47,6 +47,7 @@
#include "OCG_vars.h"
#include
#include
+//#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c"
#define NR_PRACH_DEBUG 1
@@ -62,14 +63,18 @@ RU_t *ru;
double cpuf;
extern uint16_t prach_root_sequence_map0_3[838];
openair0_config_t openair0_cfg[MAX_CARDS];
-uint8_t nfapi_mode=0;
-int sl_ahead = 0;
+//uint8_t nfapi_mode=0;
+uint16_t sl_ahead = 0;
//void dump_nr_prach_config(NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe);
/* temporary dummy implem of get_softmodem_optmask, till basic simulators implemented as device */
uint64_t get_softmodem_optmask(void) {return 0;}
softmodem_params_t *get_softmodem_params(void) {return 0;}
+int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) { return(0); }
+int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req){ return(0); }
+int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req){ return(0); }
+int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req){ return(0); }
void
rrc_data_ind(
@@ -127,13 +132,30 @@ nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP(
int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, const int8_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) {return 0;}
+void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index)
+{
+ return;
+}
+
+int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP,
+ const int CC_id,
+ const uint8_t gNB_id,
+ const frame_t frameP,
+ const rb_id_t Srb_id,
+ uint8_t *buffer_pP)
+{
+ return 0;
+}
+
// Dummy function to avoid linking error at compilation of nr-prachsim
int is_x2ap_enabled(void)
{
return 0;
}
-int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len) {
+int nr_derive_key(int alg_type, uint8_t alg_id,
+ const uint8_t key[32], uint8_t **out)
+{
return 0;
}
diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c
index a96a62f656..8d79633a6f 100644
--- a/openair1/SIMULATION/NR_PHY/pucchsim.c
+++ b/openair1/SIMULATION/NR_PHY/pucchsim.c
@@ -53,7 +53,7 @@ openair0_config_t openair0_cfg[MAX_CARDS];
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
double cpuf;
-uint8_t nfapi_mode = 0;
+//uint8_t nfapi_mode = 0;
uint16_t NB_UE_INST = 1;
uint8_t const nr_rv_round_map[4] = {0, 2, 1, 3};
uint8_t const nr_rv_round_map_ue[4] = {0, 2, 1, 3};
diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c
index afebe4ed97..6f2af73a1d 100644
--- a/openair1/SIMULATION/NR_PHY/ulschsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulschsim.c
@@ -60,7 +60,7 @@ uint8_t const nr_rv_round_map[4] = {0, 2, 1, 3};
uint8_t const nr_rv_round_map_ue[4] = {0, 2, 1, 3};
double cpuf;
-uint8_t nfapi_mode = 0;
+//uint8_t nfapi_mode = 0;
uint16_t NB_UE_INST = 1;
// needed for some functions
diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c
index 51d75955d4..2b0f713f7f 100644
--- a/openair1/SIMULATION/NR_PHY/ulsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulsim.c
@@ -75,10 +75,11 @@ PHY_VARS_NR_UE *UE;
RAN_CONTEXT_t RC;
int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
-int sf_ahead=4 ;
-int sl_ahead=0;
+uint16_t sf_ahead=4 ;
+int slot_ahead=6 ;
+uint16_t sl_ahead=0;
double cpuf;
-uint8_t nfapi_mode = 0;
+//uint8_t nfapi_mode = 0;
uint64_t downlink_frequency[MAX_NUM_CCs][4];
@@ -154,7 +155,31 @@ int is_x2ap_enabled(void)
return 0;
}
-int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len) {
+void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index)
+{
+ return;
+}
+
+int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP,
+ const int CC_id,
+ const uint8_t gNB_id,
+ const frame_t frameP,
+ const rb_id_t Srb_id,
+ uint8_t *buffer_pP)
+{
+ return 0;
+}
+
+//nFAPI P7 dummy functions
+
+int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) { return(0); }
+int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req){ return(0); }
+int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req){ return(0); }
+int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req){ return(0); }
+
+int nr_derive_key(int alg_type, uint8_t alg_id,
+ const uint8_t key[32], uint8_t **out)
+{
return 0;
}
diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/dummy_functions.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/dummy_functions.c
index cc8c62a36d..4d17fe723c 100644
--- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/dummy_functions.c
+++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/dummy_functions.c
@@ -142,6 +142,10 @@ void thread_top_init(char *thread_name,
int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { return(0);}
int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { return(0); }
+int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) { return(0); }
+int oai_nfapi_tx_data_req(nfapi_nr_tx_data_request_t *tx_data_req){ return(0); }
+int oai_nfapi_ul_dci_req(nfapi_nr_ul_dci_request_t *ul_dci_req){ return(0); }
+int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req){ return(0); }
int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { return(0); }
diff --git a/openair2/COMMON/s1ap_messages_types.h b/openair2/COMMON/s1ap_messages_types.h
index f6b4f3c4e2..2151375686 100644
--- a/openair2/COMMON/s1ap_messages_types.h
+++ b/openair2/COMMON/s1ap_messages_types.h
@@ -155,6 +155,11 @@ typedef struct security_capabilities_s {
uint16_t integrity_algorithms;
} security_capabilities_t;
+typedef struct nr_security_capabilities_s {
+ uint16_t encryption_algorithms;
+ uint16_t integrity_algorithms;
+} nr_security_capabilities_t;
+
/* Provides the establishment cause for the RRC connection request as provided
* by the upper layers. W.r.t. the cause value names: highPriorityAccess
* concerns AC11..AC15, ‘mt’ stands for ‘Mobile Terminating’ and ‘mo’ for
@@ -393,6 +398,11 @@ typedef struct s1ap_register_enb_req_s {
/* Number of SCTP streams used for a mme association */
uint16_t sctp_in_streams;
uint16_t sctp_out_streams;
+ uint16_t s1_setuprsp_wait_timer;
+ uint16_t s1_setupreq_wait_timer;
+ uint16_t s1_setupreq_count;
+ uint16_t sctp_req_timer;
+ uint16_t sctp_req_count;
} s1ap_register_enb_req_t;
//-------------------------------------------------------------------------------------------//
@@ -538,6 +548,9 @@ typedef struct s1ap_initial_context_setup_req_s {
uint8_t nb_of_e_rabs;
/* list of e_rab to be setup by RRC layers */
e_rab_t e_rab_param[S1AP_MAX_E_RAB];
+
+ /* NR Security algorithms (if any, set to 0 if not present) */
+ nr_security_capabilities_t nr_security_capabilities;
} s1ap_initial_context_setup_req_t;
typedef struct tai_plmn_identity_s {
diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h
index 0c55764d6e..f4911c47dc 100644
--- a/openair2/COMMON/x2ap_messages_types.h
+++ b/openair2/COMMON/x2ap_messages_types.h
@@ -338,7 +338,7 @@ typedef struct x2ap_ENDC_sgnb_addition_req_s {
/* used for RRC->X2AP in source eNB */
int rnti;
- security_capabilities_t security_capabilities;
+ nr_security_capabilities_t security_capabilities;
/* SgNB Security Key */
uint8_t kgnb[32];
diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c
index 6c709ea63b..d05fe7ac26 100644
--- a/openair2/ENB_APP/enb_config.c
+++ b/openair2/ENB_APP/enb_config.c
@@ -2429,6 +2429,65 @@ int RCconfig_S1(
"to\n"
" tracking_area_code = 1; // no string!!\n"
" plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } )\n");
+ if(*ENBParamList.paramarray[k][ENB_S1SETUP_RSP_TIMER_IDX].uptr <= 0xffff)
+ {
+ S1AP_REGISTER_ENB_REQ(msg_p).s1_setuprsp_wait_timer = *ENBParamList.paramarray[k][ENB_S1SETUP_RSP_TIMER_IDX].uptr;
+ }
+ else
+ {
+ LOG_E(S1AP,
+ "s1setup_rsp_timer value in conf file is invalid (%d). Default value is set.\n",
+ *ENBParamList.paramarray[k][ENB_S1SETUP_RSP_TIMER_IDX].uptr);
+ S1AP_REGISTER_ENB_REQ(msg_p).s1_setuprsp_wait_timer = 5;
+ }
+
+ if(*ENBParamList.paramarray[k][ENB_S1SETUP_REQ_TIMER_IDX].uptr <= 0xffff)
+ {
+ S1AP_REGISTER_ENB_REQ(msg_p).s1_setupreq_wait_timer = *ENBParamList.paramarray[k][ENB_S1SETUP_REQ_TIMER_IDX].uptr;
+ }
+ else
+ {
+ LOG_E(S1AP,
+ "s1setup_req_timer value in conf file is invalid (%d). Default value is set.\n",
+ *ENBParamList.paramarray[k][ENB_S1SETUP_REQ_TIMER_IDX].uptr);
+ S1AP_REGISTER_ENB_REQ(msg_p).s1_setupreq_wait_timer = 5;
+ }
+
+ if(*ENBParamList.paramarray[k][ENB_S1SETUP_REQ_COUNT_IDX].uptr <= 0xffff)
+ {
+ S1AP_REGISTER_ENB_REQ(msg_p).s1_setupreq_count = *ENBParamList.paramarray[k][ENB_S1SETUP_REQ_COUNT_IDX].uptr;
+ }
+ else
+ {
+ LOG_E(S1AP,
+ "s1setup_req_count value in conf file is invalid (%d). Default value is set.\n",
+ *ENBParamList.paramarray[k][ENB_S1SETUP_REQ_COUNT_IDX].uptr);
+ S1AP_REGISTER_ENB_REQ(msg_p).s1_setupreq_count = 0xffff;
+ }
+
+ if(*ENBParamList.paramarray[k][ENB_SCTP_REQ_TIMER_IDX].uptr <= 0xffff)
+ {
+ S1AP_REGISTER_ENB_REQ(msg_p).sctp_req_timer = *ENBParamList.paramarray[k][ENB_SCTP_REQ_TIMER_IDX].uptr;
+ }
+ else
+ {
+ LOG_E(S1AP,
+ "sctp_req_timer value in conf file is invalid (%d). Default value is set.\n",
+ *ENBParamList.paramarray[k][ENB_SCTP_REQ_TIMER_IDX].uptr);
+ S1AP_REGISTER_ENB_REQ(msg_p).sctp_req_timer = 180;
+ }
+
+ if(*ENBParamList.paramarray[k][ENB_SCTP_REQ_COUNT_IDX].uptr <= 0xffff)
+ {
+ S1AP_REGISTER_ENB_REQ(msg_p).sctp_req_count = *ENBParamList.paramarray[k][ENB_SCTP_REQ_COUNT_IDX].uptr;
+ }
+ else
+ {
+ LOG_E(S1AP,
+ "sctp_req_count value in conf file is invalid (%d). Default value is set.\n",
+ *ENBParamList.paramarray[k][ENB_SCTP_REQ_COUNT_IDX].uptr);
+ S1AP_REGISTER_ENB_REQ(msg_p).sctp_req_count = 0xffff;
+ }
config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), aprefix);
if (PLMNParamList.numelt < 1 || PLMNParamList.numelt > 6) {
diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h
index de7e0bbdad..f26863414c 100644
--- a/openair2/ENB_APP/enb_paramdef.h
+++ b/openair2/ENB_APP/enb_paramdef.h
@@ -214,6 +214,11 @@ typedef enum {
#define ENB_CONFIG_STRING_X2 "enable_x2"
#define ENB_CONFIG_STRING_ENB_M2 "enable_enb_m2"
#define ENB_CONFIG_STRING_MCE_M2 "enable_mce_m2"
+#define ENB_CONFIG_STRING_S1SETUP_RSP_TIMER "s1setup_rsp_timer"
+#define ENB_CONFIG_STRING_S1SETUP_REQ_TIMER "s1setup_req_timer"
+#define ENB_CONFIG_STRING_S1SETUP_REQ_COUNT "s1setup_req_count"
+#define ENB_CONFIG_STRING_SCTP_REQ_TIMER "sctp_req_timer"
+#define ENB_CONFIG_STRING_SCTP_REQ_COUNT "sctp_req_count"
/*-----------------------------------------------------------------------------------------------------------------------------------------*/
/* cell configuration parameters */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
@@ -239,6 +244,11 @@ typedef enum {
{ENB_CONFIG_STRING_X2, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
{ENB_CONFIG_STRING_ENB_M2, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \
{ENB_CONFIG_STRING_MCE_M2, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \
+ {ENB_CONFIG_STRING_S1SETUP_RSP_TIMER, NULL, 0, uptr:NULL, defuintval:5, TYPE_UINT, 0}, \
+ {ENB_CONFIG_STRING_S1SETUP_REQ_TIMER, NULL, 0, uptr:NULL, defuintval:5, TYPE_UINT, 0}, \
+ {ENB_CONFIG_STRING_S1SETUP_REQ_COUNT, NULL, 0, uptr:NULL, defuintval:65535, TYPE_UINT, 0}, \
+ {ENB_CONFIG_STRING_SCTP_REQ_TIMER, NULL, 0, uptr:NULL, defuintval:180, TYPE_UINT, 0}, \
+ {ENB_CONFIG_STRING_SCTP_REQ_COUNT, NULL, 0, uptr:NULL, defuintval:65535, TYPE_UINT, 0}, \
}
#define ENB_ENB_ID_IDX 0
@@ -261,6 +271,11 @@ typedef enum {
#define ENB_ENABLE_X2 17
#define ENB_ENABLE_ENB_M2 18
#define ENB_ENABLE_MCE_M2 19
+#define ENB_S1SETUP_RSP_TIMER_IDX 20
+#define ENB_S1SETUP_REQ_TIMER_IDX 21
+#define ENB_S1SETUP_REQ_COUNT_IDX 22
+#define ENB_SCTP_REQ_TIMER_IDX 23
+#define ENB_SCTP_REQ_COUNT_IDX 24
#define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD}
#define ENBPARAMS_CHECK { \
diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c
index 8902cd8db4..0600ee408a 100644
--- a/openair2/GNB_APP/gnb_config.c
+++ b/openair2/GNB_APP/gnb_config.c
@@ -163,6 +163,8 @@ void prepare_scc(NR_ServingCellConfigCommon_t *scc) {
// scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rsrp_ThresholdSSB_SUL = CALLOC(1,sizeof(NR_RSRP_Range_t));
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing = CALLOC(1,sizeof(NR_SubcarrierSpacing_t));
scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder = CALLOC(1,sizeof(long));
+ // 0 - ENABLE, 1 - DISABLE, hence explicitly setting to DISABLED.
+ *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder = NR_PUSCH_Config__transformPrecoder_disabled;
scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon = CALLOC(1,sizeof(NR_SetupRelease_PUSCH_ConfigCommon_t));
scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->present = NR_SetupRelease_PUSCH_ConfigCommon_PR_setup;
scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup = CALLOC(1,sizeof(struct NR_PUSCH_ConfigCommon));
@@ -430,7 +432,7 @@ void RCconfig_NR_L1(void) {
mac_top_init_gNB();
- configure_nfapi_pnf(RC.gNB[j]->eth_params_n.remote_addr, RC.gNB[j]->eth_params_n.remote_portc, RC.gNB[j]->eth_params_n.my_addr, RC.gNB[j]->eth_params_n.my_portd, RC.gNB[j]->eth_params_n .remote_portd);
+ configure_nr_nfapi_pnf(RC.gNB[j]->eth_params_n.remote_addr, RC.gNB[j]->eth_params_n.remote_portc, RC.gNB[j]->eth_params_n.my_addr, RC.gNB[j]->eth_params_n.my_portd, RC.gNB[j]->eth_params_n .remote_portd);
}else { // other midhaul
}
}// for (j = 0; j < RC.nb_nr_L1_inst; j++)
@@ -500,8 +502,8 @@ void RCconfig_nr_macrlc() {
//sf_ahead = 2; // Cannot cope with 4 subframes between RX and TX - set it to 2
- printf("**************** vnf_port:%d\n", RC.mac[j]->eth_params_s.my_portc);
- configure_nfapi_vnf(RC.nrmac[j]->eth_params_s.my_addr, RC.nrmac[j]->eth_params_s.my_portc);
+ printf("**************** vnf_port:%d\n", RC.nrmac[j]->eth_params_s.my_portc);
+ configure_nr_nfapi_vnf(RC.nrmac[j]->eth_params_s.my_addr, RC.nrmac[j]->eth_params_s.my_portc);
printf("**************** RETURNED FROM configure_nfapi_vnf() vnf_port:%d\n", RC.nrmac[j]->eth_params_s.my_portc);
}else { // other midhaul
AssertFatal(1==0,"MACRLC %d: %s unknown southbound midhaul\n",j,*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr));
@@ -513,6 +515,101 @@ void RCconfig_nr_macrlc() {
}
+void config_security(gNB_RRC_INST *rrc)
+{
+ paramdef_t logparams_defaults[] = SECURITY_GLOBALPARAMS_DESC;
+ int ret = config_get(logparams_defaults,
+ sizeof(logparams_defaults) / sizeof(paramdef_t),
+ CONFIG_STRING_SECURITY);
+ int i;
+
+ if (ret < 0) {
+ LOG_W(RRC, "configuration file does not contain a \"security\" section, applying default parameters (no security)\n");
+ rrc->security.ciphering_algorithms[0] = 0; /* nea0 = no ciphering */
+ rrc->security.ciphering_algorithms_count = 1;
+ rrc->security.integrity_algorithms[0] = 0; /* nia0 = no integrity */
+ rrc->security.integrity_algorithms_count = 1;
+ return;
+ }
+
+ if (logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].numelt > 4) {
+ LOG_E(RRC, "too much ciphering algorithms in section \"security\" of the configuration file, maximum is 4\n");
+ exit(1);
+ }
+ if (logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].numelt > 4) {
+ LOG_E(RRC, "too much integrity algorithms in section \"security\" of the configuration file, maximum is 4\n");
+ exit(1);
+ }
+
+ /* get ciphering algorithms */
+ rrc->security.ciphering_algorithms_count = 0;
+ for (i = 0; i < logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].numelt; i++) {
+ if (!strcmp(logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i], "nea0")) {
+ rrc->security.ciphering_algorithms[rrc->security.ciphering_algorithms_count] = 0;
+ rrc->security.ciphering_algorithms_count++;
+ continue;
+ }
+ if (!strcmp(logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i], "nea1")) {
+ rrc->security.ciphering_algorithms[rrc->security.ciphering_algorithms_count] = 1;
+ rrc->security.ciphering_algorithms_count++;
+ continue;
+ }
+ if (!strcmp(logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i], "nea2")) {
+ rrc->security.ciphering_algorithms[rrc->security.ciphering_algorithms_count] = 2;
+ rrc->security.ciphering_algorithms_count++;
+ continue;
+ }
+ if (!strcmp(logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i], "nea3")) {
+ rrc->security.ciphering_algorithms[rrc->security.ciphering_algorithms_count] = 3;
+ rrc->security.ciphering_algorithms_count++;
+ continue;
+ }
+ LOG_E(RRC, "unknown ciphering algorithm \"%s\" in section \"security\" of the configuration file\n",
+ logparams_defaults[SECURITY_CONFIG_CIPHERING_IDX].strlistptr[i]);
+ exit(1);
+ }
+
+ /* get integrity algorithms */
+ rrc->security.integrity_algorithms_count = 0;
+ for (i = 0; i < logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].numelt; i++) {
+ if (!strcmp(logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i], "nia0")) {
+ rrc->security.integrity_algorithms[rrc->security.integrity_algorithms_count] = 0;
+ rrc->security.integrity_algorithms_count++;
+ continue;
+ }
+ if (!strcmp(logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i], "nia1")) {
+ rrc->security.integrity_algorithms[rrc->security.integrity_algorithms_count] = 1;
+ rrc->security.integrity_algorithms_count++;
+ continue;
+ }
+ if (!strcmp(logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i], "nia2")) {
+ rrc->security.integrity_algorithms[rrc->security.integrity_algorithms_count] = 2;
+ rrc->security.integrity_algorithms_count++;
+ continue;
+ }
+ if (!strcmp(logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i], "nia3")) {
+ rrc->security.integrity_algorithms[rrc->security.integrity_algorithms_count] = 3;
+ rrc->security.integrity_algorithms_count++;
+ continue;
+ }
+ LOG_E(RRC, "unknown integrity algorithm \"%s\" in section \"security\" of the configuration file\n",
+ logparams_defaults[SECURITY_CONFIG_INTEGRITY_IDX].strlistptr[i]);
+ exit(1);
+ }
+
+ if (rrc->security.ciphering_algorithms_count == 0) {
+ LOG_W(RRC, "no preferred ciphering algorithm set in configuration file, applying default parameters (no security)\n");
+ rrc->security.ciphering_algorithms[0] = 0; /* nea0 = no ciphering */
+ rrc->security.ciphering_algorithms_count = 1;
+ }
+
+ if (rrc->security.integrity_algorithms_count == 0) {
+ LOG_W(RRC, "no preferred integrity algorithm set in configuration file, applying default parameters (no security)\n");
+ rrc->security.integrity_algorithms[0] = 0; /* nia0 = no integrity */
+ rrc->security.integrity_algorithms_count = 1;
+ }
+}
+
void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
int num_gnbs = 0;
@@ -681,7 +778,7 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) {
}//End for (k=0; k 0)
-
+ config_security(rrc);
}//End RCconfig_NRRRC function
int RCconfig_nr_gtpu(void ) {
diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h
index b823ed41fc..8b326d58c9 100644
--- a/openair2/GNB_APP/gnb_paramdef.h
+++ b/openair2/GNB_APP/gnb_paramdef.h
@@ -455,4 +455,27 @@ typedef enum {
#define CONFIG_HLP_WORKER "coding and FEP worker thread WORKER_DISABLE or WORKER_ENABLE\n"
#define CONFIG_HLP_PARALLEL "PARALLEL_SINGLE_THREAD, PARALLEL_RU_L1_SPLIT, or PARALLEL_RU_L1_TRX_SPLIT(RU_L1_TRX_SPLIT by defult)\n"
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+/* security configuration */
+/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+#define CONFIG_STRING_SECURITY "security"
+
+#define SECURITY_CONFIG_CIPHERING "ciphering_algorithms"
+#define SECURITY_CONFIG_INTEGRITY "integrity_algorithms"
+
+/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+/* security configuration */
+/* optname help paramflags XXXptr defXXXval type numelt */
+/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+#define SECURITY_GLOBALPARAMS_DESC { \
+ {SECURITY_CONFIG_CIPHERING, "preferred ciphering algorithms\n", 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST, 0}, \
+ {SECURITY_CONFIG_INTEGRITY, "preferred integrity algorithms\n", 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST, 0}, \
+}
+
+#define SECURITY_CONFIG_CIPHERING_IDX 0
+#define SECURITY_CONFIG_INTEGRITY_IDX 1
+/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+
#endif
diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h
index 1bae590a59..ae8522bc83 100644
--- a/openair2/LAYER2/MAC/mac.h
+++ b/openair2/LAYER2/MAC/mac.h
@@ -490,7 +490,7 @@ typedef struct {
/*! \brief Uplink SCH PDU Structure */
typedef struct {
- int8_t payload[SCH_PAYLOAD_SIZE_MAX]; /*!< \brief SACH payload */
+ uint8_t payload[SCH_PAYLOAD_SIZE_MAX]; /*!< \brief SACH payload */
uint16_t Pdu_size;
} __attribute__ ((__packed__)) ULSCH_PDU;
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
index 8dc261df1d..ce4e0f81f3 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
@@ -31,6 +31,7 @@
*/
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
+#include "common/utils/nr/nr_common.h"
#include
#define reserved 0xffff
@@ -1220,6 +1221,11 @@ int get_nr_prach_occasion_info_from_index(uint8_t index,
else { // FDD
x = table_6_3_3_2_2_prachConfig_Index[index][2];
s_map = table_6_3_3_2_2_prachConfig_Index[index][4];
+ for(int i = 0; i < 64 ; i++) {
+ if ( (s_map >> i) & 0x01) {
+ (*N_RA_sfn)++;
+ }
+ }
*N_RA_slot = table_6_3_3_2_2_prachConfig_Index[index][6];
if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL){
*start_symbol = table_6_3_3_2_2_prachConfig_Index[index][5];
@@ -1429,6 +1435,11 @@ int get_nr_prach_info_from_index(uint8_t index,
if ( (table_6_3_3_2_2_prachConfig_Index[index][6] <= 1) && (slot%2 == 0) )
return 0; // no prach in even slots @ 30kHz for 1 prach per subframe
}
+ for(int i = 0; i <= subframe ; i++) {
+ if ( (s_map >> i) & 0x01) {
+ (*RA_sfn_index)++;
+ }
+ }
if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL){
*start_symbol = table_6_3_3_2_2_prachConfig_Index[index][5];
*N_t_slot = table_6_3_3_2_2_prachConfig_Index[index][7];
@@ -1567,79 +1578,6 @@ uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config,
}
}
-// Table 5.2-1 NR operating bands in FR1 & FR2 (3GPP TS 38.101)
-// Table 5.4.2.3-1 Applicable NR-ARFCN per operating band in FR1 & FR2 (3GPP TS 38.101)
-// Notes:
-// - N_OFFs for bands from 80 to 89 and band 95 is referred to UL
-// - Frequencies are expressed in KHz
-// - col: NR_band ul_min ul_max dl_min dl_max step N_OFFs_DL deltaf_raster
-nr_bandentry_t nr_bandtable[] = {
- {1, 1920000, 1980000, 2110000, 2170000, 20, 422000, 100},
- {2, 1850000, 1910000, 1930000, 1990000, 20, 386000, 100},
- {3, 1710000, 1785000, 1805000, 1880000, 20, 361000, 100},
- {5, 824000, 849000, 869000, 894000, 20, 173800, 100},
- {7, 2500000, 2570000, 2620000, 2690000, 20, 524000, 100},
- {8, 880000, 915000, 925000, 960000, 20, 185000, 100},
- {12, 698000, 716000, 729000, 746000, 20, 145800, 100},
- {14, 788000, 798000, 758000, 768000, 20, 151600, 100},
- {18, 815000, 830000, 860000, 875000, 20, 172000, 100},
- {20, 832000, 862000, 791000, 821000, 20, 158200, 100},
- {25, 1850000, 1915000, 1930000, 1995000, 20, 386000, 100},
- {26, 814000, 849000, 859000, 894000, 20, 171800, 100},
- {28, 703000, 758000, 758000, 813000, 20, 151600, 100},
- {29, 000, 000, 717000, 728000, 20, 143400, 100},
- {30, 2305000, 2315000, 2350000, 2360000, 20, 470000, 100},
- {34, 2010000, 2025000, 2010000, 2025000, 20, 402000, 100},
- {38, 2570000, 2620000, 2570000, 2630000, 20, 514000, 100},
- {39, 1880000, 1920000, 1880000, 1920000, 20, 376000, 100},
- {40, 2300000, 2400000, 2300000, 2400000, 20, 460000, 100},
- {41, 2496000, 2690000, 2496000, 2690000, 3, 499200, 15},
- {41, 2496000, 2690000, 2496000, 2690000, 6, 499200, 30},
- {47, 5855000, 5925000, 5855000, 5925000, 1, 790334, 15},
- //{48, 3550000, 3700000, 3550000, 3700000, 1, 636667, 15},
- //{48, 3550000, 3700000, 3550000, 3700000, 2, 636668, 30},
- {50, 1432000, 1517000, 1432000, 1517000, 20, 286400, 100},
- {51, 1427000, 1432000, 1427000, 1432000, 20, 285400, 100},
- {53, 2483500, 2495000, 2483500, 2495000, 20, 496700, 100},
- {65, 1920000, 2010000, 2110000, 2200000, 20, 422000, 100},
- {66, 1710000, 1780000, 2110000, 2200000, 20, 422000, 100},
- {70, 1695000, 1710000, 1995000, 2020000, 20, 399000, 100},
- {71, 663000, 698000, 617000, 652000, 20, 123400, 100},
- {74, 1427000, 1470000, 1475000, 1518000, 20, 295000, 100},
- {75, 000, 000, 1432000, 1517000, 20, 286400, 100},
- {76, 000, 000, 1427000, 1432000, 20, 285400, 100},
- {77, 3300000, 4200000, 3300000, 4200000, 1, 620000, 15},
- {77, 3300000, 4200000, 3300000, 4200000, 2, 620000, 30},
- {78, 3300000, 3800000, 3300000, 3800000, 1, 620000, 15},
- {78, 3300000, 3800000, 3300000, 3800000, 2, 620000, 30},
- {79, 4400010, 5000000, 4400010, 5000000, 1, 693334, 15},
- {79, 4400010, 5000000, 4400010, 5000000, 2, 693334, 30},
- {80, 1710000, 1785000, 000, 000, 20, 342000, 100},
- {81, 880000, 915000, 000, 000, 20, 176000, 100},
- {82, 832000, 862000, 000, 000, 20, 166400, 100},
- {83, 703000, 748000, 000, 000, 20, 140600, 100},
- {84, 1920000, 1980000, 000, 000, 20, 384000, 100},
- {86, 1710000, 1785000, 000, 000, 20, 342000, 100},
- {89, 824000, 849000, 000, 000, 20, 342000, 100},
- {90, 2496000, 2690000, 2496000, 2690000, 3, 499200, 15},
- {90, 2496000, 2690000, 2496000, 2690000, 6, 499200, 30},
- {90, 2496000, 2690000, 2496000, 2690000, 20, 499200, 100},
- {91, 832000, 862000, 1427000, 1432000, 20, 285400, 100},
- {92, 832000, 862000, 1432000, 1517000, 20, 286400, 100},
- {93, 880000, 915000, 1427000, 1432000, 20, 285400, 100},
- {94, 880000, 915000, 1432000, 1517000, 20, 286400, 100},
- {95, 2010000, 2025000, 000, 000, 20, 402000, 100},
- {257,26500020,29500000,26500020,29500000, 1,2054166, 60},
- {257,26500080,29500000,26500080,29500000, 2,2054167, 120},
- {258,24250080,27500000,24250080,27500000, 1,2016667, 60},
- {258,24250080,27500000,24250080,27500000, 2,2016667, 120},
- {260,37000020,40000000,37000020,40000000, 1,2229166, 60},
- {260,37000080,40000000,37000080,40000000, 2,2229167, 120},
- {261,27500040,28350000,27500040,28350000, 1,2070833, 60},
- {261,27500040,28350000,27500040,28350000, 2,2070833, 120}
-};
-
-
// TS 38.211 Table 6.4.1.1.3-3: PUSCH DMRS positions l' within a slot for single-symbol DMRS and intra-slot frequency hopping disabled.
// The first 4 colomns are PUSCH mapping type A and the last 4 colomns are PUSCH mapping type B.
// When l' = l0, it is represented by 1
@@ -1680,11 +1618,9 @@ int32_t table_6_4_1_1_3_4_pusch_dmrs_positions_l [12][8] = {
{1, 1025, -1, -1, 1, 513, -1, -1}, //14 // (DMRS l' position)
};
-#define NR_BANDTABLE_SIZE (sizeof(nr_bandtable)/sizeof(nr_bandentry_t))
-
// Returns the corresponding row index of the NR table
-int get_nr_table_idx(int nr_bandP, uint8_t scs_index){
-
+int get_nr_table_idx(int nr_bandP, uint8_t scs_index)
+{
int i, j;
int scs_khz = 15 << scs_index;
int supplementary_bands[] = {29,75,76,80,81,82,83,84,86,89,95};
@@ -1695,8 +1631,8 @@ int get_nr_table_idx(int nr_bandP, uint8_t scs_index){
AssertFatal(0 == 1, "Band %d is a supplementary band (%d). This is not supported yet.\n", nr_bandP, supplementary_bands[j]);
}
- AssertFatal(nr_bandP <= nr_bandtable[NR_BANDTABLE_SIZE-1].band, "NR band %d exceeds NR bands table maximum limit %d\n", nr_bandP, nr_bandtable[NR_BANDTABLE_SIZE-1].band);
- for (i = 0; i < NR_BANDTABLE_SIZE && nr_bandtable[i].band != nr_bandP; i++);
+ AssertFatal(nr_bandP <= nr_bandtable[nr_bandtable_size-1].band, "NR band %d exceeds NR bands table maximum limit %d\n", nr_bandP, nr_bandtable[nr_bandtable_size-1].band);
+ for (i = 0; i < nr_bandtable_size && nr_bandtable[i].band != nr_bandP; i++);
// selection of correct Deltaf raster according to SCS
if ((nr_bandtable[i].deltaf_raster != 100) && (nr_bandtable[i].deltaf_raster != scs_khz))
@@ -1705,35 +1641,33 @@ int get_nr_table_idx(int nr_bandP, uint8_t scs_index){
LOG_D(PHY, "NR band table index %d (Band %d, dl_min %lu, ul_min %lu)\n", i, nr_bandtable[i].band, nr_bandtable[i].dl_min,nr_bandtable[i].ul_min);
return i;
-
}
// Computes the duplex spacing (either positive or negative) in KHz
-void get_delta_duplex(int nr_bandP, uint8_t scs_index, int32_t *delta_duplex){
-
+int32_t get_delta_duplex(int nr_bandP, uint8_t scs_index)
+{
int nr_table_idx = get_nr_table_idx(nr_bandP, scs_index);
- *delta_duplex = (nr_bandtable[nr_table_idx].ul_min - nr_bandtable[nr_table_idx].dl_min);
+ int32_t delta_duplex = (nr_bandtable[nr_table_idx].ul_min - nr_bandtable[nr_table_idx].dl_min);
- LOG_D(PHY, "NR band duplex spacing is %d KHz (nr_bandtable[%d].band = %d)\n", *delta_duplex, nr_table_idx, nr_bandtable[nr_table_idx].band);
+ LOG_I(PHY, "NR band duplex spacing is %d KHz (nr_bandtable[%d].band = %d)\n", delta_duplex, nr_table_idx, nr_bandtable[nr_table_idx].band);
+ return delta_duplex;
}
-void get_frame_type(uint16_t current_band,
- uint8_t scs_index,
- lte_frame_type_t *current_type){
+lte_frame_type_t get_frame_type(uint16_t current_band, uint8_t scs_index)
+{
+ lte_frame_type_t current_type;
+ int32_t delta_duplex = get_delta_duplex(current_band, scs_index);
- int32_t current_offset;
- get_delta_duplex(current_band, scs_index, ¤t_offset);
-
- current_offset *= 1000;
- if (current_offset == 0)
- *current_type = TDD;
+ if (delta_duplex == 0)
+ current_type = TDD;
else
- *current_type = FDD;
+ current_type = FDD;
- LOG_I(MAC, "NR band %d, duplex mode %s, duplex spacing = %d KHz\n", current_band, duplex_mode[*current_type], current_offset);
+ LOG_I(MAC, "NR band %d, duplex mode %s, duplex spacing = %d KHz\n", current_band, duplex_mode[current_type], delta_duplex);
+ return current_type;
}
uint16_t config_bandwidth(int mu, int nb_rb, int nr_band)
@@ -1911,7 +1845,6 @@ uint64_t from_nrarfcn(int nr_bandP,
int deltaFglobal = 5;
uint32_t N_REF_Offs = 0;
uint64_t F_REF_Offs_khz = 0;
- int32_t delta_duplex;
uint64_t N_OFFs, frequency, freq_min;
int i = get_nr_table_idx(nr_bandP, scs_index);
@@ -1926,7 +1859,7 @@ uint64_t from_nrarfcn(int nr_bandP,
F_REF_Offs_khz = 24250080;
}
- get_delta_duplex(nr_bandP, scs_index, &delta_duplex);
+ int32_t delta_duplex = get_delta_duplex(nr_bandP, scs_index);
if (delta_duplex <= 0){ // DL band >= UL band
if (nrarfcn >= nr_bandtable[i].N_OFFs_DL){ // is TDD of FDD DL
@@ -2836,11 +2769,15 @@ int is_nr_DL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slot) {
else return(slot_in_period <= slots1+scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSlots ? 1 : 0);
}
-int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slot) {
+int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc, slot_t slot, lte_frame_type_t frame_type) {
int period,period1,period2=0;
- if (scc->tdd_UL_DL_ConfigurationCommon==NULL) return(1);
+ // Note: condition on frame_type
+ // goal: the UL scheduler assumes mode is TDD therefore this hack is needed to make FDD work
+ if (scc->tdd_UL_DL_ConfigurationCommon == NULL || frame_type == FDD) {
+ return(1);
+ }
if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1 &&
scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530)
@@ -3067,6 +3004,7 @@ bool set_dl_ptrs_values(NR_PTRS_DownlinkConfig_t *ptrs_config,
//printf("[MAC] PTRS is set K= %u L= %u\n", *K_ptrs,1<<*L_ptrs);
return valid;
}
+
uint32_t get_ssb_slot(uint32_t ssb_index){
// this function now only support f <= 3GHz
return ssb_index & 0x3 ;
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
index 58ecd54733..ffb36963a7 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
@@ -39,9 +39,9 @@
uint16_t config_bandwidth(int mu, int nb_rb, int nr_band);
-void get_frame_type(uint16_t nr_bandP, uint8_t scs_index, lte_frame_type_t *current_type);
+lte_frame_type_t get_frame_type(uint16_t nr_bandP, uint8_t scs_index);
-void get_delta_duplex(int nr_bandP, uint8_t scs_index, int32_t *delta_duplex);
+int32_t get_delta_duplex(int nr_bandP, uint8_t scs_index);
uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t dl_nrarfcn);
@@ -51,7 +51,7 @@ int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,i
int is_nr_DL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slotP);
-int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slotP);
+int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc, slot_t slotP, lte_frame_type_t frame_type);
uint16_t nr_dci_size(const NR_ServingCellConfigCommon_t *scc,
const NR_CellGroupConfig_t *secondaryCellGroup,
diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c
index f6bd5436bc..fee2efc4a8 100755
--- a/openair2/LAYER2/NR_MAC_UE/config_ue.c
+++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c
@@ -203,13 +203,12 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
uint32_t band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
frequency_range_t frequency_range = band<100?FR1:FR2;
- lte_frame_type_t frame_type;
- get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing, &frame_type);
+ mac->frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
// cell config
cfg->cell_config.phy_cell_id = *scc->physCellId;
- cfg->cell_config.frame_duplex_type = frame_type;
+ cfg->cell_config.frame_duplex_type = mac->frame_type;
// SSB config
cfg->ssb_config.ss_pbch_power = scc->ss_PBCH_BlockPower;
@@ -313,7 +312,7 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
cfg->prach_config.num_prach_fd_occasions_list[i].k1 = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart;
cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig;
- cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences = compute_nr_root_seq(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup, nb_preambles, frame_type,frequency_range);
+ cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences = compute_nr_root_seq(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup, nb_preambles, mac->frame_type, frequency_range);
//cfg->prach_config.num_prach_fd_occasions_list[i].num_unused_root_sequences = ???
}
diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h
index dd0aa15c52..3e299d291e 100755
--- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h
@@ -325,6 +325,8 @@ typedef struct {
NR_ControlResourceSet_t *coreset[MAX_NUM_BWP][FAPI_NR_MAX_CORESET_PER_BWP];
NR_SearchSpace_t *SSpace[MAX_NUM_BWP][FAPI_NR_MAX_CORESET_PER_BWP][FAPI_NR_MAX_SS_PER_CORESET];
+ lte_frame_type_t frame_type;
+
/*BWP*/
// dedicated active DL BWP
NR_BWP_Id_t DL_BWP_Id;
diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
index c4909c1384..14d1ea63fb 100755
--- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
@@ -56,14 +56,14 @@ int8_t nr_ue_decode_mib(
void *pduP,
uint16_t cell_id );
-/**\brief decode sib1 pdu in NR_UE, from if_module dl_ind
+/**\brief decode SIB1 and other SIs pdus in NR_UE, from if_module dl_ind
\param module_id module id
\param cc_id component carrier id
\param gNB_index gNB index
\param sibs_mask sibs mask
\param pduP pointer to pdu
\param pdu_length length of pdu */
-int8_t nr_ue_decode_sib1(module_id_t module_id,
+int8_t nr_ue_decode_BCCH_DL_SCH(module_id_t module_id,
int cc_id,
unsigned int gNB_index,
uint32_t sibs_mask,
diff --git a/openair2/LAYER2/NR_MAC_UE/mac_vars.c b/openair2/LAYER2/NR_MAC_UE/mac_vars.c
index ecabdb870c..383267090f 100644
--- a/openair2/LAYER2/NR_MAC_UE/mac_vars.c
+++ b/openair2/LAYER2/NR_MAC_UE/mac_vars.c
@@ -32,7 +32,7 @@
#include
-const char *rnti_types[]={"RNTI_new", "RNTI_C", "RNTI_RA", "NR_RNTI_P", "NR_RNTI_CS", "NR_RNTI_TC"};
+const char *rnti_types[]={"RNTI_new", "RNTI_C", "RNTI_RA", "NR_RNTI_P", "NR_RNTI_CS", "NR_RNTI_TC", "NR_RNTI_SP_CSI", "NR_RNTI_SI"};
const char *dci_formats[]={"1_0", "1_1", "2_0", "2_1", "2_2", "2_3", "0_0", "0_1"};
// table_7_3_1_1_2_2_3_4_5 contains values for number of layers and precoding information for tables 7.3.1.1.2-2/3/4/5 from TS 38.212 subclause 7.3.1.1.2
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c
index b4b63e0064..8f234cb585 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c
@@ -35,6 +35,7 @@
/* RRC */
#include "NR_RACH-ConfigCommon.h"
+#include "RRC/NR_UE/rrc_proto.h"
/* PHY */
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
@@ -514,7 +515,8 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
uint8_t sdu_lcids[NB_RB_MAX] = {0};
uint16_t sdu_lengths[NB_RB_MAX] = {0};
- int TBS_bytes = 848, header_length_total=0, num_sdus, offset, mac_ce_len;
+ int num_sdus = 0;
+ int offset = 0;
// Delay init RA procedure to allow the convergence of the IIR filter on PRACH noise measurements at gNB side
if (!prach_resources->init_msg1) {
@@ -532,36 +534,27 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
LOG_D(MAC, "RA not active. Checking for data to transmit from upper layers...\n");
- payload = (uint8_t*) &mac->CCCH_pdu.payload;
- mac_ce_len = 0;
+ uint8_t TBS_max = 8 + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT);
+ payload = (uint8_t*) mac->CCCH_pdu.payload;
+
num_sdus = 1;
post_padding = 1;
+ sdu_lcids[0] = lcid;
- if (0){
- // initialisation by RRC
- // CCCH PDU
- // size_sdu = (uint16_t) mac_rrc_data_req_ue(mod_id,
- // CC_id,
- // frame,
- // CCCH,
- // 1,
- // mac_sdus,
- // gNB_id,
- // 0);
- LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n", mod_id, frame, size_sdu);
- } else {
- // 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_lcids and sdu_lengths
- sdu_lcids[0] = lcid;
- sdu_lengths[0] = TBS_bytes - 3 - post_padding - mac_ce_len;
- header_length_total += 2 + (sdu_lengths[0] >= 128);
- size_sdu += sdu_lengths[0];
+ // initialisation by RRC
+
+ // TODO: To be removed after RA procedures fully implemented
+ if(get_softmodem_params()->do_ra) {
+ nr_rrc_ue_generate_RRCSetupRequest(mod_id,gNB_id);
}
+ // CCCH PDU
+ size_sdu = (uint16_t) nr_mac_rrc_data_req_ue(mod_id, CC_id, gNB_id, frame, CCCH, mac_sdus);
+
+ sdu_lengths[0] = size_sdu;
+
+ LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n", mod_id, frame, size_sdu);
+
if (size_sdu > 0) {
LOG_D(MAC, "[UE %d][%d.%d]: starting initialisation Random Access Procedure...\n", mod_id, frame, nr_slot_tx);
@@ -589,12 +582,27 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
post_padding,
0);
+ AssertFatal(TBS_max > offset, "Frequency resources are not enough for Msg3!\n");
+
// Padding: fill remainder with 0
if (post_padding > 0){
- for (int j = 0; j < (TBS_bytes - offset); j++)
- payload[offset + j] = 0; // mac_pdu[offset + j] = 0;
+ for (int j = 0; j < (TBS_max - offset); j++)
+ payload[offset + j] = 0;
}
- }
+ }
+
+ LOG_D(MAC,"size_sdu = %i\n", size_sdu);
+ LOG_D(MAC,"offset = %i\n", offset);
+ for(int k = 0; k < TBS_max; k++) {
+ LOG_D(MAC,"(%i): %i\n", k, prach_resources->Msg3[k]);
+ }
+
+ // 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, prach_resources->Msg3, TBS_max);
+
} else if (ra->RA_window_cnt != -1) { // RACH is active
LOG_D(MAC, "In %s [%d.%d] RA is active: RA window count %d, RA backoff count %d\n", __FUNCTION__, frame, nr_slot_tx, ra->RA_window_cnt, ra->RA_backoff_cnt);
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
index 64067e9d60..568d1808de 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
@@ -154,13 +154,13 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
return 0;
}
-int8_t nr_ue_decode_sib1(module_id_t module_id,
- int cc_id,
- unsigned int gNB_index,
- uint32_t sibs_mask,
- uint8_t *pduP,
- uint32_t pdu_len) {
- LOG_D(MAC, "Decode sib1\n");
+int8_t nr_ue_decode_BCCH_DL_SCH(module_id_t module_id,
+ int cc_id,
+ unsigned int gNB_index,
+ uint32_t sibs_mask,
+ uint8_t *pduP,
+ uint32_t pdu_len) {
+ LOG_D(NR_MAC, "Decoding NR-BCCH-DL-SCH-Message (SIB1 or SI)\n");
nr_mac_rrc_data_ind_ue(module_id, cc_id, gNB_index, NR_BCCH_DL_SCH, (uint8_t *) pduP, pdu_len);
return 0;
}
@@ -814,7 +814,17 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH;
dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.rnti = rnti;
+
+ // FIXME: fix number of additional dmrs
+ if(pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition == NULL)
+ pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition=calloc(1,sizeof(*pdsch_config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition));
+
fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu_1_1 = &dl_config->dl_config_list[dl_config->number_pdus].dlsch_config_pdu.dlsch_config_rel15;
+
+ dlsch_config_pdu_1_1->BWPSize = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+ dlsch_config_pdu_1_1->BWPStart = NRRIV2PRBOFFSET(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
+ dlsch_config_pdu_1_1->SubcarrierSpacing = mac->DLbwp[0]->bwp_Common->genericParameters.subcarrierSpacing;
+
/* IDENTIFIER_DCI_FORMATS */
/* CARRIER_IND */
/* BANDWIDTH_PART_IND */
@@ -2230,7 +2240,7 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t
// TA command
ul_time_alignment->apply_ta = 1;
- ul_time_alignment->ta_command = rar->TA2 + (rar->TA1 << 5);
+ ul_time_alignment->ta_command = 31 + rar->TA2 + (rar->TA1 << 5);
#ifdef DEBUG_RAR
// CSI
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
index d6e1cba6df..194df8101f 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
@@ -118,13 +118,14 @@ long get_k2(NR_UE_MAC_INST_t *mac, uint8_t time_domain_ind) {
* This function returns the UL config corresponding to a given UL slot
* from MAC instance .
*/
-fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int slot) {
+fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int slot)
+{
//Check if request to access ul_config is for a UL slot
- if (is_nr_UL_slot(mac->scc, slot) == 0) {
+ if (is_nr_UL_slot(mac->scc, slot, mac->frame_type) == 0) {
LOG_W(MAC, "Slot %d is not a UL slot. %s called for wrong slot!!!\n", slot, __FUNCTION__);
return NULL;
}
-
+
// Calculate the index of the UL slot in mac->ul_config_request list. This is
// based on the TDD pattern (slot configuration period) and number of UL+mixed
// slots in the period. TS 38.213 Sec 11.1
@@ -889,34 +890,40 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
uint16_t TBS_bytes = ulcfg_pdu->pusch_config_pdu.pusch_data.tb_size;
- // Push data from MAC to PHY only when NDI toggles
- if (IS_SOFTMODEM_NOS1 && (mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] != ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator)){
- // Getting IP traffic to be transmitted
- data_existing = nr_ue_get_sdu(mod_id,
- cc_id,
- frame_tx,
- slot_tx,
- 0,
- ulsch_input_buffer,
- TBS_bytes,
- &access_mode);
- }
+ if (ra->ra_state == WAIT_RAR){
+ memcpy(ulsch_input_buffer, mac->ulsch_pdu.payload, TBS_bytes);
+ LOG_D(NR_MAC,"[RAPROC] Msg3 to be transmitted:\n");
+ for (int k = 0; k < TBS_bytes; k++) {
+ LOG_D(NR_MAC,"(%i): 0x%x\n",k,mac->ulsch_pdu.payload[k]);
+ }
+ } else {
+ if (IS_SOFTMODEM_NOS1 && (mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] != ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator)){
+ // Getting IP traffic to be transmitted
+ data_existing = nr_ue_get_sdu(mod_id,
+ cc_id,
+ frame_tx,
+ slot_tx,
+ 0,
+ ulsch_input_buffer,
+ TBS_bytes,
+ &access_mode);
+ }
- mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator;
- //Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity
- if (!IS_SOFTMODEM_NOS1 || !data_existing) {
- //Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid
- //and block this traffic from being forwarded to the upper layers at the gNB
- LOG_D(PHY, "In %s: Random data to be transmitted: TBS_bytes %d \n", __FUNCTION__, TBS_bytes);
+ mac->UL_ndi[ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id] = ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator;
+ //Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity
+ if (!IS_SOFTMODEM_NOS1 || !data_existing) {
+ //Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid
+ //and block this traffic from being forwarded to the upper layers at the gNB
+ LOG_D(PHY, "In %s: Random data to be transmitted: TBS_bytes %d \n", __FUNCTION__, TBS_bytes);
- //Give the first byte a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2)
- //in order to distinguish the PHY random packets at the MAC layer of the gNB receiver from the normal packets that should
- //have a valid LCID (nr_process_mac_pdu function)
- ulsch_input_buffer[0] = 0x31;
+ //Give the first byte a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2)
+ //in order to distinguish the PHY random packets at the MAC layer of the gNB receiver from the normal packets that should
+ //have a valid LCID (nr_process_mac_pdu function)
+ ulsch_input_buffer[0] = 0x31;
- for (int i = 1; i < TBS_bytes; i++) {
- ulsch_input_buffer[i] = (unsigned char) rand();
- //printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
+ for (int i = 1; i < TBS_bytes; i++) {
+ ulsch_input_buffer[i] = (unsigned char) rand();
+ }
}
}
@@ -1662,7 +1669,7 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
ra->RA_offset = 2; // to compensate the rx frame offset at the gNB
ra->generate_nr_prach = 0; // Reset flag for PRACH generation
- if (is_nr_UL_slot(scc, slotP)) {
+ if (is_nr_UL_slot(scc, slotP, mac->frame_type)) {
// WIP Need to get the proper selected ssb_idx
// Initial beam selection functionality is not available yet
@@ -1683,13 +1690,11 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
format0 = format & 0xff; // single PRACH format
format1 = (format >> 8) & 0xff; // dual PRACH format
- ul_config->sfn = frameP;
- ul_config->slot = slotP;
-
- ul_config->ul_config_list[ul_config->number_pdus].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PRACH;
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));
- ul_config->number_pdus += 1;
+
+ fill_ul_config(ul_config, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PRACH);
+
LOG_D(PHY, "In %s: (%p) %d UL PDUs:\n", __FUNCTION__, ul_config, ul_config->number_pdus);
ncs = get_NCS(rach_ConfigGeneric->zeroCorrelationZoneConfig, format0, setup->restrictedSetConfig);
@@ -1767,11 +1772,10 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
AssertFatal(1 == 0, "Invalid PRACH format");
}
} // if format1
+ fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, thread_id);
+ if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
+ mac->if_module->scheduled_response(&scheduled_response);
} // is_nr_prach_slot
-
- fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, thread_id);
- if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
- mac->if_module->scheduled_response(&scheduled_response);
} // if is_nr_UL_slot
}
diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c
index d13488686d..3986e5b7f0 100644
--- a/openair2/LAYER2/NR_MAC_gNB/config.c
+++ b/openair2/LAYER2/NR_MAC_gNB/config.c
@@ -45,7 +45,7 @@
#include "NR_MIB.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
-
+#include "../../../../nfapi/oai_integration/vendor_ext.h"
/* Softmodem params */
#include "executables/softmodem-common.h"
@@ -127,8 +127,7 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, int pusch_AntennaPorts,
uint32_t band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
frequency_range_t frequency_range = band<100?FR1:FR2;
- lte_frame_type_t frame_type;
- get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing, &frame_type);
+ lte_frame_type_t frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
RC.nrmac[Mod_idP]->common_channels[0].frame_type = frame_type;
// Cell configuration
@@ -264,6 +263,7 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, int pusch_AntennaPorts,
}
cfg->ssb_table.ssb_mask_list[0].ssb_mask.tl.tag = NFAPI_NR_CONFIG_SSB_MASK_TAG;
+ cfg->ssb_table.ssb_mask_list[1].ssb_mask.tl.tag = NFAPI_NR_CONFIG_SSB_MASK_TAG;
cfg->num_tlv++;
cfg->carrier_config.num_tx_ant.value = pdsch_AntennaPorts;
@@ -306,7 +306,7 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, int pusch_AntennaPorts,
if (return_tdd != 0)
LOG_E(MAC,"TDD configuration can not be done\n");
else
- LOG_I(MAC,"TDD has been properly configurated\n");
+ LOG_I(MAC,"TDD has been properly configurated\n");
}
}
@@ -369,11 +369,11 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
LOG_E(MAC, "%s() %s:%d RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req:%p\n", __FUNCTION__, __FILE__, __LINE__, RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req);
// if in nFAPI mode
- if ( (nfapi_mode == 1 || nfapi_mode == 2) && (RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req == NULL) ){
+ if ( (NFAPI_MODE == NFAPI_MODE_PNF || NFAPI_MODE == NFAPI_MODE_VNF) && (RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req == NULL) ){
while(RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req == NULL) {
- // DJP AssertFatal(RC.nrmac[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");
+ // DJP AssertFatal(RC.nrmac[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");
}
}
@@ -403,21 +403,37 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
const int UE_id = add_new_nr_ue(Mod_idP, rnti, secondaryCellGroup);
LOG_I(PHY,"Added new UE_id %d/%x with initial secondaryCellGroup\n",UE_id,rnti);
} else if (add_ue == 1 && !get_softmodem_params()->phy_test) {
- /* TODO: should check for free RA process */
const int CC_id = 0;
- NR_RA_t *ra = &RC.nrmac[Mod_idP]->common_channels[CC_id].ra[0];
- ra->state = RA_IDLE;
+ NR_COMMON_channels_t *cc = &RC.nrmac[Mod_idP]->common_channels[CC_id];
+ uint8_t ra_index = 0;
+ /* checking for free RA process */
+ for(; ra_index < NR_NB_RA_PROC_MAX; ra_index++) {
+ if((cc->ra[ra_index].state == RA_IDLE) && (!cc->ra[ra_index].cfra)) break;
+ }
+ if (ra_index == NR_NB_RA_PROC_MAX) {
+ LOG_E(MAC, "%s() %s:%d RA processes are not available for CFRA RNTI :%x\n", __FUNCTION__, __FILE__, __LINE__, rnti);
+ return -1;
+ }
+ NR_RA_t *ra = &cc->ra[ra_index];
ra->secondaryCellGroup = secondaryCellGroup;
if (secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated!=NULL) {
if (secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra != NULL) {
ra->cfra = true;
ra->rnti = rnti;
- struct NR_CFRA cfra = *secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra;
- uint8_t num_preamble = cfra.resources.choice.ssb->ssb_ResourceList.list.count;
+ struct NR_CFRA *cfra = secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra;
+ uint8_t num_preamble = cfra->resources.choice.ssb->ssb_ResourceList.list.count;
ra->preambles.num_preambles = num_preamble;
ra->preambles.preamble_list = (uint8_t *) malloc(num_preamble*sizeof(uint8_t));
- for (int i = 0; i < num_preamble; i++)
- ra->preambles.preamble_list[i] = cfra.resources.choice.ssb->ssb_ResourceList.list.array[i]->ra_PreambleIndex;
+ for(int i=0; inum_active_ssb; i++) {
+ for(int j=0; jssb_index[i] == cfra->resources.choice.ssb->ssb_ResourceList.list.array[j]->ssb) {
+ // one dedicated preamble for each beam
+ ra->preambles.preamble_list[i] =
+ cfra->resources.choice.ssb->ssb_ResourceList.list.array[j]->ra_PreambleIndex;
+ break;
+ }
+ }
+ }
}
}
LOG_I(PHY,"Added new RA process for UE RNTI %04x with initial secondaryCellGroup\n", rnti);
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
index d5dbbe5ddf..3c300c5f9d 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
@@ -52,6 +52,7 @@
#include "intertask_interface.h"
#include "executables/softmodem-common.h"
+#include "nfapi/oai_integration/vendor_ext.h"
uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 };
@@ -104,7 +105,7 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB,
gNB->pdu_index[CC_idP] = 0;
- if (nfapi_mode==0 || nfapi_mode == 1) { // monolithic or PNF
+ if (NFAPI_MODE == NFAPI_MONOLITHIC || NFAPI_MODE == NFAPI_MODE_PNF) { // monolithic or PNF
DL_req[CC_idP].SFN = frameP;
DL_req[CC_idP].Slot = slotP;
@@ -363,14 +364,22 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
/* send tick to RLC and RRC every ms */
if ((slot & ((1 << *scc->ssbSubcarrierSpacing) - 1)) == 0) {
void nr_rlc_tick(int frame, int subframe);
+ void nr_pdcp_tick(int frame, int subframe);
nr_rlc_tick(frame, slot >> *scc->ssbSubcarrierSpacing);
+ nr_pdcp_tick(frame, slot >> *scc->ssbSubcarrierSpacing);
nr_rrc_trigger(&ctxt, 0 /*CC_id*/, frame, slot >> *scc->ssbSubcarrierSpacing);
}
#define BIT(x) (1 << (x))
const uint64_t dlsch_in_slot_bitmap = BIT( 1) | BIT( 2) | BIT( 3) | BIT( 4) | BIT( 5) | BIT( 6)
| BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16);
- const uint64_t ulsch_in_slot_bitmap = BIT( 8) | BIT(18);
+
+ uint8_t prach_config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex;
+ uint64_t ulsch_in_slot_bitmap;
+ if (prach_config_index==4) //this is the PRACH config used in the Benetel RRU. TODO: make this generic for any PRACH config.
+ ulsch_in_slot_bitmap = BIT( 8) | BIT( 9);
+ else
+ ulsch_in_slot_bitmap = BIT( 8) | BIT(18);
memset(RC.nrmac[module_idP]->cce_list[bwp_id][0],0,MAX_NUM_CCE*sizeof(int)); // coreset0
memset(RC.nrmac[module_idP]->cce_list[bwp_id][1],0,MAX_NUM_CCE*sizeof(int)); // coresetid 1
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
index e45abf5203..82774cd2a6 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
@@ -151,6 +151,38 @@ void find_SSB_and_RO_available(module_id_t module_idP) {
uint8_t num_active_ssb = 0;
uint8_t max_association_period = 1;
+ struct NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB *ssb_perRACH_OccasionAndCB_PreamblesPerSSB = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB;
+
+ switch (ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present){
+ case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneEighth:
+ cc->cb_preambles_per_ssb = 4 * (ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneEighth + 1);
+ break;
+ case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneFourth:
+ cc->cb_preambles_per_ssb = 4 * (ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneFourth + 1);
+ break;
+ case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneHalf:
+ cc->cb_preambles_per_ssb = 4 * (ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneHalf + 1);
+ break;
+ case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_one:
+ cc->cb_preambles_per_ssb = 4 * (ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.one + 1);
+ break;
+ case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_two:
+ cc->cb_preambles_per_ssb = 4 * (ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.two + 1);
+ break;
+ case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_four:
+ cc->cb_preambles_per_ssb = ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.four;
+ break;
+ case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_eight:
+ cc->cb_preambles_per_ssb = ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.eight;
+ break;
+ case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_sixteen:
+ cc->cb_preambles_per_ssb = ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.sixteen;
+ break;
+ default:
+ AssertFatal(1 == 0, "Unsupported ssb_perRACH_config %d\n", ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present);
+ break;
+ }
+
if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing)
mu = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing;
else
@@ -181,25 +213,28 @@ void find_SSB_and_RO_available(module_id_t module_idP) {
}
}
- for(int i = 1; (1 << (i-1)) <= max_association_period;i++) {
+ cc->total_prach_occasions_per_config_period = total_RA_occasions;
+ for(int i=1; (1 << (i-1)) < max_association_period; i++) {
+ cc->max_association_period = (1 <<(i-1));
+ total_RA_occasions = total_RA_occasions * cc->max_association_period;
if(total_RA_occasions >= (int) (num_active_ssb/num_ssb_per_RO)) {
repetition = (uint16_t)((total_RA_occasions * num_ssb_per_RO )/num_active_ssb);
break;
}
- else {
- total_RA_occasions = total_RA_occasions * i;
- cc->max_association_period = i;
- }
}
- if(cc->max_association_period == 0)
- cc->max_association_period = 1;
unused_RA_occasion = total_RA_occasions - (int)((num_active_ssb * repetition)/num_ssb_per_RO);
cc->total_prach_occasions = total_RA_occasions - unused_RA_occasion;
cc->num_active_ssb = num_active_ssb;
- LOG_I(MAC, "Total available RO %d, num of active SSB %d: unused RO = %d max_association_period %u N_RA_sfn %u \n",
- cc->total_prach_occasions, cc->num_active_ssb, unused_RA_occasion, max_association_period, N_RA_sfn);
+ LOG_I(MAC,
+ "Total available RO %d, num of active SSB %d: unused RO = %d association_period %u N_RA_sfn %u total_prach_occasions_per_config_period %u\n",
+ cc->total_prach_occasions,
+ cc->num_active_ssb,
+ unused_RA_occasion,
+ cc->max_association_period,
+ N_RA_sfn,
+ cc->total_prach_occasions_per_config_period);
}
void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
@@ -210,7 +245,8 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP
nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[module_idP]->UL_tti_req_ahead[0][slotP];
nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0];
- if (is_nr_UL_slot(scc,slotP)) {
+ if (is_nr_UL_slot(scc, slotP, cc->frame_type)) {
+
uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex;
uint8_t mu,N_dur,N_t_slot,start_symbol = 0,N_RA_slot;
uint16_t RA_sfn_index = -1;
@@ -439,139 +475,167 @@ void nr_initiate_ra_proc(module_id_t module_idP,
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
- NR_RA_t *ra = &cc->ra[0];
- uint16_t ra_rnti;
+ uint8_t total_RApreambles = 64;
+ uint8_t num_ssb_per_RO = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present;
+ int pr_found;
- // ra_rnti from 5.1.3 in 38.321
- // FK: in case of long PRACH the phone seems to expect the subframe number instead of the slot number here.
- if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present==NR_RACH_ConfigCommon__prach_RootSequenceIndex_PR_l839)
- ra_rnti=1+symbol+(9/*slotP*/*14)+(freq_index*14*80)+(ul_carrier_id*14*80*8);
- else
- ra_rnti=1+symbol+(slotP*14)+(freq_index*14*80)+(ul_carrier_id*14*80*8);
-
-
- // if the preamble received correspond to one of the listed
- // the UE sent a RACH either for starting RA procedure or RA procedure failed and UE retries
- int pr_found=0;
- for (int i = 0; i < ra->preambles.num_preambles; i++) {
- if (preamble_index == ra->preambles.preamble_list[i]) {
- pr_found=1;
- break;
- }
+ if( scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL)
+ total_RApreambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles;
+
+ if(num_ssb_per_RO > 3) { /*num of ssb per RO >= 1*/
+ num_ssb_per_RO -= 3;
+ total_RApreambles = total_RApreambles/num_ssb_per_RO ;
}
- if (!pr_found) {
- LOG_E(MAC, "[gNB %d][RAPROC] FAILURE: preamble %d does not correspond to any of the ones in rach_ConfigDedicated\n",
- module_idP, preamble_index);
-
- return; // if the PRACH preamble does not correspond to any of the ones sent through RRC abort RA proc
- }
- // This should be handled differently when we use the initialBWP for RA
- ra->bwp_id=1;
- NR_BWP_Downlink_t *bwp=ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id-1];
-
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1);
-
- LOG_I(MAC, "[gNB %d][RAPROC] CC_id %d Frame %d, Slot %d Initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, slotP, preamble_index);
-
- if (ra->state == RA_IDLE) {
-
- uint8_t beam_index = ssb_index_from_prach(module_idP,
- frameP,
- slotP,
- preamble_index,
- freq_index,
- symbol);
- int loop = 0;
- LOG_D(MAC, "Frame %d, Slot %d: Activating RA process \n", frameP, slotP);
- ra->state = Msg2;
- ra->timing_offset = timing_offset;
- ra->preamble_slot = slotP;
-
- struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList;
- AssertFatal(commonSearchSpaceList->list.count>0,
- "common SearchSpace list has 0 elements\n");
- // Common searchspace list
- for (int i=0;ilist.count;i++) {
- ss=commonSearchSpaceList->list.array[i];
- if(ss->searchSpaceId == *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace)
- ra->ra_ss=ss;
- }
-
- // retrieving ra pdcch monitoring period and offset
- find_monitoring_periodicity_offset_common(ra->ra_ss,
- &monitoring_slot_period,
- &monitoring_offset);
-
- nr_schedule_msg2(frameP, slotP, &msg2_frame, &msg2_slot, scc, monitoring_slot_period, monitoring_offset,beam_index,cc->num_active_ssb);
-
- ra->Msg2_frame = msg2_frame;
- ra->Msg2_slot = msg2_slot;
-
- LOG_I(MAC, "%s() Msg2[%04d%d] SFN/SF:%04d%d\n", __FUNCTION__, ra->Msg2_frame, ra->Msg2_slot, frameP, slotP);
- if (!ra->cfra) {
- do {
- ra->rnti = (taus() % 65518) + 1;
- loop++;
+ for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
+ NR_RA_t *ra = &cc->ra[i];
+ pr_found = 0;
+ 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]) {
+ pr_found=1;
+ break;
+ }
}
- while (loop != 100 && !((find_nr_UE_id(module_idP, ra->rnti) == -1) && (find_nr_RA_id(module_idP, CC_id, ra->rnti) == -1) && ra->rnti >= 1 && ra->rnti <= 65519));
- if (loop == 100) {
- LOG_E(MAC,"%s:%d:%s: [RAPROC] initialisation random access aborted\n", __FILE__, __LINE__, __FUNCTION__);
- abort();
+
+ if (pr_found == 0) {
+ continue;
}
+
+ uint16_t ra_rnti;
+
+ // ra_rnti from 5.1.3 in 38.321
+ // FK: in case of long PRACH the phone seems to expect the subframe number instead of the slot number here.
+ if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present
+ == NR_RACH_ConfigCommon__prach_RootSequenceIndex_PR_l839)
+ ra_rnti = 1 + symbol + (9 /*slotP*/ * 14) + (freq_index * 14 * 80) + (ul_carrier_id * 14 * 80 * 8);
+ else
+ ra_rnti = 1 + symbol + (slotP * 14) + (freq_index * 14 * 80) + (ul_carrier_id * 14 * 80 * 8);
+
+ // This should be handled differently when we use the initialBWP for RA
+ ra->bwp_id = 1;
+ NR_BWP_Downlink_t *bwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList
+ ->list.array[ra->bwp_id - 1];
+
+ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1);
+
+ LOG_I(MAC,
+ "[gNB %d][RAPROC] CC_id %d Frame %d, Slot %d Initiating RA procedure for preamble index %d\n",
+ module_idP,
+ CC_id,
+ frameP,
+ slotP,
+ preamble_index);
+
+ uint8_t beam_index = ssb_index_from_prach(module_idP, frameP, slotP, preamble_index, freq_index, symbol);
+
+ // the UE sent a RACH either for starting RA procedure or RA procedure failed and UE retries
+ if (ra->cfra) {
+ // if the preamble received correspond to one of the listed
+ if (!(preamble_index == ra->preambles.preamble_list[beam_index])) {
+ LOG_E(
+ MAC,
+ "[gNB %d][RAPROC] FAILURE: preamble %d does not correspond to any of the ones in rach_ConfigDedicated\n",
+ module_idP,
+ preamble_index);
+ continue; // if the PRACH preamble does not correspond to any of the ones sent through RRC abort RA proc
+ }
+ }
+ int loop = 0;
+ LOG_D(MAC, "Frame %d, Slot %d: Activating RA process \n", frameP, slotP);
+ ra->state = Msg2;
+ ra->timing_offset = timing_offset;
+ ra->preamble_slot = slotP;
+
+ struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList =
+ bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList;
+ AssertFatal(commonSearchSpaceList->list.count > 0, "common SearchSpace list has 0 elements\n");
+ // Common searchspace list
+ for (int i = 0; i < commonSearchSpaceList->list.count; i++) {
+ ss = commonSearchSpaceList->list.array[i];
+ if (ss->searchSpaceId == *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace)
+ ra->ra_ss = ss;
+ }
+
+ // retrieving ra pdcch monitoring period and offset
+ find_monitoring_periodicity_offset_common(ra->ra_ss, &monitoring_slot_period, &monitoring_offset);
+
+ nr_schedule_msg2(frameP,
+ slotP,
+ &msg2_frame,
+ &msg2_slot,
+ scc,
+ monitoring_slot_period,
+ monitoring_offset,
+ beam_index,
+ cc->num_active_ssb);
+
+ ra->Msg2_frame = msg2_frame;
+ ra->Msg2_slot = msg2_slot;
+
+ LOG_I(MAC, "%s() Msg2[%04d%d] SFN/SF:%04d%d\n", __FUNCTION__, ra->Msg2_frame, ra->Msg2_slot, frameP, slotP);
+ if (!ra->cfra) {
+ do {
+ ra->rnti = (taus() % 65518) + 1;
+ loop++;
+ } while (loop != 100
+ && !((find_nr_UE_id(module_idP, ra->rnti) == -1) && (find_nr_RA_id(module_idP, CC_id, ra->rnti) == -1)
+ && ra->rnti >= 1 && ra->rnti <= 65519));
+ if (loop == 100) {
+ LOG_E(MAC, "%s:%d:%s: [RAPROC] initialisation random access aborted\n", __FILE__, __LINE__, __FUNCTION__);
+ abort();
+ }
+ }
+ ra->RA_rnti = ra_rnti;
+ ra->preamble_index = preamble_index;
+ ra->beam_id = beam_index;
+
+ LOG_I(MAC,
+ "[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x SSB "
+ "index %u\n",
+ module_idP,
+ CC_id,
+ frameP,
+ ra->Msg2_frame,
+ ra->Msg2_slot,
+ ra->RA_rnti,
+ cc->ssb_index[beam_index]);
+
+ return;
}
- ra->RA_rnti = ra_rnti;
- ra->preamble_index = preamble_index;
- ra->beam_id = beam_index;
-
- LOG_I(MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x SSB index %u\n",
- module_idP,
- CC_id,
- frameP,
- ra->Msg2_frame,
- ra->Msg2_slot,
- ra->RA_rnti,
- cc->ssb_index[beam_index]);
-
- return;
}
LOG_E(MAC, "[gNB %d][RAPROC] FAILURE: CC_id %d Frame %d initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, preamble_index);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0);
}
-void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){
-
- //uint8_t i = 0;
- int CC_id = 0;
+void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
+{
gNB_MAC_INST *mac = RC.nrmac[module_idP];
- NR_COMMON_channels_t *cc = &mac->common_channels[CC_id];
start_meas(&mac->schedule_ra);
-
-// for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
-// for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
-
-// NR_RA_t *ra = &cc->ra[i];
- NR_RA_t *ra = &cc->ra[0];
-
- LOG_D(MAC,"RA[state:%d]\n",ra->state);
- switch (ra->state){
- case Msg2:
- nr_generate_Msg2(module_idP, CC_id, frameP, slotP);
- break;
- case Msg4:
- //generate_Msg4(module_idP, CC_id, frameP, slotP);
- break;
- case WAIT_Msg4_ACK:
- //check_Msg4_retransmission(module_idP, CC_id, frameP, slotP);
- break;
- default:
- break;
+ for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+ NR_COMMON_channels_t *cc = &mac->common_channels[CC_id];
+ for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
+ NR_RA_t *ra = &cc->ra[i];
+ LOG_D(MAC, "RA[state:%d]\n", ra->state);
+ switch (ra->state) {
+ case Msg2:
+ nr_generate_Msg2(module_idP, CC_id, frameP, slotP, ra);
+ break;
+ case Msg4:
+ // generate_Msg4(module_idP, CC_id, frameP, slotP);
+ break;
+ case WAIT_Msg4_ACK:
+ // check_Msg4_retransmission(module_idP, CC_id, frameP, slotP);
+ break;
+ default:
+ break;
+ }
+ }
}
-// }
-// }
stop_meas(&mac->schedule_ra);
}
@@ -584,7 +648,8 @@ void nr_get_Msg3alloc(module_id_t module_id,
NR_RA_t *ra) {
// msg3 is schedulend in mixed slot in the following TDD period
- // for now we consider a TBS of 18 bytes
+
+ uint16_t msg3_nb_rb = 8 + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); // sdu has 6 or 8 bytes
int mu = ubwp->bwp_Common->genericParameters.subcarrierSpacing;
int StartSymbolIndex, NrOfSymbols, startSymbolAndLength, temp_slot;
@@ -614,30 +679,30 @@ void nr_get_Msg3alloc(module_id_t module_id,
uint16_t *vrb_map_UL =
&RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[ra->Msg3_slot * MAX_BWP_SIZE];
const uint16_t bwpSize = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE);
- /* search 18 free RBs */
+
+ /* search msg3_nb_rb free RBs */
int rbSize = 0;
int rbStart = 0;
- while (rbSize < 18) {
+ while (rbSize < msg3_nb_rb) {
rbStart += rbSize; /* last iteration rbSize was not enough, skip it */
rbSize = 0;
while (rbStart < bwpSize && vrb_map_UL[rbStart])
rbStart++;
- AssertFatal(rbStart < bwpSize - 18, "no space to allocate Msg 3 for RA!\n");
+ AssertFatal(rbStart < bwpSize - msg3_nb_rb, "no space to allocate Msg 3 for RA!\n");
while (rbStart + rbSize < bwpSize
&& !vrb_map_UL[rbStart + rbSize]
- && rbSize < 18)
+ && rbSize < msg3_nb_rb)
rbSize++;
}
- ra->msg3_nb_rb = 18;
+ ra->msg3_nb_rb = msg3_nb_rb;
ra->msg3_first_rb = rbStart;
}
-void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP){
-
+void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra, uint8_t *RAR_pdu)
+{
gNB_MAC_INST *mac = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = &mac->common_channels[CC_id];
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
- NR_RA_t *ra = &cc->ra[0];
if (ra->state == RA_IDLE) {
LOG_W(MAC,"RA is not active for RA %X. skipping msg3 scheduling\n", ra->rnti);
@@ -752,27 +817,25 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
pusch_pdu->nrOfLayers = 1)>>3;
// calling function to fill rar message
- nr_fill_rar(module_idP, ra, cc->RAR_pdu.payload, pusch_pdu);
-
+ nr_fill_rar(module_idP, ra, RAR_pdu, pusch_pdu);
}
-// WIP
-// todo:
-// - fix me
-// - get msg3 alloc (see nr_process_rar)
-void nr_generate_Msg2(module_id_t module_idP,
- int CC_id,
- frame_t frameP,
- sub_frame_t slotP)
+void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra)
{
-
int mcsIndex;
int startSymbolAndLength = 0, StartSymbolIndex = -1, NrOfSymbols = 14, StartSymbolIndex_tmp, NrOfSymbols_tmp, x_Overhead, time_domain_assignment = 0;
gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
- NR_RA_t *ra = &cc->ra[CC_id];
NR_SearchSpace_t *ss = ra->ra_ss;
+ // This code from this point on will not work on initialBWP or CORESET0
+ AssertFatal(ra->bwp_id > 0, "cannot work on initialBWP for now\n");
+
+ AssertFatal(ra->secondaryCellGroup, "no secondaryCellGroup for RNTI %04x\n", ra->crnti);
+ AssertFatal(ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
+ "downlinkBWP_ToAddModList has %d BWP!\n",
+ ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
+
uint16_t RA_rnti = ra->RA_rnti;
long locationAndBandwidth;
@@ -780,7 +843,7 @@ void nr_generate_Msg2(module_id_t module_idP,
// get the BW of the PDCCH for PDCCH size and RAR PDSCH size
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
- int dci10_bw;
+ int dci10_bw = 0;
if (ra->coreset0_configured == 1) {
AssertFatal(1==0,"This is a standalone condition\n");
@@ -792,8 +855,24 @@ void nr_generate_Msg2(module_id_t module_idP,
if ((ra->Msg2_frame == frameP) && (ra->Msg2_slot == slotP)) {
+ uint16_t *vrb_map = cc[CC_id].vrb_map;
+ int rbStart = 0, rbSize = 6;
+ for (int i = 0; (i < rbSize) && (rbStart <= (dci10_bw - rbSize)); i++) {
+ if (vrb_map[rbStart + i]) {
+ rbStart += i;
+ i = 0;
+ }
+ }
+ if (rbStart > (dci10_bw - rbSize)) {
+ LOG_E(MAC, "%s(): cannot find free vrb_map for RA RNTI %04x!\n", __func__, ra->RA_rnti);
+ return;
+ }
+
nfapi_nr_dl_tti_request_body_t *dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body;
- // Checking if the DCI allocation is feasible in current subframe
+ // Checking if the DCI allocation is feasible in current subframe: we might
+ // need to need up to two (PDCCH + PDSCH) messages, so check that we can
+ // always allocate both (this might be an overestimation, since the PDCCH
+ // message might already exist)
if (dl_req->nPDUs > NFAPI_NR_MAX_DL_TTI_PDUS - 2) {
LOG_I(MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, RA_rnti);
return;
@@ -816,8 +895,6 @@ void nr_generate_Msg2(module_id_t module_idP,
return;
}
- nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs];
-
/* look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not
* exist, create it. This is especially important if we have multiple RAs,
* and the DLSCH has to reuse them, so we need to mark them */
@@ -844,14 +921,6 @@ void nr_generate_Msg2(module_id_t module_idP,
LOG_I(MAC,"[gNB %d] [RAPROC] CC_id %d Frame %d, slotP %d: Generating RAR DCI, state %d\n", module_idP, CC_id, frameP, slotP, ra->state);
- // This code from this point on will not work on initialBWP or CORESET0
- AssertFatal(ra->bwp_id>0,"cannot work on initialBWP for now\n");
-
- AssertFatal(ra->secondaryCellGroup,
- "no secondaryCellGroup for RNTI %04x\n",
- ra->crnti);
- AssertFatal(ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
- "downlinkBWP_ToAddModList has %d BWP!\n", ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
NR_BWP_Uplink_t *ubwp=ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1];
LOG_I(MAC, "[RAPROC] Scheduling common search space DCI type 1 dlBWP BW %d\n", dci10_bw);
@@ -898,8 +967,8 @@ void nr_generate_Msg2(module_id_t module_idP,
pdsch_pdu_rel15->numDmrsCdmGrpsNoData = 2;
pdsch_pdu_rel15->dmrsPorts = 1;
pdsch_pdu_rel15->resourceAlloc = 1;
- pdsch_pdu_rel15->rbStart = 0;
- pdsch_pdu_rel15->rbSize = 6;
+ pdsch_pdu_rel15->rbStart = rbStart;
+ pdsch_pdu_rel15->rbSize = rbSize;
pdsch_pdu_rel15->VRBtoPRBMapping = 0; // non interleaved
for (int i=0; ibwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count; i++) {
@@ -974,17 +1043,8 @@ void nr_generate_Msg2(module_id_t module_idP,
dci10_bw,
ra->bwp_id);
- // Program UL processing for Msg3
- nr_get_Msg3alloc(module_idP, CC_id, scc, ubwp, slotP, frameP, ra);
- LOG_I(MAC, "Frame %d, Subframe %d: Setting Msg3 reception for Frame %d Subframe %d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot);
- nr_add_msg3(module_idP, CC_id, frameP, slotP);
- ra->state = WAIT_Msg3;
- LOG_I(MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: RA state %d\n", module_idP, frameP, slotP, ra->state);
-
- x_Overhead = 0;
- nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead, pdsch_pdu_rel15->numDmrsCdmGrpsNoData, dci_payload.tb_scaling);
-
// DL TX request
+ nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs];
tx_req->PDU_length = pdsch_pdu_rel15->TBSize[0];
tx_req->PDU_index = pduindex;
tx_req->num_TLV = 1;
@@ -992,16 +1052,24 @@ void nr_generate_Msg2(module_id_t module_idP,
nr_mac->TX_req[CC_id].SFN = frameP;
nr_mac->TX_req[CC_id].Number_of_PDUs++;
nr_mac->TX_req[CC_id].Slot = slotP;
- memcpy((void*)&tx_req->TLVs[0].value.direct[0], (void*)&cc[CC_id].RAR_pdu.payload[0], tx_req->TLVs[0].length);
+
+ // Program UL processing for Msg3
+ nr_get_Msg3alloc(module_idP, CC_id, scc, ubwp, slotP, frameP, ra);
+ LOG_I(MAC, "Frame %d, Subframe %d: Setting Msg3 reception for Frame %d Subframe %d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot);
+ nr_add_msg3(module_idP, CC_id, frameP, slotP, ra, (uint8_t *) &tx_req->TLVs[0].value.direct[0]);
+ ra->state = WAIT_Msg3;
+ LOG_I(MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: RA state %d\n", module_idP, frameP, slotP, ra->state);
+
+ x_Overhead = 0;
+ nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead, pdsch_pdu_rel15->numDmrsCdmGrpsNoData, dci_payload.tb_scaling);
T(T_GNB_MAC_DL_RAR_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id),
T_INT(RA_rnti), T_INT(frameP), T_INT(slotP), T_INT(0) /* harq pid, meaningful? */,
- T_BUFFER(&cc[CC_id].RAR_pdu.payload[0], tx_req->TLVs[0].length));
+ T_BUFFER(&tx_req->TLVs[0].value.direct[0], tx_req->TLVs[0].length));
/* mark the corresponding RBs as used */
- uint16_t *vrb_map = cc[CC_id].vrb_map;
- for (int rb = 0; rb < pdsch_pdu_rel15->rbSize; rb++)
- vrb_map[rb + pdsch_pdu_rel15->rbStart] = 1;
+ for (int rb = 0; rb < rbSize; rb++)
+ vrb_map[rb + rbStart] = 1;
}
}
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
index 1de46aaea4..3f69cfbe74 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
@@ -235,6 +235,7 @@ void schedule_control_sib1(module_id_t module_id,
int time_domain_allocation,
uint8_t mcsTableIdx,
uint8_t mcs,
+ uint8_t candidate_idx,
int num_total_bytes) {
gNB_MAC_INST *gNB_mac = RC.nrmac[module_id];
@@ -266,13 +267,10 @@ void schedule_control_sib1(module_id_t module_id,
gNB_mac->sched_ctrlCommon->coreset,
gNB_mac->sched_ctrlCommon->aggregation_level,
0,
- 0,
+ candidate_idx,
nr_of_candidates);
- if (gNB_mac->sched_ctrlCommon->cce_index < 0) {
- LOG_E(MAC, "%s(): could not find CCE for coreset0\n", __func__);
- return;
- }
+ AssertFatal(gNB_mac->sched_ctrlCommon->cce_index >= 0, "Could not find CCE for coreset0\n");
const uint16_t bwpSize = gNB_mac->type0_PDCCH_CSS_config.num_rbs;
int rbStart = gNB_mac->type0_PDCCH_CSS_config.cset_start_rb;
@@ -301,9 +299,7 @@ void schedule_control_sib1(module_id_t module_id,
TBS = nr_compute_tbs(nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx),
nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx),
rbSize, nrOfSymbols, N_PRB_DMRS * dmrs_length,0, 0,1) >> 3;
-
- // FIXME: Something is not working in nr_modulation() for TBS = 84, so we need to skip it
- } while ( (rbStart + rbSize < bwpSize && !vrb_map[rbStart + rbSize] && TBS < gNB_mac->sched_ctrlCommon->num_total_bytes) || (TBS==84) );
+ } while (rbStart + rbSize < bwpSize && !vrb_map[rbStart + rbSize] && TBS < gNB_mac->sched_ctrlCommon->num_total_bytes);
gNB_mac->sched_ctrlCommon->rbSize = rbSize;
gNB_mac->sched_ctrlCommon->rbStart = 0;
@@ -467,6 +463,7 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
int time_domain_allocation = 0;
uint8_t mcsTableIdx = 0;
uint8_t mcs = 6;
+ uint8_t candidate_idx = 0;
gNB_MAC_INST *gNB_mac = RC.nrmac[module_idP];
@@ -482,7 +479,7 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
for (int i=0;iphy_test || get_softmodem_params()->do_ra) {
+ else if (get_softmodem_params()->phy_test || get_softmodem_params()->do_ra || get_softmodem_params()->sa) {
/* we will need the large header, phy-test typically allocates all
* resources and fills to the last byte below */
NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) buf;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
index 8dbe8728f3..6487f391b9 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
@@ -103,7 +103,7 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE;
dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu));
- dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs+1];
+ dl_tti_pdsch_pdu = &nr_mac->DL_req[CC_id].dl_tti_request_body.dl_tti_pdu_list[nr_mac->DL_req[CC_id].dl_tti_request_body.nPDUs+1];
memset((void *)dl_tti_pdsch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
dl_tti_pdsch_pdu->PDUType = NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE;
dl_tti_pdsch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdsch_pdu));
@@ -238,14 +238,16 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
pdsch_pdu_rel15->mcsIndex[0]);
*/
- dl_req->nPDUs+=2;
+ nr_mac->DL_req[CC_id].dl_tti_request_body.nPDUs+=2;
TX_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs];
TX_req->PDU_length = 6;
TX_req->PDU_index = nr_mac->pdu_index[CC_id]++;
TX_req->num_TLV = 1;
TX_req->TLVs[0].length = 8;
- memcpy((void*)&TX_req->TLVs[0].value.direct[0],(void*)&cc[CC_id].RAR_pdu.payload[0],TX_req->TLVs[0].length);
+ // why do we copy from RAR_pdu here? Shouldn't we fill some more or less
+ // meaningful data, e.g., padding + random data?
+ //memcpy((void *)&TX_req->TLVs[0].value.direct[0], (void *)&cc[CC_id].RAR_pdu[0].payload[0], TX_req->TLVs[0].length);
nr_mac->TX_req[CC_id].Number_of_PDUs++;
nr_mac->TX_req[CC_id].SFN=frameP;
nr_mac->TX_req[CC_id].Slot=slotP;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
index f0a20d8e6f..629b4dc7b0 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
@@ -31,6 +31,7 @@
#include "NR_MAC_COMMON/nr_mac_extern.h"
#include "NR_MAC_gNB/mac_proto.h"
#include "common/ran_context.h"
+#include "nfapi/oai_integration/vendor_ext.h"
extern RAN_CONTEXT_t RC;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
index 95aa2e2292..25a419af16 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
@@ -395,7 +395,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
T_BUFFER(sduP, sdu_lenP));
UE_info->mac_stats[UE_id].ulsch_total_bytes_rx += sdu_lenP;
- LOG_D(MAC, "[gNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu from PHY (rnti %x, UE_id %d) ul_cqi %d\n",
+ LOG_D(NR_MAC, "[gNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu from PHY (rnti %x, UE_id %d) ul_cqi %d sduP %p\n",
gnb_mod_idP,
harq_pid,
CC_idP,
@@ -403,7 +403,8 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
slotP,
current_rnti,
UE_id,
- ul_cqi);
+ ul_cqi,
+ sduP);
// if not missed detection (10dB threshold for now)
if (UE_scheduling_control->ul_rssi < (100+rssi)) {
@@ -411,7 +412,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
if (timing_advance != 0xffff)
UE_scheduling_control->ta_update = timing_advance;
UE_scheduling_control->ul_rssi = rssi;
- LOG_D(MAC, "[UE %d] PUSCH TPC %d and TA %d\n",UE_id,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update);
+ LOG_D(NR_MAC, "[UE %d] PUSCH TPC %d and TA %d\n",UE_id,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update);
}
else{
UE_scheduling_control->tpc0 = 1;
@@ -430,9 +431,10 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
#endif
if (sduP != NULL){
- LOG_D(MAC, "Received PDU at MAC gNB \n");
+ LOG_D(NR_MAC, "Received PDU at MAC gNB \n");
- UE_scheduling_control->sched_ul_bytes -= UE_info->mac_stats[UE_id].ulsch_current_bytes;
+ const uint32_t tb_size = UE_scheduling_control->ul_harq_processes[harq_pid].sched_pusch.tb_size;
+ UE_scheduling_control->sched_ul_bytes -= tb_size;
if (UE_scheduling_control->sched_ul_bytes < 0)
UE_scheduling_control->sched_ul_bytes = 0;
@@ -442,7 +444,8 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
NR_UE_ul_harq_t *cur_harq = &UE_scheduling_control->ul_harq_processes[harq_pid];
/* reduce sched_ul_bytes when cur_harq->round == 3 */
if (cur_harq->round == 3){
- UE_scheduling_control->sched_ul_bytes -= UE_info->mac_stats[UE_id].ulsch_current_bytes;
+ const uint32_t tb_size = UE_scheduling_control->ul_harq_processes[harq_pid].sched_pusch.tb_size;
+ UE_scheduling_control->sched_ul_bytes -= tb_size;
if (UE_scheduling_control->sched_ul_bytes < 0)
UE_scheduling_control->sched_ul_bytes = 0;
}
@@ -465,7 +468,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
// random access pusch with TC-RNTI
if (ra->rnti != current_rnti) {
- LOG_W(MAC,
+ LOG_W(NR_MAC,
"expected TC-RNTI %04x to match current RNTI %04x\n",
ra->rnti,
current_rnti);
@@ -473,19 +476,25 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
}
const int UE_id = add_new_nr_ue(gnb_mod_idP, ra->rnti, ra->secondaryCellGroup);
UE_info->UE_beam_index[UE_id] = ra->beam_id;
- LOG_I(MAC,
+ LOG_I(NR_MAC,
"[gNB %d][RAPROC] PUSCH with TC_RNTI %x received correctly, "
"adding UE MAC Context UE_id %d/RNTI %04x\n",
gnb_mod_idP,
current_rnti,
UE_id,
ra->rnti);
+
+ 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]);
+ }
+
// re-initialize ta update variables afrer RA procedure completion
UE_info->UE_sched_ctrl[UE_id].ta_frame = frameP;
free(ra->preambles.preamble_list);
ra->state = RA_IDLE;
- LOG_I(MAC,
+ LOG_I(NR_MAC,
"reset RA state information for RA-RNTI %04x/index %d\n",
ra->rnti,
i);
@@ -862,7 +871,7 @@ void nr_schedule_ulsch(module_id_t module_id,
/* a PDCCH PDU groups DCIs per BWP and CORESET. Save a pointer to each
* allocated PDCCH so we can easily allocate UE's DCIs independent of any
* CORESET order */
- nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_bwp_coreset[MAX_NUM_BWP][MAX_NUM_CORESET] = {0};
+ nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_bwp_coreset[MAX_NUM_BWP][MAX_NUM_CORESET] = {{0}};
NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon;
NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
@@ -916,6 +925,7 @@ void nr_schedule_ulsch(module_id_t module_id,
/* Save information on MCS, TBS etc for the current initial transmission
* so we have access to it when retransmitting */
cur_harq->sched_pusch = *sched_pusch;
+ sched_ctrl->sched_ul_bytes += sched_pusch->tb_size;
} else {
LOG_D(MAC,
"%d.%2d UL retransmission RNTI %04x sched %d.%2d HARQ PID %d round %d NDI %d\n",
@@ -929,7 +939,6 @@ void nr_schedule_ulsch(module_id_t module_id,
cur_harq->ndi);
}
UE_info->mac_stats[UE_id].ulsch_current_bytes = sched_pusch->tb_size;
- sched_ctrl->sched_ul_bytes += sched_pusch->tb_size;
LOG_D(MAC,
"%4d.%2d RNTI %04x UL sched %4d.%2d start %d RBS %d MCS %d TBS %d HARQ PID %d round %d NDI %d\n",
@@ -1130,4 +1139,4 @@ void nr_schedule_ulsch(module_id_t module_id,
memset(sched_pusch, 0, sizeof(*sched_pusch));
}
-}
+}
\ No newline at end of file
diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
index 8e4e18b534..f18bede58b 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
@@ -75,6 +75,7 @@ void schedule_control_sib1(module_id_t module_id,
int time_domain_allocation,
uint8_t mcsTableIdx,
uint8_t mcs,
+ uint8_t candidate_idx,
int num_total_bytes);
void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP);
@@ -348,11 +349,7 @@ void config_nr_mib(int Mod_idP,
int cellBarred,
int intraFreqReselection);
-
-void nr_generate_Msg2(module_id_t module_idP,
- int CC_id,
- frame_t frameP,
- sub_frame_t slotP);
+void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra);
void nr_process_mac_pdu(
module_id_t module_idP,
diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c
index 8dc1303801..33e575d2b9 100644
--- a/openair2/LAYER2/NR_MAC_gNB/main.c
+++ b/openair2/LAYER2/NR_MAC_gNB/main.c
@@ -96,7 +96,7 @@ void mac_top_init_gNB(void)
// These should be out of here later
pdcp_layer_init();
- if(IS_SOFTMODEM_NOS1 && !get_softmodem_params()->do_ra)
+ if(IS_SOFTMODEM_NOS1 && !(get_softmodem_params()->do_ra || get_softmodem_params()->sa) )
nr_DRB_preconfiguration(0x1234);
rrc_init_nr_global_param();
diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
index bca974a00f..63587d58a4 100644
--- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
+++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
@@ -194,8 +194,6 @@ typedef struct {
uint32_t PCCH_alloc_pdu;
/// Outgoing PCCH pdu for PHY
PCCH_PDU PCCH_pdu;
- /// Outgoing RAR pdu for PHY
- RAR_PDU RAR_pdu;
/// Template for RA computations
NR_RA_t ra[NR_NB_RA_PROC_MAX];
/// VRB map for common channels
@@ -215,6 +213,8 @@ typedef struct {
uint8_t max_association_period;
//SSB index
uint8_t ssb_index[MAX_NUM_OF_SSB];
+ //CB preambles for each SSB
+ uint8_t cb_preambles_per_ssb;
} NR_COMMON_channels_t;
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
index 8196d2b1fc..ee2711c6ef 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
@@ -2098,8 +2098,7 @@ pdcp_config_set_security(
}
//-----------------------------------------------------------------------------
-void
-rrc_pdcp_config_req (
+void rrc_pdcp_config_req (
const protocol_ctxt_t *const ctxt_pP,
const srb_flag_t srb_flagP,
const uint32_t actionP,
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c
index f3d4b16130..eda6888ecd 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c
@@ -21,24 +21,223 @@
#include "nr_pdcp_entity.h"
-#include "nr_pdcp_entity_drb_am.h"
+#include
+#include
+#include
+
+#include "nr_pdcp_security_nea2.h"
+#include "nr_pdcp_sdu.h"
#include "LOG/log.h"
-nr_pdcp_entity_t *new_nr_pdcp_entity_srb(
- int rb_id,
- void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
- char *buf, int size),
- void *deliver_sdu_data,
- void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity,
- char *buf, int size, int sdu_id),
- void *deliver_pdu_data)
+static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
+ char *_buffer, int size)
{
- abort();
+ unsigned char *buffer = (unsigned char *)_buffer;
+ nr_pdcp_sdu_t *sdu;
+ int rcvd_sn;
+ uint32_t rcvd_hfn;
+ uint32_t rcvd_count;
+ int header_size;
+ int integrity_size;
+ int rx_deliv_sn;
+ uint32_t rx_deliv_hfn;
+
+ if (size < 1) {
+ LOG_E(PDCP, "bad PDU received (size = %d)\n", size);
+ return;
+ }
+
+ if (!(buffer[0] & 0x80)) {
+ LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
+ exit(1);
+ }
+
+ if (entity->sn_size == 12) {
+ rcvd_sn = (((unsigned char)buffer[0] & 0xf) << 8) |
+ (unsigned char)buffer[1];
+ header_size = 2;
+ } else {
+ rcvd_sn = (((unsigned char)buffer[0] & 0x3) << 16) |
+ ((unsigned char)buffer[1] << 8) |
+ (unsigned char)buffer[2];
+ header_size = 3;
+ }
+
+ integrity_size = 0;
+
+ if (size < header_size + integrity_size + 1) {
+ LOG_E(PDCP, "bad PDU received (size = %d)\n", size);
+ return;
+ }
+
+ rx_deliv_sn = entity->rx_deliv & entity->sn_max;
+ rx_deliv_hfn = (entity->rx_deliv >> entity->sn_size) & ~entity->sn_max;
+
+ if (rcvd_sn < rx_deliv_sn - entity->window_size) {
+ rcvd_hfn = rx_deliv_hfn + 1;
+ } else if (rcvd_sn >= rx_deliv_sn + entity->window_size) {
+ rcvd_hfn = rx_deliv_hfn - 1;
+ } else {
+ rcvd_hfn = rx_deliv_hfn;
+ }
+
+ rcvd_count = (rcvd_hfn << entity->sn_size) | rcvd_sn;
+
+ if (entity->has_ciphering)
+ entity->cipher(entity->security_context,
+ (unsigned char *)buffer+header_size, size-header_size,
+ entity->rb_id, rcvd_count, entity->is_gnb ? 0 : 1);
+
+ if (rcvd_count < entity->rx_deliv
+ || nr_pdcp_sdu_in_list(entity->rx_list, rcvd_count)) {
+ LOG_D(PDCP, "discard NR PDU rcvd_count=%d\n", rcvd_count);
+ return;
+ }
+
+ sdu = nr_pdcp_new_sdu(rcvd_count,
+ (char *)buffer + header_size,
+ size - header_size - integrity_size);
+ entity->rx_list = nr_pdcp_sdu_list_add(entity->rx_list, sdu);
+ entity->rx_size += size-header_size;
+
+ if (rcvd_count >= entity->rx_next) {
+ entity->rx_next = rcvd_count + 1;
+ }
+
+ /* TODO(?): out of order delivery */
+
+ if (rcvd_count == entity->rx_deliv) {
+ /* deliver all SDUs starting from rx_deliv up to discontinuity or end of list */
+ uint32_t count = entity->rx_deliv;
+ while (entity->rx_list != NULL && count == entity->rx_list->count) {
+ nr_pdcp_sdu_t *cur = entity->rx_list;
+ entity->deliver_sdu(entity->deliver_sdu_data, entity,
+ cur->buffer, cur->size);
+ entity->rx_list = cur->next;
+ entity->rx_size -= cur->size;
+ nr_pdcp_free_sdu(cur);
+ count++;
+ }
+ entity->rx_deliv = count;
+ }
+
+ if (entity->t_reordering_start != 0 && entity->rx_deliv > entity->rx_reord) {
+ /* stop and reset t-Reordering */
+ entity->t_reordering_start = 0;
+ }
+
+ if (entity->t_reordering_start == 0 && entity->rx_deliv < entity->rx_next) {
+ entity->rx_reord = entity->rx_next;
+ entity->t_reordering_start = entity->t_current;
+ }
}
-nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am(
- int rb_id,
+static void nr_pdcp_entity_recv_sdu(nr_pdcp_entity_t *entity,
+ char *buffer, int size, int sdu_id)
+{
+ uint32_t count;
+ int sn;
+ int header_size;
+ char buf[size+3+4];
+
+ count = entity->tx_next;
+ sn = entity->tx_next & entity->sn_max;
+
+ if (entity->sn_size == 12) {
+ buf[0] = 0x80 | ((sn >> 8) & 0xf);
+ buf[1] = sn & 0xff;
+ header_size = 2;
+ } else {
+ buf[0] = 0x80 | ((sn >> 16) & 0x3);
+ buf[1] = (sn >> 8) & 0xff;
+ buf[2] = sn & 0xff;
+ header_size = 3;
+ }
+
+ memcpy(buf+header_size, buffer, size);
+
+ if (entity->has_ciphering)
+ entity->cipher(entity->security_context,
+ (unsigned char *)buf+header_size, size,
+ entity->rb_id, count, entity->is_gnb ? 1 : 0);
+
+ entity->tx_next++;
+
+ entity->deliver_pdu(entity->deliver_pdu_data, entity, buf,
+ size+header_size, sdu_id);
+}
+
+static void nr_pdcp_entity_set_integrity_key(nr_pdcp_entity_t *entity,
+ char *key)
+{
+ memcpy(entity->integrity_key, key, 16);
+}
+
+static void check_t_reordering(nr_pdcp_entity_t *entity)
+{
+ uint32_t count;
+
+ if (entity->t_reordering_start == 0
+ || entity->t_current <= entity->t_reordering_start + entity->t_reordering)
+ return;
+
+ /* stop timer */
+ entity->t_reordering_start = 0;
+
+ /* deliver all SDUs with count < rx_reord */
+ while (entity->rx_list != NULL && entity->rx_list->count < entity->rx_reord) {
+ nr_pdcp_sdu_t *cur = entity->rx_list;
+ entity->deliver_sdu(entity->deliver_sdu_data, entity,
+ cur->buffer, cur->size);
+ entity->rx_list = cur->next;
+ entity->rx_size -= cur->size;
+ nr_pdcp_free_sdu(cur);
+ }
+
+ /* deliver all SDUs starting from rx_reord up to discontinuity or end of list */
+ count = entity->rx_reord;
+ while (entity->rx_list != NULL && count == entity->rx_list->count) {
+ nr_pdcp_sdu_t *cur = entity->rx_list;
+ entity->deliver_sdu(entity->deliver_sdu_data, entity,
+ cur->buffer, cur->size);
+ entity->rx_list = cur->next;
+ entity->rx_size -= cur->size;
+ nr_pdcp_free_sdu(cur);
+ count++;
+ }
+
+ entity->rx_deliv = count;
+
+ if (entity->rx_deliv < entity->rx_next) {
+ entity->rx_reord = entity->rx_next;
+ entity->t_reordering_start = entity->t_current;
+ }
+}
+
+void nr_pdcp_entity_set_time(struct nr_pdcp_entity_t *entity, uint64_t now)
+{
+ entity->t_current = now;
+
+ check_t_reordering(entity);
+}
+
+void nr_pdcp_entity_delete(nr_pdcp_entity_t *entity)
+{
+ nr_pdcp_sdu_t *cur = entity->rx_list;
+ while (cur != NULL) {
+ nr_pdcp_sdu_t *next = cur->next;
+ nr_pdcp_free_sdu(cur);
+ cur = next;
+ }
+ if (entity->free_security != NULL)
+ entity->free_security(entity->security_context);
+ free(entity);
+}
+
+nr_pdcp_entity_t *new_nr_pdcp_entity(
+ nr_pdcp_entity_type_t type,
+ int is_gnb, int rb_id,
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
char *buf, int size),
void *deliver_sdu_data,
@@ -47,34 +246,62 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am(
void *deliver_pdu_data,
int sn_size,
int t_reordering,
- int discard_timer)
+ int discard_timer,
+ int ciphering_algorithm,
+ int integrity_algorithm,
+ unsigned char *ciphering_key,
+ unsigned char *integrity_key)
{
- nr_pdcp_entity_drb_am_t *ret;
+ nr_pdcp_entity_t *ret;
- ret = calloc(1, sizeof(nr_pdcp_entity_drb_am_t));
+ ret = calloc(1, sizeof(nr_pdcp_entity_t));
if (ret == NULL) {
LOG_E(PDCP, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
- ret->common.recv_pdu = nr_pdcp_entity_drb_am_recv_pdu;
- ret->common.recv_sdu = nr_pdcp_entity_drb_am_recv_sdu;
- ret->common.set_integrity_key = nr_pdcp_entity_drb_am_set_integrity_key;
+ ret->type = type;
- ret->common.delete = nr_pdcp_entity_drb_am_delete;
+ ret->recv_pdu = nr_pdcp_entity_recv_pdu;
+ ret->recv_sdu = nr_pdcp_entity_recv_sdu;
+ ret->set_integrity_key = nr_pdcp_entity_set_integrity_key;
+ ret->set_time = nr_pdcp_entity_set_time;
- ret->common.deliver_sdu = deliver_sdu;
- ret->common.deliver_sdu_data = deliver_sdu_data;
+ ret->delete = nr_pdcp_entity_delete;
- ret->common.deliver_pdu = deliver_pdu;
- ret->common.deliver_pdu_data = deliver_pdu_data;
+ ret->deliver_sdu = deliver_sdu;
+ ret->deliver_sdu_data = deliver_sdu_data;
+
+ ret->deliver_pdu = deliver_pdu;
+ ret->deliver_pdu_data = deliver_pdu_data;
ret->rb_id = rb_id;
ret->sn_size = sn_size;
ret->t_reordering = t_reordering;
ret->discard_timer = discard_timer;
- ret->common.maximum_nr_pdcp_sn = (1 << sn_size) - 1;
+ ret->sn_max = (1 << sn_size) - 1;
+ ret->window_size = 1 << (sn_size - 1);
- return (nr_pdcp_entity_t *)ret;
+ if (ciphering_key != NULL && ciphering_algorithm != 0) {
+ if (ciphering_algorithm != 2) {
+ LOG_E(PDCP, "FATAL: only nea2 supported for the moment\n");
+ exit(1);
+ }
+ ret->has_ciphering = 1;
+ ret->ciphering_algorithm = ciphering_algorithm;
+ memcpy(ret->ciphering_key, ciphering_key, 16);
+
+ ret->security_context = nr_pdcp_security_nea2_init(ciphering_key);
+ ret->cipher = nr_pdcp_security_nea2_cipher;
+ ret->free_security = nr_pdcp_security_nea2_free_security;
+ }
+ ret->is_gnb = is_gnb;
+
+ if (integrity_key != NULL) {
+ printf("%s:%d:%s: TODO\n", __FILE__, __LINE__, __FUNCTION__);
+ exit(1);
+ }
+
+ return ret;
}
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h
index ce5dd300e9..36e7a540c4 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h
@@ -19,18 +19,29 @@
* contact@openairinterface.org
*/
-#include
-
#ifndef _NR_PDCP_ENTITY_H_
#define _NR_PDCP_ENTITY_H_
+#include
+
+#include "nr_pdcp_sdu.h"
+
+typedef enum {
+ NR_PDCP_DRB_AM,
+ NR_PDCP_DRB_UM,
+ NR_PDCP_SRB
+} nr_pdcp_entity_type_t;
+
typedef struct nr_pdcp_entity_t {
+ nr_pdcp_entity_type_t type;
+
/* functions provided by the PDCP module */
void (*recv_pdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size);
void (*recv_sdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size,
int sdu_id);
void (*delete)(struct nr_pdcp_entity_t *entity);
void (*set_integrity_key)(struct nr_pdcp_entity_t *entity, char *key);
+ void (*set_time)(struct nr_pdcp_entity_t *entity, uint64_t now);
/* callbacks provided to the PDCP module */
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
@@ -39,22 +50,56 @@ typedef struct nr_pdcp_entity_t {
void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity,
char *buf, int size, int sdu_id);
void *deliver_pdu_data;
- int tx_hfn;
- int next_nr_pdcp_tx_sn;
- int maximum_nr_pdcp_sn;
+
+ /* configuration variables */
+ int rb_id;
+
+ int sn_size; /* SN size, in bits */
+ int t_reordering; /* unit: ms */
+ int discard_timer; /* unit: ms */
+
+ int sn_max; /* (2^SN_size) - 1 */
+ int window_size; /* 2^(SN_size - 1) */
+
+ /* state variables */
+ uint32_t tx_next;
+ uint32_t rx_next;
+ uint32_t rx_deliv;
+ uint32_t rx_reord;
+
+ /* set to the latest know time by the user of the module. Unit: ms */
+ uint64_t t_current;
+
+ /* timers (stores the ms of activation, 0 means not active) */
+ int t_reordering_start;
+
+ /* security */
+ int has_ciphering;
+ int has_integrity;
+ int ciphering_algorithm;
+ int integrity_algorithm;
+ unsigned char ciphering_key[16];
+ unsigned char integrity_key[16];
+ void *security_context;
+ void (*cipher)(void *security_context,
+ unsigned char *buffer, int length,
+ int bearer, int count, int direction);
+ void (*free_security)(void *security_context);
+ /* security algorithms need to know uplink/downlink information
+ * which is reverse for gnb and ue, so we need to know if this
+ * pdcp entity is for a gnb or an ue
+ */
+ int is_gnb;
+
+ /* rx management */
+ nr_pdcp_sdu_t *rx_list;
+ int rx_size;
+ int rx_maxsize;
} nr_pdcp_entity_t;
-nr_pdcp_entity_t *new_nr_pdcp_entity_srb(
- int rb_id,
- void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
- char *buf, int size),
- void *deliver_sdu_data,
- void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity,
- char *buf, int size, int sdu_id),
- void *deliver_pdu_data);
-
-nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am(
- int rb_id,
+nr_pdcp_entity_t *new_nr_pdcp_entity(
+ nr_pdcp_entity_type_t type,
+ int is_gnb, int rb_id,
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity,
char *buf, int size),
void *deliver_sdu_data,
@@ -63,7 +108,11 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am(
void *deliver_pdu_data,
int sn_size,
int t_reordering,
- int discard_timer);
+ int discard_timer,
+ int ciphering_algorithm,
+ int integrity_algorithm,
+ unsigned char *ciphering_key,
+ unsigned char *integrity_key);
void nr_DRB_preconfiguration(uint16_t crnti);
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c
deleted file mode 100644
index f2f849b9e3..0000000000
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The OpenAirInterface Software Alliance licenses this file to You under
- * the OAI Public License, Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.openairinterface.org/?page_id=698
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *-------------------------------------------------------------------------------
- * For more information about the OpenAirInterface (OAI) Software Alliance:
- * contact@openairinterface.org
- */
-
-#include "nr_pdcp_entity_drb_am.h"
-
-#include
-#include
-#include
-#include "common/utils/LOG/log.h"
-
-void nr_pdcp_entity_drb_am_recv_pdu(nr_pdcp_entity_t *_entity, char *buffer, int size)
-{
- nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity;
-
- if (size < 3) abort();
-
- if (!(buffer[0] & 0x80))
- LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
-
- entity->common.deliver_sdu(entity->common.deliver_sdu_data,
- (nr_pdcp_entity_t *)entity, buffer+3, size-3);
-}
-
-void nr_pdcp_entity_drb_am_recv_sdu(nr_pdcp_entity_t *_entity, char *buffer, int size,
- int sdu_id)
-{
- nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity;
- int sn;
- char buf[size+3];
-
- sn = entity->common.next_nr_pdcp_tx_sn;
-
- entity->common.next_nr_pdcp_tx_sn++;
- if (entity->common.next_nr_pdcp_tx_sn > entity->common.maximum_nr_pdcp_sn) {
- entity->common.next_nr_pdcp_tx_sn = 0;
- entity->common.tx_hfn++;
- }
-
- buf[0] = 0x80 | ((sn >> 16) & 0x3);
- buf[1] = (sn >> 8) & 0xff;
- buf[2] = sn & 0xff;
- memcpy(buf+3, buffer, size);
-
- entity->common.deliver_pdu(entity->common.deliver_pdu_data,
- (nr_pdcp_entity_t *)entity, buf, size+3, sdu_id);
-}
-
-void nr_pdcp_entity_drb_am_set_integrity_key(nr_pdcp_entity_t *_entity, char *key)
-{
- /* nothing to do */
-}
-
-void nr_pdcp_entity_drb_am_delete(nr_pdcp_entity_t *_entity)
-{
- nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity;
- free(entity);
-}
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
index 6195a91ea2..597cba7bf5 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
@@ -24,6 +24,7 @@
#endif
#include "asn1_utils.h"
#include "nr_pdcp_ue_manager.h"
+#include "nr_pdcp_timer_thread.h"
#include "NR_RadioBearerConfig.h"
#include "NR_RLC-BearerConfig.h"
#include "NR_RLC-Config.h"
@@ -41,6 +42,11 @@
static nr_pdcp_ue_manager_t *nr_pdcp_ue_manager;
+/* TODO: handle time a bit more properly */
+static uint64_t nr_pdcp_current_time;
+static int nr_pdcp_current_time_last_frame;
+static int nr_pdcp_current_time_last_subframe;
+
/* necessary globals for OAI, not used internally */
hash_table_t *pdcp_coll_p;
static uint64_t pdcp_optmask;
@@ -339,6 +345,8 @@ void pdcp_layer_init(void)
nr_pdcp_ue_manager = new_nr_pdcp_ue_manager(1);
init_nr_rlc_data_req_queue();
+
+ nr_pdcp_init_timer_thread(nr_pdcp_ue_manager);
}
#include "nfapi/oai_integration/vendor_ext.h"
@@ -591,7 +599,11 @@ static void add_srb(int rnti, struct NR_SRB_ToAddMod *s)
TODO;
}
-static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s)
+static void add_drb_am(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s,
+ int ciphering_algorithm,
+ int integrity_algorithm,
+ unsigned char *ciphering_key,
+ unsigned char *integrity_key)
{
nr_pdcp_entity_t *pdcp_drb;
nr_pdcp_ue_t *ue;
@@ -621,8 +633,11 @@ static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s)
LOG_D(PDCP, "%s:%d:%s: warning DRB %d already exist for ue %d, do nothing\n",
__FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
} else {
- pdcp_drb = new_nr_pdcp_entity_drb_am(drb_id, deliver_sdu_drb, ue, deliver_pdu_drb, ue,
- sn_size_dl, t_reordering, discard_timer);
+ pdcp_drb = new_nr_pdcp_entity(NR_PDCP_DRB_AM, is_gnb, drb_id,
+ deliver_sdu_drb, ue, deliver_pdu_drb, ue,
+ sn_size_dl, t_reordering, discard_timer,
+ ciphering_algorithm, integrity_algorithm,
+ ciphering_key, integrity_key);
nr_pdcp_ue_add_drb_pdcp_entity(ue, drb_id, pdcp_drb);
LOG_D(PDCP, "%s:%d:%s: added drb %d to ue rnti %x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
@@ -630,16 +645,23 @@ static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s)
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
}
-static void add_drb(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_Config_t *rlc_Config)
+static void add_drb(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s,
+ NR_RLC_Config_t *rlc_Config,
+ int ciphering_algorithm,
+ int integrity_algorithm,
+ unsigned char *ciphering_key,
+ unsigned char *integrity_key)
{
switch (rlc_Config->present) {
case NR_RLC_Config_PR_am:
- add_drb_am(rnti, s);
+ add_drb_am(is_gnb, rnti, s, ciphering_algorithm, integrity_algorithm,
+ ciphering_key, integrity_key);
break;
case NR_RLC_Config_PR_um_Bi_Directional:
//add_drb_um(rnti, s);
/* hack */
- add_drb_am(rnti, s);
+ add_drb_am(is_gnb, rnti, s, ciphering_algorithm, integrity_algorithm,
+ ciphering_key, integrity_key);
break;
default:
LOG_E(PDCP, "%s:%d:%s: fatal: unhandled DRB type\n",
@@ -657,7 +679,8 @@ boolean_t nr_rrc_pdcp_config_asn1_req(
const uint8_t security_modeP,
uint8_t *const kRRCenc,
uint8_t *const kRRCint,
- uint8_t *const kUPenc
+ uint8_t *const kUPenc,
+ uint8_t *const kUPint
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
#endif
@@ -676,7 +699,7 @@ boolean_t nr_rrc_pdcp_config_asn1_req(
//srb2add_list == NULL ||
//drb2add_list != NULL ||
drb2release_list != NULL ||
- security_modeP != 255 ||
+ //security_modeP != 255 ||
//kRRCenc != NULL ||
//kRRCint != NULL ||
//kUPenc != NULL ||
@@ -693,7 +716,10 @@ boolean_t nr_rrc_pdcp_config_asn1_req(
if (drb2add_list != NULL) {
for (i = 0; i < drb2add_list->list.count; i++) {
- add_drb(rnti, drb2add_list->list.array[i], rlc_bearer2add_list->list.array[i]->rlc_Config);
+ add_drb(ctxt_pP->enb_flag, rnti, drb2add_list->list.array[i],
+ rlc_bearer2add_list->list.array[i]->rlc_Config,
+ security_modeP & 0x0f, (security_modeP >> 4) & 0x0f,
+ kUPenc, kUPint);
}
}
@@ -705,6 +731,7 @@ boolean_t nr_rrc_pdcp_config_asn1_req(
free(kRRCenc);
free(kRRCint);
free(kUPenc);
+ free(kUPint);
return 0;
}
@@ -805,6 +832,7 @@ void nr_DRB_preconfiguration(uint16_t crnti)
NULL,
NULL,
NULL,
+ NULL,
Rlc_Bearer_ToAdd_list);
nr_rrc_rlc_config_asn1_req (&ctxt,
@@ -956,3 +984,14 @@ void
pdcp_mbms_run ( const protocol_ctxt_t *const ctxt_pP){
/* nothing to do */
}
+
+void nr_pdcp_tick(int frame, int subframe)
+{
+ if (frame != nr_pdcp_current_time_last_frame ||
+ subframe != nr_pdcp_current_time_last_subframe) {
+ nr_pdcp_current_time_last_frame = frame;
+ nr_pdcp_current_time_last_subframe = subframe;
+ nr_pdcp_current_time++;
+ nr_pdcp_wakeup_timer_thread(nr_pdcp_current_time);
+ }
+}
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.c
new file mode 100644
index 0000000000..47d95156e3
--- /dev/null
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.c
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ * contact@openairinterface.org
+ */
+
+#include "nr_pdcp_sdu.h"
+
+#include
+#include
+
+nr_pdcp_sdu_t *nr_pdcp_new_sdu(uint32_t count, char *buffer, int size)
+{
+ nr_pdcp_sdu_t *ret = calloc(1, sizeof(nr_pdcp_sdu_t));
+ if (ret == NULL)
+ exit(1);
+ ret->count = count;
+ ret->buffer = malloc(size);
+ if (ret->buffer == NULL)
+ exit(1);
+ memcpy(ret->buffer, buffer, size);
+ ret->size = size;
+ return ret;
+}
+
+nr_pdcp_sdu_t *nr_pdcp_sdu_list_add(nr_pdcp_sdu_t *l, nr_pdcp_sdu_t *sdu)
+{
+ nr_pdcp_sdu_t head;
+ nr_pdcp_sdu_t *cur;
+ nr_pdcp_sdu_t *prev;
+
+ head.next = l;
+ cur = l;
+ prev = &head;
+
+ /* order is by 'count' */
+ while (cur != NULL) {
+ /* check if 'sdu' is before 'cur' in the list */
+ if (sdu->count < cur->count)
+ break;
+ prev = cur;
+ cur = cur->next;
+ }
+ prev->next = sdu;
+ sdu->next = cur;
+ return head.next;
+}
+
+int nr_pdcp_sdu_in_list(nr_pdcp_sdu_t *l, uint32_t count)
+{
+ while (l != NULL) {
+ if (l->count == count)
+ return 1;
+ l = l->next;
+ }
+ return 0;
+}
+
+void nr_pdcp_free_sdu(nr_pdcp_sdu_t *sdu)
+{
+ free(sdu->buffer);
+ free(sdu);
+}
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.h
similarity index 58%
rename from openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.h
rename to openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.h
index d7c42e6a62..3d4e50a4ce 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.h
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_sdu.h
@@ -19,23 +19,21 @@
* contact@openairinterface.org
*/
-#ifndef _NR_PDCP_ENTITY_DRB_AM_H_
-#define _NR_PDCP_ENTITY_DRB_AM_H_
+#ifndef _NR_PDCP_SDU_H_
+#define _NR_PDCP_SDU_H_
-#include "nr_pdcp_entity.h"
+#include
-typedef struct {
- nr_pdcp_entity_t common;
- int rb_id;
- int sn_size; /* unit: bits */
- int t_reordering; /* unit: ms */
- int discard_timer; /* unit: ms, -1 means infinity */
-} nr_pdcp_entity_drb_am_t;
+typedef struct nr_pdcp_sdu_t {
+ uint32_t count;
+ char *buffer;
+ int size;
+ struct nr_pdcp_sdu_t *next;
+} nr_pdcp_sdu_t;
-void nr_pdcp_entity_drb_am_recv_pdu(nr_pdcp_entity_t *entity, char *buffer, int size);
-void nr_pdcp_entity_drb_am_recv_sdu(nr_pdcp_entity_t *entity, char *buffer, int size,
- int sdu_id);
-void nr_pdcp_entity_drb_am_set_integrity_key(nr_pdcp_entity_t *entity, char *key);
-void nr_pdcp_entity_drb_am_delete(nr_pdcp_entity_t *entity);
+nr_pdcp_sdu_t *nr_pdcp_new_sdu(uint32_t count, char *buffer, int size);
+nr_pdcp_sdu_t *nr_pdcp_sdu_list_add(nr_pdcp_sdu_t *l, nr_pdcp_sdu_t *sdu);
+int nr_pdcp_sdu_in_list(nr_pdcp_sdu_t *l, uint32_t count);
+void nr_pdcp_free_sdu(nr_pdcp_sdu_t *sdu);
-#endif /* _NR_PDCP_ENTITY_DRB_AM_H_ */
+#endif /* _NR_PDCP_SDU_H_ */
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c
new file mode 100644
index 0000000000..fc07f661dd
--- /dev/null
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ * contact@openairinterface.org
+ */
+
+#include "nr_pdcp_security_nea2.h"
+
+#include
+#include
+#include
+#include
+#include
+
+void *nr_pdcp_security_nea2_init(unsigned char *ciphering_key)
+{
+ void *ctx = calloc(1, nettle_aes128.context_size);
+ if (ctx == NULL) exit(1);
+
+#if NETTLE_VERSION_MAJOR < 3
+ nettle_aes128.set_encrypt_key(ctx, 16, ciphering_key);
+#else
+ nettle_aes128.set_encrypt_key(ctx, ciphering_key);
+#endif
+
+ return ctx;
+}
+
+void nr_pdcp_security_nea2_cipher(void *security_context,
+ unsigned char *buffer, int length,
+ int bearer, int count, int direction)
+{
+ unsigned char t[16];
+
+ t[0] = (count >> 24) & 255;
+ t[1] = (count >> 16) & 255;
+ t[2] = (count >> 8) & 255;
+ t[3] = (count ) & 255;
+ t[4] = ((bearer-1) << 3) | (direction << 2);
+ memset(&t[5], 0, 16-5);
+
+ nettle_ctr_crypt(security_context, nettle_aes128.encrypt,
+ nettle_aes128.block_size, t,
+ length, buffer, buffer);
+}
+
+void nr_pdcp_security_nea2_free_security(void *security_context)
+{
+ free(security_context);
+}
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.h
new file mode 100644
index 0000000000..c3667c93d4
--- /dev/null
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.h
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ * contact@openairinterface.org
+ */
+
+#ifndef _NR_PDCP_SECURITY_NEA2_H_
+#define _NR_PDCP_SECURITY_NEA2_H_
+
+void *nr_pdcp_security_nea2_init(unsigned char *ciphering_key);
+
+void nr_pdcp_security_nea2_cipher(void *security_context,
+ unsigned char *buffer, int length,
+ int bearer, int count, int direction);
+
+void nr_pdcp_security_nea2_free_security(void *security_context);
+
+#endif /* _NR_PDCP_SECURITY_NEA2_H_ */
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_timer_thread.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_timer_thread.c
new file mode 100644
index 0000000000..36e9b16024
--- /dev/null
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_timer_thread.c
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ * contact@openairinterface.org
+ */
+
+#include "nr_pdcp_timer_thread.h"
+
+#include
+#include
+#include
+
+#include "LOG/log.h"
+
+static pthread_mutex_t timer_thread_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t timer_thread_cond = PTHREAD_COND_INITIALIZER;
+static volatile uint64_t timer_thread_curtime = 0;
+
+static void *nr_pdcp_timer_thread(void *_nr_pdcp_ue_manager)
+{
+ nr_pdcp_ue_manager_t *nr_pdcp_ue_manager = (nr_pdcp_ue_manager_t *)_nr_pdcp_ue_manager;
+ nr_pdcp_ue_t **ue_list;
+ int ue_count;
+ int i;
+ int j;
+ uint64_t curtime = 0;
+
+ while (1) {
+ if (pthread_mutex_lock(&timer_thread_mutex) != 0) abort();
+ while (curtime == timer_thread_curtime)
+ if (pthread_cond_wait(&timer_thread_cond, &timer_thread_mutex) != 0) abort();
+ curtime = timer_thread_curtime;
+ if (pthread_mutex_unlock(&timer_thread_mutex) != 0) abort();
+
+ nr_pdcp_manager_lock(nr_pdcp_ue_manager);
+
+ ue_list = nr_pdcp_manager_get_ue_list(nr_pdcp_ue_manager);
+ ue_count = nr_pdcp_manager_get_ue_count(nr_pdcp_ue_manager);
+ for (i = 0; i < ue_count; i++) {
+ for (j = 0; j < 2; j++) {
+ if (ue_list[i]->srb[j] != NULL)
+ ue_list[i]->srb[j]->set_time(ue_list[i]->srb[j], curtime);
+ }
+ for (j = 0; j < 5; j++) {
+ if (ue_list[i]->drb[j] != NULL)
+ ue_list[i]->drb[j]->set_time(ue_list[i]->drb[j], curtime);
+ }
+ }
+
+ nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
+ }
+
+ return NULL;
+}
+
+void nr_pdcp_init_timer_thread(nr_pdcp_ue_manager_t *nr_pdcp_ue_manager)
+{
+ pthread_t t;
+
+ if (pthread_create(&t, NULL, nr_pdcp_timer_thread, nr_pdcp_ue_manager) != 0) {
+ LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__);
+ exit(1);
+ }
+}
+
+void nr_pdcp_wakeup_timer_thread(uint64_t time)
+{
+ if (pthread_mutex_lock(&timer_thread_mutex)) abort();
+ timer_thread_curtime = time;
+ if (pthread_cond_broadcast(&timer_thread_cond)) abort();
+ if (pthread_mutex_unlock(&timer_thread_mutex)) abort();
+}
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_timer_thread.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_timer_thread.h
new file mode 100644
index 0000000000..db8282f940
--- /dev/null
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_timer_thread.h
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ * contact@openairinterface.org
+ */
+
+#ifndef _NR_PDCP_TIMER_THREAD_H_
+#define _NR_PDCP_TIMER_THREAD_H_
+
+#include "nr_pdcp_ue_manager.h"
+
+#include
+
+void nr_pdcp_init_timer_thread(nr_pdcp_ue_manager_t *nr_pdcp_ue_manager);
+void nr_pdcp_wakeup_timer_thread(uint64_t time);
+
+#endif /* _NR_PDCP_TIMER_THREAD_H_ */
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c
index ca51da3d5f..f89a18f94e 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c
@@ -189,6 +189,20 @@ void nr_pdcp_ue_add_drb_pdcp_entity(nr_pdcp_ue_t *ue, int drb_id, nr_pdcp_entity
ue->drb[drb_id] = entity;
}
+/* must be called with lock acquired */
+nr_pdcp_ue_t **nr_pdcp_manager_get_ue_list(nr_pdcp_ue_manager_t *_m)
+{
+ nr_pdcp_ue_manager_internal_t *m = _m;
+ return m->ue_list;
+}
+
+/* must be called with lock acquired */
+int nr_pdcp_manager_get_ue_count(nr_pdcp_ue_manager_t *_m)
+{
+ nr_pdcp_ue_manager_internal_t *m = _m;
+ return m->ue_count;
+}
+
int nr_pdcp_get_first_rnti(nr_pdcp_ue_manager_t *_m)
{
nr_pdcp_ue_manager_internal_t *m = _m;
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h
index 0de2f024b3..3329f856b7 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h
@@ -46,6 +46,9 @@ void nr_pdcp_manager_unlock(nr_pdcp_ue_manager_t *m);
nr_pdcp_ue_t *nr_pdcp_manager_get_ue(nr_pdcp_ue_manager_t *m, int rnti);
void nr_pdcp_manager_remove_ue(nr_pdcp_ue_manager_t *m, int rnti);
+nr_pdcp_ue_t **nr_pdcp_manager_get_ue_list(nr_pdcp_ue_manager_t *_m);
+int nr_pdcp_manager_get_ue_count(nr_pdcp_ue_manager_t *_m);
+
/***********************************************************************/
/* ue functions */
/***********************************************************************/
diff --git a/openair2/NETWORK_DRIVER/UE_IP/device.c b/openair2/NETWORK_DRIVER/UE_IP/device.c
index 63184eb6da..0ff9a73925 100644
--- a/openair2/NETWORK_DRIVER/UE_IP/device.c
+++ b/openair2/NETWORK_DRIVER/UE_IP/device.c
@@ -302,6 +302,7 @@ void ue_ip_change_rx_flags(struct net_device *dev_pP, int flagsP) {
}
//---------------------------------------------------------------------------
+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)
void ue_ip_tx_timeout(struct net_device *dev_pP, unsigned int txqueue)
#else
diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
index b5cda6ecd6..b183b32aab 100644
--- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
+++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
@@ -36,6 +36,7 @@
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "common/ran_context.h"
#include "executables/softmodem-common.h"
+#include "nfapi/oai_integration/vendor_ext.h"
#define MAX_IF_MODULES 100
//#define UL_HARQ_PRINT
@@ -104,6 +105,7 @@ void handle_nr_uci(NR_UL_IND_t *UL_info)
}
UL_info->uci_ind.num_ucis = 0;
+
// mark corresponding PUCCH resources as free
// NOTE: we just assume it is BWP ID 1, to be revised for multiple BWPs
RC.nrmac[mod_id]->pucch_index_used[1][slot] = 0;
@@ -184,7 +186,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
module_id,CC_id, UL_info->rach_ind.number_of_pdus,
UL_info->rx_ind.number_of_pdus, UL_info->crc_ind.number_crcs);
- if (nfapi_mode != 1) {
+ if (NFAPI_MODE != NFAPI_MODE_PNF) {
if (ifi->CC_mask==0) {
ifi->current_frame = UL_info->frame;
ifi->current_slot = UL_info->slot;
@@ -203,7 +205,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) {
mac->UL_dci_req[CC_id].numPdus = 0;
handle_nr_ulsch(UL_info);
- if (nfapi_mode != 1) {
+ if (NFAPI_MODE != NFAPI_MODE_PNF) {
if (ifi->CC_mask == ((1<scc, ul_info->slot_tx) && get_softmodem_params()->do_ra)
+ if (is_nr_UL_slot(mac->scc, ul_info->slot_tx, mac->frame_type) && get_softmodem_params()->do_ra)
nr_ue_prach_scheduler(module_id, ul_info->frame_tx, ul_info->slot_tx, ul_info->thread_id);
switch(ret){
diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c
index b4a7f8c6e7..21740016b1 100644
--- a/openair2/PHY_INTERFACE/phy_stub_UE.c
+++ b/openair2/PHY_INTERFACE/phy_stub_UE.c
@@ -30,6 +30,10 @@
#include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h"
#include "common/config/config_load_configmodule.h"
#include "common/config/config_userapi.h"
+#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"
extern int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind);
void configure_nfapi_pnf(char *vnf_ip_addr,
diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h
index 7602e9ca64..4f55f94121 100644
--- a/openair2/RRC/LTE/rrc_defs.h
+++ b/openair2/RRC/LTE/rrc_defs.h
@@ -546,6 +546,13 @@ typedef struct rrc_gummei_s {
uint16_t mme_group_id;
} rrc_gummei_t;
+typedef struct {
+ uint16_t ciphering_algorithms;
+ uint16_t integrity_algorithms;
+ uint16_t sk_counter;
+ uint8_t kgNB[32];
+} lte_rrc_nr_security_t;
+
typedef struct eNB_RRC_UE_s {
uint8_t primaryCC_id;
LTE_SCellToAddMod_r10_t sCell_config[2];
@@ -615,6 +622,9 @@ typedef struct eNB_RRC_UE_s {
security_capabilities_t security_capabilities;
+ /* security capabilities and settings for an UE in ENDC mode */
+ lte_rrc_nr_security_t nr_security;
+
int next_hop_chain_count;
uint8_t next_security_key[SECURITY_KEY_LENGTH];
diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c
index 6d39fb2221..526ce129b1 100644
--- a/openair2/RRC/LTE/rrc_eNB.c
+++ b/openair2/RRC/LTE/rrc_eNB.c
@@ -4426,69 +4426,11 @@ static int encode_CG_ConfigInfo(
struct NR_RadioBearerConfig *rb_config = NULL;
asn_enc_rval_t enc_rval;
int RRC_OK = 1;
- int index = 0;
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;
NR_UE_CapabilityRAT_Container_t *ue_cap_rat_container_nr = NULL;
int RAT_Container_count = 0;
- rb_config = calloc(1,sizeof(struct NR_RadioBearerConfig));
- AssertFatal(rb_config != NULL,"failed to allocate memory for rb_config");
-
- if(ue_context_pP->ue_context.DRB_configList->list.count != 0) {
- rb_config->drb_ToAddModList = calloc(1,sizeof(struct NR_DRB_ToAddModList ));
- AssertFatal(rb_config->drb_ToAddModList != NULL,"failed to allocated memory for drbtoaddmodlist");
- rb_config->drb_ToAddModList->list.count = NUMBEROF_DRBS_TOBE_ADDED;
- rb_config->drb_ToAddModList->list.array
- = calloc(NUMBEROF_DRBS_TOBE_ADDED, sizeof(struct NR_DRB_ToAddMod *));
- AssertFatal( rb_config->drb_ToAddModList->list.array != NULL,
- "falied to allocate memory for list.array");
-
- for(index = 0; index < NUMBEROF_DRBS_TOBE_ADDED; index++) {
- rb_config->drb_ToAddModList->list.array[index]
- = calloc(1,sizeof(struct NR_DRB_ToAddMod));
- AssertFatal(rb_config->drb_ToAddModList->list.array[index] != NULL,
- "failed to allocate memory for drb_toaddmod");
- rb_config->drb_ToAddModList->list.array[index]->drb_Identity
- = ue_context_pP->ue_context.DRB_configList->list.array[index]->drb_Identity;
-
- if(ue_context_pP->ue_context.DRB_configList->list.array[index]->eps_BearerIdentity) {
- rb_config->drb_ToAddModList->list.array[index]->cnAssociation
- = calloc(1,sizeof(struct NR_DRB_ToAddMod__cnAssociation));
- AssertFatal(rb_config->drb_ToAddModList->list.array[index]->cnAssociation != NULL,
- "failed to allocate memory cnAssociation");
- rb_config->drb_ToAddModList->list.array[index]->cnAssociation->present
- = NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity;
- rb_config->drb_ToAddModList->list.array[index]->cnAssociation->choice.eps_BearerIdentity
- = *(ue_context_pP->ue_context.DRB_configList->list.array[index]->eps_BearerIdentity);
- }
-
- rb_config->drb_ToAddModList->list.array[index]->pdcp_Config = calloc(1,sizeof(struct NR_PDCP_Config));
- rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb = calloc(1,sizeof(struct NR_PDCP_Config__drb));
- rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->discardTimer = calloc(1,sizeof(long));
- *rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->discardTimer
- = *(ue_context_pP->ue_context.DRB_configList->list.array[index]->pdcp_Config->discardTimer);
- rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->pdcp_SN_SizeUL = calloc(1,sizeof(long));
- *rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->pdcp_SN_SizeUL
- = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits;
- rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->pdcp_SN_SizeDL = calloc(1,sizeof(long));
- *rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->pdcp_SN_SizeDL
- = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits;
- rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->headerCompression.present
- = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
- rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->drb->headerCompression.choice.notUsed = 0;
- rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->t_Reordering = calloc(1,sizeof(long));
- *rb_config->drb_ToAddModList->list.array[index]->pdcp_Config->t_Reordering
- = NR_PDCP_Config__t_Reordering_ms0;
- }
-
- rb_config->securityConfig = calloc(1,sizeof(struct NR_SecurityConfig ));
- rb_config->securityConfig->securityAlgorithmConfig = calloc(1,sizeof(struct NR_SecurityAlgorithmConfig));
- rb_config->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = NR_CipheringAlgorithm_nea0;
- rb_config->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm = NULL;
- rb_config->securityConfig->keyToUse = calloc(1,sizeof(long));
- *rb_config->securityConfig->keyToUse = NR_SecurityConfig__keyToUse_master;
- }
cg_configinfo = calloc(1,sizeof(struct NR_CG_ConfigInfo));
AssertFatal(cg_configinfo != NULL,"failed to allocate memory for cg_configinfo");
@@ -4548,15 +4490,6 @@ static int encode_CG_ConfigInfo(
(const char *)temp_buff, (enc_rval.encoded+7)>>3);
}
- cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo->mcg_RB_Config
- = calloc(1,sizeof(OCTET_STRING_t));
- AssertFatal(cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo->
- mcg_RB_Config != NULL, "failed to allocate memory for mcg_rb_config");
- enc_rval = uper_encode_to_buffer(&asn_DEF_NR_RadioBearerConfig,NULL,(void *)rb_config,temp_buff,ASN_MAX_ENCODE_SIZE);
- AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n",
- enc_rval.failed_type->name, enc_rval.encoded);
- OCTET_STRING_fromBuf(cg_configinfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo->mcg_RB_Config,
- (const char *)temp_buff, (enc_rval.encoded+7)>>3);
// this xer_fprint can be enabled for additional debugging messages
// xer_fprint(stdout,&asn_DEF_NR_CG_ConfigInfo,(void *)cg_configinfo);
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CG_ConfigInfo,NULL,(void *)cg_configinfo,
@@ -4665,11 +4598,20 @@ rrc_eNB_process_MeasurementReport(
msg = itti_alloc_new_message(TASK_RRC_ENB, 0, X2AP_ENDC_SGNB_ADDITION_REQ);
memset(&(X2AP_ENDC_SGNB_ADDITION_REQ(msg)), 0, sizeof(x2ap_ENDC_sgnb_addition_req_t));
+
X2AP_ENDC_SGNB_ADDITION_REQ(msg).rnti = ctxt_pP->rnti;
+
+ X2AP_ENDC_SGNB_ADDITION_REQ(msg).security_capabilities.encryption_algorithms = ue_context_pP->ue_context.nr_security.ciphering_algorithms;
+ X2AP_ENDC_SGNB_ADDITION_REQ(msg).security_capabilities.integrity_algorithms = ue_context_pP->ue_context.nr_security.integrity_algorithms;
+
+ memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).kgnb, ue_context_pP->ue_context.nr_security.kgNB, 32);
+
memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer,enc_buf,enc_size);
X2AP_ENDC_SGNB_ADDITION_REQ(msg).rrc_buffer_size = enc_size;
+
X2AP_ENDC_SGNB_ADDITION_REQ(msg).target_physCellId
= measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[0]->physCellId;
+
//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;
diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c
index 320004a361..0e6d5b580f 100644
--- a/openair2/RRC/LTE/rrc_eNB_S1AP.c
+++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c
@@ -782,21 +782,37 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ(
S1AP_NAS_FIRST_REQ (message_p).ue_identity.presenceMask |= UE_IDENTITIES_gummei;
if (r_mme->plmn_Identity != NULL) {
- if ((r_mme->plmn_Identity->mcc != NULL) && (r_mme->plmn_Identity->mcc->list.count > 0)) {
- /* Use first indicated PLMN MCC if it is defined */
- S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc = *r_mme->plmn_Identity->mcc->list.array[selected_plmn_identity];
+ if ((r_mme->plmn_Identity->mcc != NULL) && (r_mme->plmn_Identity->mcc->list.count == 3))
+ {
+ S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc = (*r_mme->plmn_Identity->mcc->list.array[0] & 0xf) * 100 +
+ (*r_mme->plmn_Identity->mcc->list.array[1] & 0xf) * 10 +
+ (*r_mme->plmn_Identity->mcc->list.array[2] & 0xf);
LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MCC %u ue %x\n",
ctxt_pP->module_id,
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc,
ue_context_pP->ue_context.rnti);
}
-
- if (r_mme->plmn_Identity->mnc.list.count > 0) {
- /* Use first indicated PLMN MNC if it is defined */
- S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = *r_mme->plmn_Identity->mnc.list.array[selected_plmn_identity];
- LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u ue %x\n",
+ if(r_mme->plmn_Identity->mnc.list.count == 3)
+ {
+ S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = (*r_mme->plmn_Identity->mnc.list.array[0] & 0xf) * 100 +
+ (*r_mme->plmn_Identity->mnc.list.array[1] & 0xf) * 10 +
+ (*r_mme->plmn_Identity->mnc.list.array[2] & 0xf);
+ S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc_len = 3;
+ LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u %udigit ue %x\n",
ctxt_pP->module_id,
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc,
+ S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc_len,
+ ue_context_pP->ue_context.rnti);
+ }
+ else if(r_mme->plmn_Identity->mnc.list.count == 2)
+ {
+ S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = (*r_mme->plmn_Identity->mnc.list.array[0] & 0xf) * 10 +
+ (*r_mme->plmn_Identity->mnc.list.array[1] & 0xf);
+ S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc_len = 2;
+ LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u %udigit ue %x\n",
+ ctxt_pP->module_id,
+ S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc,
+ S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc_len,
ue_context_pP->ue_context.rnti);
}
} else { // end if plmn_Identity != NULL
@@ -1045,6 +1061,15 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char
}
}
+ ue_context_p->ue_context.nr_security.ciphering_algorithms = S1AP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nr_security_capabilities.encryption_algorithms;
+ ue_context_p->ue_context.nr_security.integrity_algorithms = S1AP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nr_security_capabilities.integrity_algorithms;
+ /* let's initialize sk_counter to 0 */
+ ue_context_p->ue_context.nr_security.sk_counter = 0;
+ /* let's compute kgNB */
+ derive_skgNB(ue_context_p->ue_context.kenb,
+ ue_context_p->ue_context.nr_security.sk_counter,
+ ue_context_p->ue_context.nr_security.kgNB);
+
// in case, send the S1SP initial context response if it is not sent with the attach complete message
if (ue_context_p->ue_context.Status == RRC_RECONFIGURED) {
LOG_I(RRC, "Sending rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP, cause %ld\n", ue_context_p->ue_context.reestablishment_cause);
diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c
index eb43eeb5f2..58c595a3d0 100644
--- a/openair2/RRC/NR/L2_nr_interface.c
+++ b/openair2/RRC/NR/L2_nr_interface.c
@@ -303,4 +303,4 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
return(0);
-}
+}
\ No newline at end of file
diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h
index ba42fd5087..e00868ae53 100644
--- a/openair2/RRC/NR/nr_rrc_defs.h
+++ b/openair2/RRC/NR/nr_rrc_defs.h
@@ -448,6 +448,15 @@ typedef struct {
//---------------------------------------------------
+typedef struct {
+ /* nea0 = 0, nea1 = 1, ... */
+ int ciphering_algorithms[4];
+ int ciphering_algorithms_count;
+
+ /* nia0 = 0, nia1 = 1, ... */
+ int integrity_algorithms[4];
+ int integrity_algorithms_count;
+} nr_security_configuration_t;
//---NR---(completely change)---------------------
typedef struct gNB_RRC_INST_s {
@@ -480,6 +489,8 @@ typedef struct gNB_RRC_INST_s {
int srb1_timer_status_prohibit;
int srs_enable[MAX_NUM_CCs];
+ // security configuration (preferred algorithms)
+ nr_security_configuration_t security;
} gNB_RRC_INST;
#include "nr_rrc_proto.h" //should be put here otherwise compilation error
diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h
index 9b7d734e2c..6d876a0eef 100644
--- a/openair2/RRC/NR/nr_rrc_proto.h
+++ b/openair2/RRC/NR/nr_rrc_proto.h
@@ -39,6 +39,7 @@
#include "LTE_UE-CapabilityRAT-ContainerList.h"
#include "NR_CG-Config.h"
#include "NR_CG-ConfigInfo.h"
+#include "NR_SecurityConfig.h"
int rrc_init_nr_global_param(void);
@@ -90,7 +91,10 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon
int n_physical_antenna_ports,
int initial_csi_index);
-void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig);
+void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig,
+ int eps_bearer_id, int rb_id,
+ e_NR_CipheringAlgorithm ciphering_algorithm,
+ e_NR_SecurityConfig__keyToUse key_to_use);
int generate_CG_Config(gNB_RRC_INST *rrc,
NR_CG_Config_t *cg_Config,
diff --git a/openair2/RRC/NR/nr_rrc_types.h b/openair2/RRC/NR/nr_rrc_types.h
index 02495591a9..61f90e3572 100644
--- a/openair2/RRC/NR/nr_rrc_types.h
+++ b/openair2/RRC/NR/nr_rrc_types.h
@@ -32,11 +32,11 @@
#define RRC_TYPES_NR_H_
typedef enum Rrc_State_NR_e {
- RRC_STATE_INACTIVE_NR=0,
- RRC_STATE_IDLE_NR,
+ RRC_STATE_IDLE_NR=0,
+ RRC_STATE_INACTIVE_NR,
RRC_STATE_CONNECTED_NR,
- RRC_STATE_FIRST_NR = RRC_STATE_INACTIVE_NR,
+ RRC_STATE_FIRST_NR = RRC_STATE_IDLE_NR,
RRC_STATE_LAST_NR = RRC_STATE_CONNECTED_NR,
} Rrc_State_NR_t;
diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c
index 5731a97669..508d63a111 100755
--- a/openair2/RRC/NR/rrc_gNB.c
+++ b/openair2/RRC/NR/rrc_gNB.c
@@ -103,7 +103,8 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req(
const uint8_t security_modeP,
uint8_t *const kRRCenc,
uint8_t *const kRRCint,
- uint8_t *const kUPenc
+ uint8_t *const kUPenc,
+ uint8_t *const kUPint
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
#endif
@@ -890,6 +891,7 @@ rrc_gNB_process_RRCReconfigurationComplete(
kUPenc,
NULL,
NULL,
+ NULL,
NULL);
/* Refresh SRBs/DRBs */
nr_rrc_rlc_config_asn1_req(ctxt_pP,
@@ -1705,6 +1707,7 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP,
// NULL,
// NULL,
// NULL,
+ // NULL,
// NULL);
// if (!NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) {
diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c
index 09badc8b03..654bf45399 100644
--- a/openair2/RRC/NR/rrc_gNB_nsa.c
+++ b/openair2/RRC/NR/rrc_gNB_nsa.c
@@ -39,6 +39,7 @@
#include "openair2/RRC/LTE/rrc_eNB_GTPV1U.h"
#include "executables/softmodem-common.h"
#include
+#include "UTIL/OSA/osa_defs.h"
extern boolean_t nr_rrc_pdcp_config_asn1_req(
const protocol_ctxt_t *const ctxt_pP,
@@ -48,7 +49,8 @@ extern boolean_t nr_rrc_pdcp_config_asn1_req(
const uint8_t security_modeP,
uint8_t *const kRRCenc,
uint8_t *const kRRCint,
- uint8_t *const kUPenc
+ uint8_t *const kUPenc,
+ uint8_t *const kUPint
#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
#endif
@@ -115,28 +117,14 @@ void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, NR_UE_CapabilityRAT_ContainerL
// dump ue_capabilities
- if ( LOG_DEBUGFLAG(DEBUG_ASN1 && ueCapabilityRAT_Container_nr != NULL) ) {
+ if ( LOG_DEBUGFLAG(DEBUG_ASN1) && ueCapabilityRAT_Container_nr != NULL ) {
xer_fprint(stdout, &asn_DEF_NR_UE_NR_Capability, ue_context_p->ue_context.UE_Capability_nr);
}
- if ( LOG_DEBUGFLAG(DEBUG_ASN1 && ueCapabilityRAT_Container_MRDC != NULL) ) {
+ 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);
}
- if(cg_config_info && cg_config_info->mcg_RB_Config) {
- asn_dec_rval_t dec_rval = uper_decode(NULL,
- &asn_DEF_NR_RadioBearerConfig,
- (void **)&ue_context_p->ue_context.rb_config,
- cg_config_info->mcg_RB_Config->buf,
- cg_config_info->mcg_RB_Config->size, 0, 0);
-
- if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
- AssertFatal(1==0,"[InterNode] Failed to decode mcg_rb_config (%zu bits), size of OCTET_STRING %lu\n",
- dec_rval.consumed, cg_config_info->mcg_RB_Config->size);
- }
- }
-
- xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *)ue_context_p->ue_context.rb_config);
rrc_add_nsa_user(rrc,ue_context_p, m);
}
@@ -152,6 +140,8 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
gtpv1u_enb_create_tunnel_req_t create_tunnel_req;
gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp;
protocol_ctxt_t ctxt={0};
+ unsigned char *kUPenc = NULL;
+ int i;
// NR RRCReconfiguration
AssertFatal(rrc->Nb_ue < MAX_NR_RRC_UE_CONTEXTS,"cannot add another UE\n");
ue_context_p->ue_context.reconfig = calloc(1,sizeof(NR_RRCReconfiguration_t));
@@ -162,9 +152,91 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
NR_RRCReconfiguration_IEs_t *reconfig_ies=calloc(1,sizeof(NR_RRCReconfiguration_IEs_t));
ue_context_p->ue_context.reconfig->criticalExtensions.choice.rrcReconfiguration = reconfig_ies;
carrier->initial_csi_index[rrc->Nb_ue] = 0;
+ ue_context_p->ue_context.rb_config = calloc(1,sizeof(NR_RRCReconfiguration_t));
if (get_softmodem_params()->phy_test == 1 || get_softmodem_params()->do_ra == 1 || get_softmodem_params()->sa == 1){
- ue_context_p->ue_context.rb_config = calloc(1,sizeof(NR_RRCReconfiguration_t));
- fill_default_rbconfig(ue_context_p->ue_context.rb_config);
+ fill_default_rbconfig(ue_context_p->ue_context.rb_config,
+ 5 /* EPS bearer ID */,
+ 1 /* drb ID */,
+ NR_CipheringAlgorithm_nea0,
+ NR_SecurityConfig__keyToUse_master);
+ } else {
+ /* TODO: handle more than one bearer */
+ if (m == NULL) {
+ LOG_E(RRC, "fatal: m==NULL\n");
+ exit(1);
+ }
+ if (m->nb_e_rabs_tobeadded != 1) {
+ LOG_E(RRC, "fatal: m->nb_e_rabs_tobeadded = %d, should be 1\n", m->nb_e_rabs_tobeadded);
+ exit(1);
+ }
+
+ /* store security key and security capabilities */
+ memcpy(ue_context_p->ue_context.kgnb, m->kgnb, 32);
+ ue_context_p->ue_context.security_capabilities.nRencryption_algorithms = m->security_capabilities.encryption_algorithms;
+ ue_context_p->ue_context.security_capabilities.nRintegrity_algorithms = m->security_capabilities.integrity_algorithms;
+
+ /* Select ciphering algorithm based on gNB configuration file and
+ * UE's supported algorithms.
+ * We take the first from the list that is supported by the UE.
+ * The ordering of the list comes from the configuration file.
+ */
+ /* preset nea0 as fallback */
+ ue_context_p->ue_context.ciphering_algorithm = 0;
+ for (i = 0; i < rrc->security.ciphering_algorithms_count; i++) {
+ int nea_mask[4] = {
+ 0,
+ 0x8000, /* nea1 */
+ 0x4000, /* nea2 */
+ 0x2000 /* nea3 */
+ };
+ if (rrc->security.ciphering_algorithms[i] == 0) {
+ /* nea0 already preselected */
+ break;
+ }
+ if (ue_context_p->ue_context.security_capabilities.nRencryption_algorithms & nea_mask[rrc->security.ciphering_algorithms[i]]) {
+ ue_context_p->ue_context.ciphering_algorithm = rrc->security.ciphering_algorithms[i];
+ break;
+ }
+ }
+
+ LOG_I(RRC, "selecting ciphering algorithm %d\n", (int)ue_context_p->ue_context.ciphering_algorithm);
+
+ /* integrity: no integrity protection for DRB in ENDC mode
+ * as written in 38.331: "If UE is connected to E-UTRA/EPC, this field
+ * indicates the integrity protection algorithm to be used for SRBs
+ * configured with NR PDCP, as specified in TS 33.501"
+ * So nothing for DRB. Plus a test with a COTS UE revealed that it
+ * did not apply integrity on the DRB.
+ */
+ ue_context_p->ue_context.integrity_algorithm = 0;
+
+ LOG_I(RRC, "selecting integrity algorithm %d\n", ue_context_p->ue_context.integrity_algorithm);
+
+ /* derive UP security key */
+ unsigned char *kUPenc_kdf;
+ nr_derive_key_up_enc(ue_context_p->ue_context.ciphering_algorithm,
+ ue_context_p->ue_context.kgnb,
+ &kUPenc_kdf);
+ /* kUPenc: last 128 bits of key derivation function which returns 256 bits */
+ kUPenc = malloc(16);
+ if (kUPenc == NULL) exit(1);
+ memcpy(kUPenc, kUPenc_kdf+16, 16);
+ free(kUPenc_kdf);
+
+ e_NR_CipheringAlgorithm cipher_algo;
+ switch (ue_context_p->ue_context.ciphering_algorithm) {
+ case 0: cipher_algo = NR_CipheringAlgorithm_nea0; break;
+ case 1: cipher_algo = NR_CipheringAlgorithm_nea1; break;
+ case 2: cipher_algo = NR_CipheringAlgorithm_nea2; break;
+ case 3: cipher_algo = NR_CipheringAlgorithm_nea3; break;
+ default: LOG_E(RRC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); exit(1);
+ }
+
+ fill_default_rbconfig(ue_context_p->ue_context.rb_config,
+ m->e_rabs_tobeadded[0].e_rab_id,
+ m->e_rabs_tobeadded[0].drb_ID,
+ cipher_algo,
+ NR_SecurityConfig__keyToUse_secondary);
}
fill_default_reconfig(carrier->servingcellconfigcommon,
reconfig_ies,
@@ -255,7 +327,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
1024);
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) {
+ } else if (get_softmodem_params()->do_ra || get_softmodem_params()->sa) {
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, ue_context_p->ue_id_rnti, 0, 0,rrc->module_id);
}
@@ -286,10 +358,11 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
(NR_SRB_ToAddModList_t *) NULL,
ue_context_p->ue_context.rb_config->drb_ToAddModList ,
ue_context_p->ue_context.rb_config->drb_ToReleaseList,
- 0xff,
- NULL,
- NULL,
- NULL,
+ (ue_context_p->ue_context.integrity_algorithm << 4) | ue_context_p->ue_context.ciphering_algorithm,
+ NULL, /* kRRCenc - unused */
+ NULL, /* kRRCint - unused */
+ kUPenc, /* kUPenc */
+ NULL, /* kUPint - unused */
NULL,
NULL,
ue_context_p->ue_context.secondaryCellGroup->rlc_BearerToAddModList);
diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c
index b1ec234214..633673444b 100644
--- a/openair2/RRC/NR/rrc_gNB_reconfig.c
+++ b/openair2/RRC/NR/rrc_gNB_reconfig.c
@@ -135,7 +135,7 @@ void fill_default_searchSpaceZero(NR_SearchSpace_t *ss0) {
// FIXME: update values from TS38.213 Section 10.1 Table 10.1-1: CCE aggregation levels and maximum number of PDCCH candidates per CCE aggregation level for CSS sets configured by searchSpaceSIB1
ss0->nrofCandidates->aggregationLevel1 = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0;
ss0->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0;
- ss0->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1;
+ ss0->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n2;
ss0->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0;
ss0->nrofCandidates->aggregationLevel16 = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0;
@@ -172,7 +172,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
secondaryCellGroup->cellGroupId = scg_id;
NR_RLC_BearerConfig_t *RLC_BearerConfig = calloc(1,sizeof(*RLC_BearerConfig));
nr_rlc_bearer_init(RLC_BearerConfig);
- if (get_softmodem_params()->do_ra)
+ if (get_softmodem_params()->do_ra || get_softmodem_params()->sa)
nr_drb_config(RLC_BearerConfig->rlc_Config, NR_RLC_Config_PR_um_Bi_Directional);
else
nr_drb_config(RLC_BearerConfig->rlc_Config, NR_RLC_Config_PR_am);
@@ -1329,7 +1329,10 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon
reconfig->nonCriticalExtension = NULL;
}
-void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) {
+void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig,
+ int eps_bearer_id, int rb_id,
+ e_NR_CipheringAlgorithm ciphering_algorithm,
+ e_NR_SecurityConfig__keyToUse key_to_use) {
rbconfig->srb_ToAddModList = NULL;
rbconfig->srb3_ToRelease = NULL;
@@ -1337,8 +1340,8 @@ void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) {
NR_DRB_ToAddMod_t *drb_ToAddMod = calloc(1,sizeof(*drb_ToAddMod));
drb_ToAddMod->cnAssociation = calloc(1,sizeof(*drb_ToAddMod->cnAssociation));
drb_ToAddMod->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity;
- drb_ToAddMod->cnAssociation->choice.eps_BearerIdentity= 5;
- drb_ToAddMod->drb_Identity = 1;
+ drb_ToAddMod->cnAssociation->choice.eps_BearerIdentity= eps_bearer_id;
+ drb_ToAddMod->drb_Identity = rb_id;
drb_ToAddMod->reestablishPDCP = NULL;
drb_ToAddMod->recoverPDCP = NULL;
drb_ToAddMod->pdcp_Config = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config));
@@ -1367,12 +1370,12 @@ void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) {
rbconfig->securityConfig = calloc(1,sizeof(*rbconfig->securityConfig));
rbconfig->securityConfig->securityAlgorithmConfig = calloc(1,sizeof(*rbconfig->securityConfig->securityAlgorithmConfig));
- rbconfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = NR_CipheringAlgorithm_nea0;
+ rbconfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = ciphering_algorithm;
rbconfig->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm=NULL;
rbconfig->securityConfig->keyToUse = calloc(1,sizeof(*rbconfig->securityConfig->keyToUse));
- *rbconfig->securityConfig->keyToUse = NR_SecurityConfig__keyToUse_master;
+ *rbconfig->securityConfig->keyToUse = key_to_use;
- xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)rbconfig);
+// xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)rbconfig);
}
/* Function to set or overwrite PTRS DL RRC parameters */
void rrc_config_dl_ptrs_params(NR_BWP_Downlink_t *bwp, int *ptrsNrb, int *ptrsMcs, int *epre_Ratio, int * reOffset)
diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c
index 5ad6746696..e21859ded8 100644
--- a/openair2/RRC/NR_UE/L2_interface_ue.c
+++ b/openair2/RRC/NR_UE/L2_interface_ue.c
@@ -33,6 +33,7 @@
#include "rrc_defs.h"
#include "rrc_proto.h"
#include "assertions.h"
+#include "rrc_vars.h"
typedef uint32_t channel_t;
@@ -50,7 +51,7 @@ nr_mac_rrc_data_ind_ue(
AssertFatal( nr_rrc_ue_decode_NR_BCCH_BCH_Message(module_id, gNB_index, (uint8_t*)pduP, pdu_len) == 0, "UE decode BCCH-BCH error!\n");
break;
case NR_BCCH_DL_SCH:
- AssertFatal( nr_rrc_ue_decode_NR_SIB1_Message(module_id, gNB_index, (uint8_t*)pduP, pdu_len) == 0, "UE decode BCCH-DLSCH error!\n");
+ AssertFatal( nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(module_id, gNB_index, (uint8_t*)pduP, pdu_len, 0, 0) == 0, "UE decode BCCH-DL-SCH error!\n");
break;
default:
break;
@@ -59,13 +60,36 @@ nr_mac_rrc_data_ind_ue(
return(0);
}
-int8_t mac_rrc_nr_data_req_ue(const module_id_t Mod_idP,
+int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP,
const int CC_id,
+ const uint8_t gNB_id,
const frame_t frameP,
const rb_id_t Srb_id,
- uint8_t *const buffer_pP ){
+ uint8_t *buffer_pP){
- // todo
+ switch(Srb_id){
+
+ case CCCH:
+
+ // TODO: Enable timer T300
+ //NR_UE_rrc_inst[Mod_idP].Info[gNB_id].T300_active = 1;
+ //NR_UE_rrc_inst[Mod_idP].Info[gNB_id].T300_cnt = 0;
+
+ LOG_D(NR_RRC, "nr_mac_rrc_data_req_ue: Payload size = %i\n", NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.payload_size);
+ memcpy(buffer_pP, (uint8_t*)NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.Payload, NR_UE_rrc_inst[Mod_idP].Srb0[gNB_id].Tx_buffer.payload_size);
+ for(int i = 0; i= MAKE_VERSION(9, 0, 0))
,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9
#endif
@@ -413,6 +414,18 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* rrc_config_path){
for(nr_ue=0;nr_uemodule_id].MBMS_flag < 3) // see -Q option
if (AMF_MODE_ENABLED) {
- rrc_ue_generate_RRCSetupRequest( ctxt_pP, gNB_index );
+ nr_rrc_ue_generate_RRCSetupRequest( ctxt_pP->module_id, gNB_index );
}
if (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State == NR_RRC_IDLE) {
@@ -1028,205 +1041,120 @@ int nr_decode_SI( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index
return 0;
}
-int nr_decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index, const uint8_t rsrq, const uint8_t rsrp ) {
- NR_SIB1_t *sib1 = NR_UE_rrc_inst[ctxt_pP->module_id].sib1[gNB_index];
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SIB1, VCD_FUNCTION_IN );
- LOG_I( RRC, "[UE %d] : Dumping SIB 1\n", ctxt_pP->module_id );
- const int n = sib1->cellAccessRelatedInfo.plmn_IdentityList.list.count;
- for (int i = 0; i < n; ++i) {
- NR_PLMN_Identity_t *PLMN_identity = sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[i]->plmn_IdentityList.list.array[0];
- int mccdigits = PLMN_identity->mcc->list.count;
- int mncdigits = PLMN_identity->mnc.list.count;
+int8_t check_requested_SI_List(module_id_t module_id, BIT_STRING_t requested_SI_List, NR_SIB1_t sib1) {
- int mcc;
- if (mccdigits == 2) {
- mcc = *PLMN_identity->mcc->list.array[0]*10 + *PLMN_identity->mcc->list.array[1];
- } else {
- mcc = *PLMN_identity->mcc->list.array[0]*100 + *PLMN_identity->mcc->list.array[1]*10 + *PLMN_identity->mcc->list.array[2];
+ if(sib1.si_SchedulingInfo) {
+
+ bool SIB_to_request[32] = {};
+
+ LOG_D(RRC, "SIBs broadcasting: ");
+ for(int i = 0; i < sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.count; i++) {
+ printf("SIB%li ", sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.array[i]->type + 2);
}
+ printf("\n");
- int mnc;
- if (mncdigits == 2) {
- mnc = *PLMN_identity->mnc.list.array[0]*10 + *PLMN_identity->mnc.list.array[1];
- } else {
- mnc = *PLMN_identity->mnc.list.array[0]*100 + *PLMN_identity->mnc.list.array[1]*10 + *PLMN_identity->mnc.list.array[2];
- }
+ LOG_D(RRC, "SIBs needed by UE: ");
+ for(int j = 0; j < 8*requested_SI_List.size; j++) {
+ if( ((requested_SI_List.buf[j/8]>>(j%8))&1) == 1) {
- 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;
+ printf("SIB%i ", j + 2);
- while (plmn_data[plmn_ind].mcc > 0) {
- 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",
- ((sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->trackingAreaCode->size == 2)?((sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->trackingAreaCode->buf[0]<<8) + sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->trackingAreaCode->buf[1]):0));
- LOG_I( RRC, "cellReservedForOperatorUse : raw:%ld decoded:%s\n", sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellReservedForOperatorUse,
- nr_SIBreserved(sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellReservedForOperatorUse) );
-
- LOG_I( RRC, "cellAccessRelatedInfo.cellIdentity : raw:%"PRIu32" decoded:%02x.%02x.%02x.%02x\n",
- BIT_STRING_to_uint32( &sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity ),
- sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity.buf[0],
- sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity.buf[1],
- sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity.buf[2],
- sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity.buf[3] >> sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity.bits_unused);
- //LOG_I( RRC, "cellAccessRelatedInfo.cellBarred : raw:%ld decoded:%s\n", sib1->cellAccessRelatedInfo.cellBarred, SIBbarred(sib1->cellAccessRelatedInfo.cellBarred) );
- //LOG_I( RRC, "cellAccessRelatedInfo.intraFreqReselection : raw:%ld decoded:%s\n", sib1->cellAccessRelatedInfo.intraFreqReselection, SIBallowed(sib1->cellAccessRelatedInfo.intraFreqReselection) );
- //LOG_I( RRC, "cellAccessRelatedInfo.csg_Indication : %d\n", sib1->cellAccessRelatedInfo.csg_Indication );
-
- //if (sib1->cellAccessRelatedInfo.csg_Identity)
- // LOG_I( RRC, "cellAccessRelatedInfo.csg_Identity : %"PRIu32"\n", BIT_STRING_to_uint32(sib1->cellAccessRelatedInfo.csg_Identity) );
- //else
- // LOG_I( RRC, "cellAccessRelatedInfo.csg_Identity : not defined\n" );
-
- LOG_I( RRC, "cellSelectionInfo.q_RxLevMin : %ld\n", sib1->cellSelectionInfo->q_RxLevMin );
-
- if (sib1->cellSelectionInfo->q_RxLevMinOffset)
- LOG_I( RRC, "cellSelectionInfo.q_RxLevMinOffset : %ld\n", *sib1->cellSelectionInfo->q_RxLevMinOffset );
- else
- LOG_I( RRC, "cellSelectionInfo.q_RxLevMinOffset : not defined\n" );
-
- //if (sib1->p_Max)
- // LOG_I( RRC, "p_Max : %ld\n", *sib1->p_Max );
- //else
- // LOG_I( RRC, "p_Max : not defined\n" );
-
- //LOG_I( RRC, "freqBandIndicator : %ld\n", sib1->freqBandIndicator );
-
- if (sib1->si_SchedulingInfo->schedulingInfoList.list.count > 0) {
- for (int i=0; isi_SchedulingInfo->schedulingInfoList.list.count; i++) {
- LOG_I( RRC, "si_Periodicity[%d] : %s\n", i, SIBPeriod[min(sib1->si_SchedulingInfo->schedulingInfoList.list.array[i]->si_Periodicity,7)]);
-
- if (sib1->si_SchedulingInfo->schedulingInfoList.list.array[i]->sib_MappingInfo.list.count > 0) {
- char temp[32 * sizeof(SIBType[0])] = {0}; // maxSIB==32
-
- for (int j=0; jsi_SchedulingInfo->schedulingInfoList.list.array[i]->sib_MappingInfo.list.count; j++) {
- sprintf( temp + j*sizeof(SIBType[0]), "%*s ", (int)sizeof(SIBType[0])-1, SIBType[min(sib1->si_SchedulingInfo->schedulingInfoList.list.array[i]->sib_MappingInfo.list.array[0]->type,11)] );
+ SIB_to_request[j] = true;
+ for(int i = 0; i < sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.count; i++) {
+ if(sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.array[i]->type == j) {
+ SIB_to_request[j] = false;
+ break;
+ }
}
- LOG_I( RRC, "siSchedulingInfoSIBType[%d] : %s\n", i, temp );
+ }
+ }
+ printf("\n");
+
+ LOG_D(RRC, "SIBs to request by UE: ");
+ bool do_ra = false;
+ for(int j = 0; j < 8*requested_SI_List.size; j++) {
+ if(SIB_to_request[j]) {
+ printf("SIB%i ", j + 2);
+ do_ra = true;
+ }
+ }
+ printf("\n");
+
+ if(do_ra) {
+
+ NR_UE_rrc_inst[module_id].ra_trigger = REQUEST_FOR_OTHER_SI;
+ get_softmodem_params()->do_ra = 1;
+
+ if(sib1.si_SchedulingInfo->si_RequestConfig) {
+ LOG_D(RRC, "Trigger contention-free RA procedure (ra_trigger = %i)\n", NR_UE_rrc_inst[module_id].ra_trigger);
} else {
- LOG_I( RRC, "mapping list %d is null\n", i );
+ LOG_D(RRC, "Trigger contention-based RA procedure (ra_trigger = %i)\n", NR_UE_rrc_inst[module_id].ra_trigger);
}
+
}
- } else {
- LOG_E( RRC, "siSchedulingInfoPeriod[0] : PROBLEM!!!\n" );
- return -1;
+
}
- if (sib1->servingCellConfigCommon->tdd_UL_DL_ConfigurationCommon) {
- //TODO
- }
-
- LOG_I( RRC, "siWindowLength : %s\n", siWindowLength[min(sib1->si_SchedulingInfo->si_WindowLength,8)] );
- //LOG_I( RRC, "systemInfoValueTag : %ld\n", sib1->systemInfoValueTag );
- NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIperiod = siPeriod_int[sib1->si_SchedulingInfo->schedulingInfoList.list.array[0]->si_Periodicity];
- NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIwindowsize = siWindowLength_int[sib1->si_SchedulingInfo->si_WindowLength];
- LOG_I( RRC, "[FRAME unknown][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB1 params gNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n",
- ctxt_pP->module_id, gNB_index, ctxt_pP->module_id );
- //rrc_mac_config_req_ue
- LOG_I(RRC,"Setting SIStatus bit 0 to 1\n");
- NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus = 1;
- //NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIB1systemInfoValueTag = sib1->systemInfoValueTag;
-
- if (AMF_MODE_ENABLED) {
- int cell_valid = 0;
-
- //if (sib1->cellAccessRelatedInfo.cellBarred == LTE_SystemInformationBlockType1__cellAccessRelatedInfo__cellBarred_notBarred) {
- /* Cell is not barred */
- int plmn;
- int plmn_number;
- plmn_number = sib1->cellAccessRelatedInfo.plmn_IdentityList.list.count;
-
- /* Compare requested PLMN and PLMNs from SIB1*/
- for (plmn = 0; plmn < plmn_number; plmn++) {
- NR_PLMN_Identity_t *plmn_Identity;
- plmn_Identity = sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[plmn]->plmn_IdentityList.list.array[0];
-
- if (
- (
- (plmn_Identity->mcc == NULL)
- ||
- (
- (NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MCCdigit1 == *(plmn_Identity->mcc->list.array[0])) &&
- (NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MCCdigit2 == *(plmn_Identity->mcc->list.array[1])) &&
- (NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MCCdigit3 == *(plmn_Identity->mcc->list.array[2]))
- )
- )
- &&
- (NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit1 == *(plmn_Identity->mnc.list.array[0]))
- &&
- (NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit2 == *(plmn_Identity->mnc.list.array[1]))
- &&
- (
- ((NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit3 == 0xf) && (plmn_Identity->mnc.list.count == 2))
- ||
- (NR_UE_rrc_inst[ctxt_pP->module_id].plmnID.MNCdigit3 == *(plmn_Identity->mnc.list.array[2]))
- )
- ) {
- /* PLMN match, send a confirmation to NAS */
- MessageDef *msg_p;
- msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CELL_SELECTION_CNF);
- NAS_CELL_SELECTION_CNF (msg_p).errCode = AS_SUCCESS;
- NAS_CELL_SELECTION_CNF (msg_p).cellID = BIT_STRING_to_uint32(&sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellIdentity);
- NAS_CELL_SELECTION_CNF (msg_p).tac = BIT_STRING_to_uint16(sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->trackingAreaCode);
- NAS_CELL_SELECTION_CNF (msg_p).rat = 0xFF;
- NAS_CELL_SELECTION_CNF (msg_p).rsrq = rsrq;
- NAS_CELL_SELECTION_CNF (msg_p).rsrp = rsrp;
- itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p);
- cell_valid = 1;
- NR_UE_rrc_inst[ctxt_pP->module_id].selected_plmn_identity = plmn + 1;
- break;
- }
- }
- //}
-
- if (cell_valid == 0) {
- /* Cell can not be used, ask PHY to try the next one */
- MessageDef *msg_p;
- msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, PHY_FIND_NEXT_CELL_REQ);
- itti_send_msg_to_task(TASK_PHY_UE, ctxt_pP->instance, msg_p);
- LOG_E(RRC,
- "Synched with a cell, but PLMN doesn't match our SIM "
- "(selected_plmn_identity %ld), the message PHY_FIND_NEXT_CELL_REQ "
- "is sent but lost in current UE implementation!\n",
- NR_UE_rrc_inst[ctxt_pP->module_id].selected_plmn_identity);
- }
- }
-
- VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SIB1, VCD_FUNCTION_OUT );
return 0;
}
-int nr_decode_BCCH_DLSCH_Message(
- const protocol_ctxt_t *const ctxt_pP,
- const uint8_t gNB_index,
- uint8_t *const Sdu,
- const uint8_t Sdu_len,
- const uint8_t rsrq,
- const uint8_t rsrp ) {
+int8_t nr_rrc_ue_generate_ra_msg(module_id_t module_id, uint8_t gNB_index) {
+
+ switch(NR_UE_rrc_inst[module_id].ra_trigger){
+ case INITIAL_ACCESS_FROM_RRC_IDLE:
+ // After SIB1 is received, prepare RRCConnectionRequest
+ nr_rrc_ue_generate_RRCSetupRequest(module_id,gNB_index);
+ break;
+ case RRC_CONNECTION_REESTABLISHMENT:
+ AssertFatal(1==0, "ra_trigger not implemented yet!\n");
+ break;
+ case DURING_HANDOVER:
+ AssertFatal(1==0, "ra_trigger not implemented yet!\n");
+ break;
+ case NON_SYNCHRONISED:
+ AssertFatal(1==0, "ra_trigger not implemented yet!\n");
+ break;
+ case TRANSITION_FROM_RRC_INACTIVE:
+ AssertFatal(1==0, "ra_trigger not implemented yet!\n");
+ break;
+ case TO_ESTABLISH_TA:
+ AssertFatal(1==0, "ra_trigger not implemented yet!\n");
+ break;
+ case REQUEST_FOR_OTHER_SI:
+ AssertFatal(1==0, "ra_trigger not implemented yet!\n");
+ break;
+ case BEAM_FAILURE_RECOVERY:
+ AssertFatal(1==0, "ra_trigger not implemented yet!\n");
+ break;
+ default:
+ AssertFatal(1==0, "Invalid ra_trigger value!\n");
+ break;
+ }
+
+ return 0;
+}
+
+int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(
+ module_id_t module_id,
+ const uint8_t gNB_index,
+ uint8_t *const Sdu,
+ const uint8_t Sdu_len,
+ const uint8_t rsrq,
+ const uint8_t rsrp) {
+
NR_BCCH_DL_SCH_Message_t *bcch_message = NULL;
- NR_SIB1_t *sib1 = NR_UE_rrc_inst[ctxt_pP->module_id].sib1[gNB_index];
+ NR_SIB1_t *sib1 = NR_UE_rrc_inst[module_id].sib1[gNB_index];
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_IN );
- if (((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&1) == 1) && // SIB1 received
- (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIcnt == sib1->si_SchedulingInfo->schedulingInfoList.list.count)) {
+ if (((NR_UE_rrc_inst[module_id].Info[gNB_index].SIStatus&1) == 1) && // SIB1 received
+ (NR_UE_rrc_inst[module_id].Info[gNB_index].SIcnt == sib1->si_SchedulingInfo->schedulingInfoList.list.count)) {
// to prevent memory bloating
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT );
return 0;
}
- nr_rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_RECEIVING_SIB_NR );
-
- if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
- xer_fprint(stdout, &asn_DEF_NR_BCCH_DL_SCH_Message,(void *)bcch_message );
- }
+ nr_rrc_set_sub_state( module_id, RRC_SUB_STATE_IDLE_RECEIVING_SIB_NR );
asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
&asn_DEF_NR_BCCH_DL_SCH_Message,
@@ -1234,11 +1162,15 @@ int nr_decode_BCCH_DLSCH_Message(
(const void *)Sdu,
Sdu_len );
+ if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
+ xer_fprint(stdout, &asn_DEF_NR_BCCH_DL_SCH_Message,(void *)bcch_message );
+ }
+
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
- LOG_E( RRC, "[UE %"PRIu8"] Failed to decode BCCH_DLSCH_MESSAGE (%zu bits)\n",
- ctxt_pP->module_id,
+ LOG_E( NR_RRC, "[UE %"PRIu8"] Failed to decode BCCH_DLSCH_MESSAGE (%zu bits)\n",
+ module_id,
dec_rval.consumed );
- log_dump(RRC, Sdu, Sdu_len, LOG_DUMP_CHAR," Received bytes:\n" );
+ log_dump(NR_RRC, Sdu, Sdu_len, LOG_DUMP_CHAR," Received bytes:\n" );
// free the memory
SEQUENCE_free( &asn_DEF_LTE_BCCH_DL_SCH_Message, (void *)bcch_message, 1 );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT );
@@ -1248,35 +1180,53 @@ int nr_decode_BCCH_DLSCH_Message(
if (bcch_message->message.present == NR_BCCH_DL_SCH_MessageType_PR_c1) {
switch (bcch_message->message.choice.c1->present) {
case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1:
- if ((ctxt_pP->frame % 2) == 0) {
- // even frame
- if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&1) == 0) {
- NR_SIB1_t *sib1 = NR_UE_rrc_inst[ctxt_pP->module_id].sib1[gNB_index];
- memcpy( (void *)sib1,
- (void *)bcch_message->message.choice.c1->choice.systemInformationBlockType1,
- sizeof(NR_SIB1_t) );
- LOG_D( RRC, "[UE %"PRIu8"] Decoding First SIB1\n", ctxt_pP->module_id );
- nr_decode_SIB1( ctxt_pP, gNB_index, rsrq, rsrp );
+ if ((NR_UE_rrc_inst[module_id].Info[gNB_index].SIStatus&1) == 0) {
+ NR_SIB1_t *sib1 = NR_UE_rrc_inst[module_id].sib1[gNB_index];
+ if(sib1 != NULL){
+ SEQUENCE_free(&asn_DEF_NR_SIB1, (void *)sib1, 1 );
+ }
+
+ sib1 = bcch_message->message.choice.c1->choice.systemInformationBlockType1;
+ if (*(int64_t*)sib1 != 1) {
+ NR_UE_rrc_inst[module_id].sib1[gNB_index] = sib1;
+ 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");
+
+ // FIXME: improve condition for the RA trigger
+ // Check for on-demand not broadcasted SI
+ 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;
+ // TODO: remove flag after full RA procedures implemented
+ get_softmodem_params()->do_ra = 1;
+ }
+ nr_rrc_ue_generate_ra_msg(module_id,gNB_index);
+ } else {
+ LOG_E(NR_RRC, "SIB1 not decoded\n");
}
}
-
break;
case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformation:
- if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&1) == 1) {
+ if ((NR_UE_rrc_inst[module_id].Info[gNB_index].SIStatus&1) == 1) {
+ LOG_W(NR_RRC, "Decoding SI not implemented yet\n");
+ // TODO: Decode SI
+ /*
// SIB1 with schedulingInfoList is available
- NR_SystemInformation_t *si = NR_UE_rrc_inst[ctxt_pP->module_id].si[gNB_index];
+ NR_SystemInformation_t *si = NR_UE_rrc_inst[module_id].si[gNB_index];
+
memcpy( si,
bcch_message->message.choice.c1->choice.systemInformation,
sizeof(NR_SystemInformation_t) );
- LOG_I( RRC, "[UE %"PRIu8"] Decoding SI for frameP %"PRIu32"\n",
- ctxt_pP->module_id,
- ctxt_pP->frame );
+ LOG_I(NR_RRC, "[UE %"PRIu8"] Decoding SI\n", module_id);
nr_decode_SI( ctxt_pP, gNB_index );
- //if (nfapi_mode == 3)
- //UE_mac_inst[ctxt_pP->module_id].SI_Decoded = 1;
- }
+ if (nfapi_mode == 3)
+ UE_mac_inst[ctxt_pP->module_id].SI_Decoded = 1;
+ */
+ }
break;
case NR_BCCH_DL_SCH_MessageType__c1_PR_NOTHING:
@@ -1285,10 +1235,10 @@ int nr_decode_BCCH_DLSCH_Message(
}
}
- if (nr_rrc_get_sub_state(ctxt_pP->module_id) == RRC_SUB_STATE_IDLE_SIB_COMPLETE_NR) {
+ if (nr_rrc_get_sub_state(module_id) == RRC_SUB_STATE_IDLE_SIB_COMPLETE_NR) {
//if ( (NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data != NULL) || (!AMF_MODE_ENABLED)) {
- rrc_ue_generate_RRCSetupRequest(ctxt_pP, 0);
- nr_rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_CONNECTING );
+ nr_rrc_ue_generate_RRCSetupRequest(module_id, 0);
+ nr_rrc_set_sub_state( module_id, RRC_SUB_STATE_IDLE_CONNECTING );
//}
}
@@ -1488,41 +1438,6 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB
return rval;
}
-/*brief decode SIB1 message*/
-int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len) {
-
- NR_BCCH_DL_SCH_Message_t *bcch_message = NULL;
-
- asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
- &asn_DEF_NR_BCCH_DL_SCH_Message,
- (void **)&bcch_message,
- (const void *)bufferP,
- buffer_len);
-
- if ((dec_rval.code != RC_OK) || (dec_rval.consumed == 0)) {
- LOG_D(RRC,"NR_BCCH_DL_SCH decode error\n");
- SEQUENCE_free( &asn_DEF_NR_BCCH_DL_SCH_Message, (void *)bcch_message, 1 );
- return -1;
- }
- else {
- NR_SIB1_t *sib1 = NR_UE_rrc_inst[module_id].sib1[gNB_index];
- if(sib1 != NULL){
- SEQUENCE_free(&asn_DEF_NR_BCCH_BCH_Message, (void *)sib1, 1 );
- }
- sib1 = bcch_message->message.choice.c1->choice.systemInformationBlockType1;
- if (*(int64_t*)sib1 != 1) {
- LOG_I(RRC, "SIB1 decoded\n");
- if( g_log->log_component[RRC].level >= OAILOG_DEBUG )
- xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void*)sib1);
- }
- else
- LOG_E(PHY, "sib1 is starting by 8 times 0\n");
- }
-
- return 0;
-}
-
-
// from NR SRB3
int8_t nr_rrc_ue_decode_NR_DL_DCCH_Message(
const module_id_t module_id,
@@ -1783,10 +1698,10 @@ nr_rrc_ue_process_securityModeCommand(
}
//-----------------------------------------------------------------------------
-void rrc_ue_generate_RRCSetupRequest( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index ) {
+void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index) {
uint8_t i=0,rv[6];
- if(NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size ==0) {
+ if(NR_UE_rrc_inst[module_id].Srb0[gNB_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++) {
@@ -1800,16 +1715,16 @@ void rrc_ue_generate_RRCSetupRequest( const protocol_ctxt_t *const ctxt_pP, cons
}
LOG_T(NR_RRC,"\n");
- NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size =
- do_RRCSetupRequest(
- ctxt_pP->module_id,
- (uint8_t *)NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload,
- rv);
- LOG_I(NR_RRC,"[UE %d] : Frame %d, Logical Channel UL-CCCH (SRB0), Generating RRCSetupRequest (bytes %d, eNB %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);
+ NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size =
+ do_RRCSetupRequest(
+ module_id,
+ (uint8_t *)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);
- for (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]);
+ for (i=0; imodule_id].defaultDRB,
// NULL);
// Refresh DRBs
@@ -2557,7 +2474,7 @@ void *rrc_nrue_task( void *args_p ) {
NR_RRC_MAC_BCCH_DATA_IND (msg_p).frame, NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index);
// PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_NO, NOT_A_RNTI, RRC_MAC_BCCH_DATA_IND (msg_p).frame, 0);
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NOT_A_RNTI, NR_RRC_MAC_BCCH_DATA_IND (msg_p).frame, 0,NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index);
- nr_decode_BCCH_DLSCH_Message (&ctxt,
+ nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message (ctxt.module_id,
NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index,
NR_RRC_MAC_BCCH_DATA_IND (msg_p).sdu,
NR_RRC_MAC_BCCH_DATA_IND (msg_p).sdu_size,
diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h
index 52bd6c564a..f4ce474657 100644
--- a/openair2/RRC/NR_UE/rrc_defs.h
+++ b/openair2/RRC/NR_UE/rrc_defs.h
@@ -77,6 +77,30 @@ typedef struct OAI_NR_UECapability_s {
NR_UE_NR_Capability_t *UE_NR_Capability;
} OAI_NR_UECapability_t;
+typedef enum requested_SI_List_e {
+ SIB2 = 1,
+ SIB3 = 2,
+ SIB4 = 4,
+ SIB5 = 8,
+ SIB6 = 16,
+ SIB7 = 32,
+ SIB8 = 64,
+ SIB9 = 128
+} requested_SI_List_t;
+
+// 3GPP TS 38.300 Section 9.2.6
+typedef enum RA_trigger_e {
+ RA_NOT_RUNNING,
+ INITIAL_ACCESS_FROM_RRC_IDLE,
+ RRC_CONNECTION_REESTABLISHMENT,
+ DURING_HANDOVER,
+ NON_SYNCHRONISED,
+ TRANSITION_FROM_RRC_INACTIVE,
+ TO_ESTABLISH_TA,
+ REQUEST_FOR_OTHER_SI,
+ BEAM_FAILURE_RECOVERY,
+} RA_trigger_t;
+
typedef struct NR_UE_RRC_INST_s {
NR_MeasConfig_t *meas_config;
@@ -99,10 +123,13 @@ typedef struct NR_UE_RRC_INST_s {
NR_SRB_INFO_TABLE_ENTRY Srb2[NB_CNX_UE];
uint8_t MBMS_flag;
- OAI_NR_UECapability_t *UECap;
- uint8_t *UECapability;
+ OAI_NR_UECapability_t *UECap;
+ uint8_t *UECapability;
uint8_t UECapability_size;
+ RA_trigger_t ra_trigger;
+ BIT_STRING_t requested_SI_List;
+
NR_SystemInformation_t *si[NB_CNX_UE];
NR_SIB1_t *sib1[NB_CNX_UE];
NR_SIB2_t *sib2[NB_CNX_UE];
diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h
index 4019248441..0acf6db634 100644
--- a/openair2/RRC/NR_UE/rrc_proto.h
+++ b/openair2/RRC/NR_UE/rrc_proto.h
@@ -86,12 +86,14 @@ int8_t nr_rrc_ue_process_radio_bearer_config(NR_RadioBearerConfig_t *radio_beare
\param sdu_len length of buffer*/
int8_t nr_rrc_ue_decode_NR_BCCH_BCH_Message(const module_id_t module_id, const uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len);
-/**\brief decode NR SIB1 message
+/**\brief decode NR BCCH-DLSCH (SI) messages
\param module_idP module id
\param gNB_index gNB index
- \param sduP pointer to buffer of ASN message
- \param sdu_len length of buffer*/
-int8_t nr_rrc_ue_decode_NR_SIB1_Message(module_id_t module_id, uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len);
+ \param sduP pointer to buffer of ASN message BCCH-DLSCH
+ \param sdu_len length of buffer
+ \param rsrq RSRQ
+ \param rsrp RSRP*/
+int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(const module_id_t module_id, const uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len, const uint8_t rsrq, const uint8_t rsrp);
/**\brief Decode NR DCCH from gNB, sent from lower layer through SRB3
\param module_id module id
@@ -112,24 +114,25 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, cons
/**\brief
\param module_id module id
\param CC_id component carrier id
+ \param gNB_index gNB index
\param frame_t frameP
\param rb_id_t SRB id
\param buffer_pP pointer to buffer*/
-int8_t mac_rrc_nr_data_req_ue(const module_id_t Mod_idP,
+int8_t nr_mac_rrc_data_req_ue(const module_id_t Mod_idP,
const int CC_id,
+ const uint8_t gNB_id,
const frame_t frameP,
const rb_id_t Srb_id,
- uint8_t *const buffer_pP);
-
+ uint8_t *buffer_pP);
/**\brief RRC UE task.
\param void *args_p Pointer on arguments to start the task. */
void *rrc_nrue_task(void *args_p);
/**\brief RRC UE generate RRCSetupRequest message.
- \param ctxt_pP protocol context
+ \param module_id module id
\param gNB_index gNB index */
-void rrc_ue_generate_RRCSetupRequest( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index );
+void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index);
/** @}*/
#endif
diff --git a/openair2/SIMULATION/NR_RRC/itti_sim.c b/openair2/SIMULATION/NR_RRC/itti_sim.c
index e11a92d691..9b35ea6721 100644
--- a/openair2/SIMULATION/NR_RRC/itti_sim.c
+++ b/openair2/SIMULATION/NR_RRC/itti_sim.c
@@ -624,7 +624,7 @@ int main( int argc, char **argv )
0);
NR_UE_rrc_inst[ctxt.module_id].Info[0].State = RRC_SI_RECEIVED;
- rrc_ue_generate_RRCSetupRequest(&ctxt, 0);
+ nr_rrc_ue_generate_RRCSetupRequest(ctxt.module_id, 0);
printf("Entering ITTI signals handler\n");
itti_wait_tasks_end();
diff --git a/openair2/UTIL/OSA/osa_defs.h b/openair2/UTIL/OSA/osa_defs.h
index 304dd07042..6334658683 100644
--- a/openair2/UTIL/OSA/osa_defs.h
+++ b/openair2/UTIL/OSA/osa_defs.h
@@ -53,6 +53,8 @@ typedef enum {
//int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t **keNB);
+int derive_skgNB(const uint8_t *keNB, const uint16_t sk_counter, uint8_t *skgNB);
+
int derive_key(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id,
const uint8_t key[32], uint8_t **out);
int nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id,
diff --git a/openair2/UTIL/OSA/osa_key_deriver.c b/openair2/UTIL/OSA/osa_key_deriver.c
index 71c7793fa0..159ee7f159 100644
--- a/openair2/UTIL/OSA/osa_key_deriver.c
+++ b/openair2/UTIL/OSA/osa_key_deriver.c
@@ -159,3 +159,27 @@ int derive_keNB(const uint8_t key[32], const uint32_t nas_count, uint8_t **keNB)
return 0;
}
*/
+
+int derive_skgNB(const uint8_t *keNB, const uint16_t sk_counter, uint8_t *skgNB)
+{
+ uint8_t *out;
+ uint8_t s[5];
+
+ /* FC is 0x1c (see 3gpp 33.401 annex A.15) */
+ s[0] = 0x1c;
+
+ /* put sk_counter */
+ s[1] = (sk_counter >> 8) & 0xff;
+ s[2] = sk_counter & 0xff;
+
+ /* put length of sk_counter (2) */
+ s[3] = 0x00;
+ s[4] = 0x02;
+
+ kdf(s, 5, keNB, 32, &out, 32);
+
+ memcpy(skgNB, out, 32);
+ free(out);
+
+ return 0;
+}
diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c
index f0e0fa9c23..1fb28ea05b 100644
--- a/openair2/X2AP/x2ap_eNB_handler.c
+++ b/openair2/X2AP/x2ap_eNB_handler.c
@@ -536,6 +536,14 @@ int x2ap_eNB_handle_x2_setup_response(instance_t instance,
return -1;
}
+ if((x2ap_eNB_data->state == X2AP_ENB_STATE_CONNECTED) ||
+ (x2ap_eNB_data->state == X2AP_ENB_STATE_READY))
+
+ {
+ X2AP_ERROR("Received Unexpexted X2 Setup Response Message\n");
+ return -1;
+ }
+
X2AP_DEBUG("Received a new X2 setup response\n");
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_X2SetupResponse_IEs_t, ie, x2SetupResponse,
@@ -662,6 +670,14 @@ int x2ap_eNB_handle_x2_setup_failure(instance_t instance,
return -1;
}
+ if((x2ap_eNB_data->state == X2AP_ENB_STATE_CONNECTED) ||
+ (x2ap_eNB_data->state == X2AP_ENB_STATE_READY))
+
+ {
+ X2AP_ERROR("Received Unexpexted X2 Setup Failure Message\n");
+ return -1;
+ }
+
X2AP_DEBUG("Received a new X2 setup failure\n");
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_X2SetupFailure_IEs_t, ie, x2SetupFailure,
@@ -730,6 +746,7 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance,
X2AP_ProtocolIE_ID_id_Old_eNB_UE_X2AP_ID, true);
if (ie == NULL ) {
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
+ itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
return -1;
}
@@ -750,7 +767,11 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance,
//measResultListEUTRA.list.array[ncell_index]->physCellId;
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequest_IEs_t, ie, x2HandoverRequest,
X2AP_ProtocolIE_ID_id_GUMMEI_ID, true);
-
+ if (ie == NULL ) {
+ X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
+ itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
+ return -1;
+ }
TBCD_TO_MCC_MNC(&ie->value.choice.ECGI.pLMN_Identity, X2AP_HANDOVER_REQ(msg).ue_gummei.mcc,
X2AP_HANDOVER_REQ(msg).ue_gummei.mnc, X2AP_HANDOVER_REQ(msg).ue_gummei.mnc_len);
OCTET_STRING_TO_INT8(&ie->value.choice.GUMMEI.mME_Code, X2AP_HANDOVER_REQ(msg).ue_gummei.mme_code);
@@ -761,6 +782,7 @@ int x2ap_eNB_handle_handover_preparation (instance_t instance,
if (ie == NULL ) {
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
+ itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
return -1;
}
@@ -872,6 +894,7 @@ int x2ap_eNB_handle_handover_response (instance_t instance,
if (ie == NULL ) {
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
+ itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
return -1;
}
@@ -882,6 +905,7 @@ int x2ap_eNB_handle_handover_response (instance_t instance,
if (ie == NULL ) {
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
+ itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
return -1;
}
@@ -912,6 +936,7 @@ int x2ap_eNB_handle_handover_response (instance_t instance,
if (ie == NULL ) {
X2AP_ERROR("%s %d: ie is a NULL pointer \n", __FILE__, __LINE__);
+ itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
return -1;
}else{
if (ie->value.choice.E_RABs_Admitted_List.list.count > 0) {
@@ -959,6 +984,12 @@ int x2ap_eNB_handle_handover_response (instance_t instance,
X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_HandoverRequestAcknowledge_IEs_t, ie, x2HandoverRequestAck,
X2AP_ProtocolIE_ID_id_TargeteNBtoSource_eNBTransparentContainer, true);
+ if (ie == NULL ) {
+ X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
+ itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
+ return -1;
+ }
+
X2AP_TargeteNBtoSource_eNBTransparentContainer_t *c = &ie->value.choice.TargeteNBtoSource_eNBTransparentContainer;
if (c->size > 1024 /* TODO: this is the size of rrc_buffer in struct x2ap_handover_req_ack_s */)
@@ -1012,6 +1043,7 @@ int x2ap_eNB_handle_ue_context_release (instance_t instance,
if (ie == NULL ) {
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
+ itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
return -1;
}
@@ -1022,6 +1054,7 @@ int x2ap_eNB_handle_ue_context_release (instance_t instance,
if (ie == NULL ) {
X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__);
+ itti_free(ITTI_MSG_ORIGIN_ID(msg), msg);
return -1;
}
diff --git a/openair3/GTPV1-U/gtpv1u_eNB.c b/openair3/GTPV1-U/gtpv1u_eNB.c
index 4769380d18..847002ab44 100644
--- a/openair3/GTPV1-U/gtpv1u_eNB.c
+++ b/openair3/GTPV1-U/gtpv1u_eNB.c
@@ -1211,7 +1211,7 @@ int gtpv1u_eNB_init(void) {
//gtpv1u_data_g.udp_data;
RC.gtpv1u_data_g->seq_num = 0;
RC.gtpv1u_data_g->restart_counter = 0;
-
+ RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up = 0;
/* Initializing GTPv1-U stack */
if ((rc = nwGtpv1uInitialize(&RC.gtpv1u_data_g->gtpv1u_stack, GTPU_STACK_ENB)) != NW_GTPV1U_OK) {
LOG_E(GTPU, "Failed to setup nwGtpv1u stack %x\n", rc);
diff --git a/openair3/NAS/COMMON/EMM/MSG/AttachAccept.c b/openair3/NAS/COMMON/EMM/MSG/AttachAccept.c
index 8ac43cf7b1..637d930226 100644
--- a/openair3/NAS/COMMON/EMM/MSG/AttachAccept.c
+++ b/openair3/NAS/COMMON/EMM/MSG/AttachAccept.c
@@ -190,7 +190,6 @@ int decode_attach_accept(attach_accept_msg *attach_accept, uint8_t *buffer, uint
default:
errorCodeDecoder = TLV_DECODE_UNEXPECTED_IEI;
LOG_TRACE(WARNING, "DECODE_UNEXPECTED_IEI %x (4 bits)", ieiDecoded);
- AssertFatal(0, " ");
return TLV_DECODE_UNEXPECTED_IEI;
}
}
diff --git a/openair3/NAS/COMMON/IES/SupportedCodecList.c b/openair3/NAS/COMMON/IES/SupportedCodecList.c
index 3a69eee366..15a2fecaa0 100644
--- a/openair3/NAS/COMMON/IES/SupportedCodecList.c
+++ b/openair3/NAS/COMMON/IES/SupportedCodecList.c
@@ -43,13 +43,17 @@ int decode_supported_codec_list(SupportedCodecList *supportedcodeclist, uint8_t
CHECK_LENGTH_DECODER(len - decoded, ielen);
supportedcodeclist->systemidentification = *(buffer + decoded);
decoded++;
+ ielen--;
supportedcodeclist->lengthofbitmap = *(buffer + decoded);
decoded++;
+ ielen--;
//IES_DECODE_U16(supportedcodeclist->codecbitmap, *(buffer + decoded));
IES_DECODE_U16(buffer, decoded, supportedcodeclist->codecbitmap);
+ ielen=ielen -2;
#if defined (NAS_DEBUG)
dump_supported_codec_list_xml(supportedcodeclist, iei);
#endif
+ decoded = decoded + ielen;
return decoded;
}
int encode_supported_codec_list(SupportedCodecList *supportedcodeclist, uint8_t iei, uint8_t *buffer, uint32_t len)
diff --git a/openair3/NAS/UE/EMM/SAP/emm_as.c b/openair3/NAS/UE/EMM/SAP/emm_as.c
index 99a3763dea..10b118eac0 100644
--- a/openair3/NAS/UE/EMM/SAP/emm_as.c
+++ b/openair3/NAS/UE/EMM/SAP/emm_as.c
@@ -443,14 +443,14 @@ static int _emm_as_data_ind(nas_user_t *user, const emm_as_data_t *msg, int *emm
EPS_MOBILITY_MANAGEMENT_MESSAGE) {
/* Process EMM data */
rc = _emm_as_recv(user, plain_msg, bytes, emm_cause);
+ free(plain_msg);
} else if (header.protocol_discriminator ==
EPS_SESSION_MANAGEMENT_MESSAGE) {
const OctetString data = {bytes, (uint8_t *)plain_msg};
/* Foward ESM data to EPS session management */
rc = lowerlayer_data_ind(user, &data);
+ free(plain_msg);
}
-
- free(plain_msg);
}
} else {
/* Process successfull lower layer transfer indication */
diff --git a/openair3/NAS/UE/EMM/SecurityModeControl.c b/openair3/NAS/UE/EMM/SecurityModeControl.c
index 67bfaf784e..b27270fadc 100644
--- a/openair3/NAS/UE/EMM/SecurityModeControl.c
+++ b/openair3/NAS/UE/EMM/SecurityModeControl.c
@@ -296,16 +296,16 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi,
else {
/* Setup EMM cause code */
emm_cause = EMM_CAUSE_SECURITY_MODE_REJECTED;
-
- /* Release security mode control internal data */
- if (security_data->kenb.value) {
- free(security_data->kenb.value);
- security_data->kenb.value = NULL;
- security_data->kenb.length = 0;
- }
}
}
+ /* Release security mode control internal data */
+ if (security_data->kenb.value) {
+ free(security_data->kenb.value);
+ security_data->kenb.value = NULL;
+ security_data->kenb.length = 0;
+ }
+
/* Setup EMM procedure handler to be executed upon receiving
* lower layer notification */
rc = emm_proc_lowerlayer_initialize(user->lowerlayer_data, NULL, NULL, NULL, NULL);
diff --git a/openair3/S1AP/s1ap_common.h b/openair3/S1AP/s1ap_common.h
index 77d03f4ae4..efac0201a3 100644
--- a/openair3/S1AP/s1ap_common.h
+++ b/openair3/S1AP/s1ap_common.h
@@ -106,7 +106,12 @@ extern int asn1_xer_print;
if (ie == NULL ) { \
S1AP_ERROR("S1AP_FIND_PROTOCOLIE_BY_ID: %s %d: ie is NULL\n",__FILE__,__LINE__);\
} \
- if (mandatory) DevAssert(ie != NULL); \
+ if (mandatory) { \
+ if (ie == NULL) { \
+ S1AP_ERROR("S1AP_FIND_PROTOCOLIE_BY_ID: %s %d: ie is NULL\n",__FILE__,__LINE__);\
+ return -1; \
+ } \
+ } \
} while(0)
/** \brief Function callback prototype.
**/
diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c
index 31ea3359da..e528c9e53e 100644
--- a/openair3/S1AP/s1ap_eNB.c
+++ b/openair3/S1AP/s1ap_eNB.c
@@ -73,6 +73,42 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *
void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp);
+static int s1ap_sctp_req(s1ap_eNB_instance_t *instance_p,
+ s1ap_eNB_mme_data_t *s1ap_mme_data_p);
+void s1ap_eNB_timer_expired(instance_t instance,
+ timer_has_expired_t *msg_p);
+
+int s1ap_timer_setup(
+ uint32_t interval_sec,
+ uint32_t interval_us,
+ task_id_t task_id,
+ int32_t instance,
+ uint32_t timer_kind,
+ timer_type_t type,
+ void *timer_arg,
+ long *timer_id)
+{
+ uint32_t *timeoutArg=NULL;
+ int ret=0;
+ timeoutArg=malloc(sizeof(uint32_t));
+ *timeoutArg=timer_kind;
+ ret=timer_setup(interval_sec,
+ interval_us,
+ task_id,
+ instance,
+ type,
+ (void*)timeoutArg,
+ timer_id);
+ return ret;
+}
+
+int s1ap_timer_remove(long timer_id)
+{
+ int ret;
+ ret=timer_remove(timer_id);
+ return ret;
+}
+
uint32_t s1ap_generate_eNB_id(void) {
char *out;
char hostname[50];
@@ -98,7 +134,7 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p,
MessageDef *message_p = NULL;
sctp_new_association_req_t *sctp_new_association_req_p = NULL;
s1ap_eNB_mme_data_t *s1ap_mme_data_p = NULL;
- struct s1ap_eNB_mme_data_s *mme = NULL;
+// struct s1ap_eNB_mme_data_s *mme = NULL;
DevAssert(instance_p != NULL);
DevAssert(mme_ip_address != NULL);
message_p = itti_alloc_new_message(TASK_S1AP, 0, SCTP_NEW_ASSOCIATION_REQ);
@@ -114,51 +150,32 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p,
local_ip_addr,
sizeof(*local_ip_addr));
S1AP_INFO("[eNB %ld] check the mme registration state\n",instance_p->instance);
- mme = NULL;
+ /* Create new MME descriptor */
+ s1ap_mme_data_p = calloc(1, sizeof(*s1ap_mme_data_p));
+ DevAssert(s1ap_mme_data_p != NULL);
+ s1ap_mme_data_p->cnx_id = s1ap_eNB_fetch_add_global_cnx_id();
+ sctp_new_association_req_p->ulp_cnx_id = s1ap_mme_data_p->cnx_id;
+ s1ap_mme_data_p->assoc_id = -1;
+ s1ap_mme_data_p->broadcast_plmn_num = broadcast_plmn_num;
+ memcpy(&s1ap_mme_data_p->mme_s1_ip,
+ mme_ip_address,
+ sizeof(*mme_ip_address));
+ s1ap_mme_data_p->mme_port = mme_port;
+ for (int i = 0; i < broadcast_plmn_num; ++i)
+ s1ap_mme_data_p->broadcast_plmn_index[i] = broadcast_plmn_index[i];
- if ( mme == NULL ) {
- /* Create new MME descriptor */
- s1ap_mme_data_p = calloc(1, sizeof(*s1ap_mme_data_p));
- DevAssert(s1ap_mme_data_p != NULL);
- s1ap_mme_data_p->cnx_id = s1ap_eNB_fetch_add_global_cnx_id();
- sctp_new_association_req_p->ulp_cnx_id = s1ap_mme_data_p->cnx_id;
- s1ap_mme_data_p->assoc_id = -1;
- s1ap_mme_data_p->broadcast_plmn_num = broadcast_plmn_num;
- memcpy(&s1ap_mme_data_p->mme_s1_ip,
- mme_ip_address,
- sizeof(*mme_ip_address));
- s1ap_mme_data_p->mme_port = mme_port;
- for (int i = 0; i < broadcast_plmn_num; ++i)
- s1ap_mme_data_p->broadcast_plmn_index[i] = broadcast_plmn_index[i];
-
- s1ap_mme_data_p->s1ap_eNB_instance = instance_p;
- STAILQ_INIT(&s1ap_mme_data_p->served_gummei);
- /* Insert the new descriptor in list of known MME
- * but not yet associated.
- */
- RB_INSERT(s1ap_mme_map, &instance_p->s1ap_mme_head, s1ap_mme_data_p);
- s1ap_mme_data_p->state = S1AP_ENB_STATE_WAITING;
- instance_p->s1ap_mme_nb ++;
- instance_p->s1ap_mme_pending_nb ++;
- } else if (mme->state == S1AP_ENB_STATE_WAITING) {
- instance_p->s1ap_mme_pending_nb ++;
- sctp_new_association_req_p->ulp_cnx_id = mme->cnx_id;
- S1AP_INFO("[eNB %ld] MME already registered, retrive the data (state %d, cnx %d, mme_nb %d, mme_pending_nb %d)\n",
- instance_p->instance,
- mme->state, mme->cnx_id,
- instance_p->s1ap_mme_nb, instance_p->s1ap_mme_pending_nb);
- /*s1ap_mme_data_p->cnx_id = mme->cnx_id;
- sctp_new_association_req_p->ulp_cnx_id = mme->cnx_id;
-
- s1ap_mme_data_p->assoc_id = -1;
- s1ap_mme_data_p->s1ap_eNB_instance = instance_p;
- */
- } else {
- S1AP_WARN("[eNB %ld] MME already registered but not in the waiting state, retrive the data (state %d, cnx %d, mme_nb %d, mme_pending_nb %d)\n",
- instance_p->instance,
- mme->state, mme->cnx_id,
- instance_p->s1ap_mme_nb, instance_p->s1ap_mme_pending_nb);
- }
+ s1ap_mme_data_p->s1ap_eNB_instance = instance_p;
+ STAILQ_INIT(&s1ap_mme_data_p->served_gummei);
+ /* Insert the new descriptor in list of known MME
+ * but not yet associated.
+ */
+ RB_INSERT(s1ap_mme_map, &instance_p->s1ap_mme_head, s1ap_mme_data_p);
+ s1ap_mme_data_p->state = S1AP_ENB_STATE_DISCONNECTED;
+ memcpy( &(s1ap_mme_data_p->mme_ip_address), mme_ip_address, sizeof(net_ip_address_t) );
+ s1ap_mme_data_p->overload_state = S1AP_NO_OVERLOAD;
+ s1ap_mme_data_p->sctp_req_cnt++;
+ s1ap_mme_data_p->timer_id = S1AP_TIMERID_INIT;
+ instance_p->s1ap_mme_pending_nb ++;
itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message_p);
}
@@ -196,10 +213,10 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *
new_instance->eNB_id = s1ap_register_eNB->eNB_id;
new_instance->cell_type = s1ap_register_eNB->cell_type;
new_instance->tac = s1ap_register_eNB->tac;
-
+
memcpy(&new_instance->eNB_s1_ip,
- &s1ap_register_eNB->enb_ip_address,
- sizeof(s1ap_register_eNB->enb_ip_address));
+ &s1ap_register_eNB->enb_ip_address,
+ sizeof(s1ap_register_eNB->enb_ip_address));
for (int i = 0; i < s1ap_register_eNB->num_plmn; i++) {
new_instance->mcc[i] = s1ap_register_eNB->mcc[i];
@@ -207,6 +224,15 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *
new_instance->mnc_digit_length[i] = s1ap_register_eNB->mnc_digit_length[i];
}
+ memcpy( &(new_instance->enb_ip_address), &(s1ap_register_eNB->enb_ip_address), sizeof(net_ip_address_t) );
+ new_instance->s1_setuprsp_wait_timer = s1ap_register_eNB->s1_setuprsp_wait_timer;
+ new_instance->s1_setupreq_wait_timer = s1ap_register_eNB->s1_setupreq_wait_timer;
+ new_instance->s1_setupreq_count = s1ap_register_eNB->s1_setupreq_count;
+ new_instance->sctp_req_timer = s1ap_register_eNB->sctp_req_timer;
+ new_instance->sctp_req_count = s1ap_register_eNB->sctp_req_count;
+ new_instance->sctp_in_streams = s1ap_register_eNB->sctp_in_streams;
+ new_instance->sctp_out_streams = s1ap_register_eNB->sctp_out_streams;
+
new_instance->num_plmn = s1ap_register_eNB->num_plmn;
new_instance->default_drx = s1ap_register_eNB->default_drx;
/* Add the new instance to the list of eNB (meaningfull in virtual mode) */
@@ -217,8 +243,12 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *
s1ap_register_eNB->eNB_id);
}
- DevCheck(s1ap_register_eNB->nb_mme <= S1AP_MAX_NB_MME_IP_ADDRESS,
- S1AP_MAX_NB_MME_IP_ADDRESS, s1ap_register_eNB->nb_mme, 0);
+ if( s1ap_register_eNB->nb_mme > S1AP_MAX_NB_MME_IP_ADDRESS )
+ {
+ S1AP_ERROR("Invalid MME number = %d\n ", s1ap_register_eNB->nb_mme);
+ s1ap_register_eNB->nb_mme = S1AP_MAX_NB_MME_IP_ADDRESS;
+ }
+ new_instance->s1ap_mme_nb = s1ap_register_eNB->nb_mme;
/* Trying to connect to provided list of MME ip address */
for (index = 0; index < s1ap_register_eNB->nb_mme; index++) {
@@ -250,28 +280,131 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *
void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) {
s1ap_eNB_instance_t *instance_p;
s1ap_eNB_mme_data_t *s1ap_mme_data_p;
+ s1ap_eNB_ue_context_t *ue_p = NULL;
+ MessageDef *message_p = NULL;
+ uint32_t timer_kind = 0;
+ struct plmn_identity_s* plmnInfo;
+ struct served_group_id_s* groupInfo;
+ struct served_gummei_s* gummeiInfo;
+ struct mme_code_s* mmeCode;
+ int8_t cnt = 0;
+ unsigned enb_s1ap_id[NUMBER_OF_UE_MAX];
DevAssert(sctp_new_association_resp != NULL);
instance_p = s1ap_eNB_get_instance(instance);
DevAssert(instance_p != NULL);
s1ap_mme_data_p = s1ap_eNB_get_MME(instance_p, -1,
sctp_new_association_resp->ulp_cnx_id);
DevAssert(s1ap_mme_data_p != NULL);
-
- if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
- S1AP_WARN("Received unsuccessful result for SCTP association (%u), instance %ld, cnx_id %u\n",
- sctp_new_association_resp->sctp_state,
- instance,
- sctp_new_association_resp->ulp_cnx_id);
- s1ap_handle_s1_setup_message(s1ap_mme_data_p, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN);
- return;
+ memset(enb_s1ap_id, 0, sizeof(enb_s1ap_id) );
+ if( s1ap_mme_data_p->timer_id != S1AP_TIMERID_INIT ) {
+ s1ap_timer_remove( s1ap_mme_data_p->timer_id );
+ s1ap_mme_data_p->timer_id = S1AP_TIMERID_INIT;
}
+
+ if( sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED ) {
+ RB_FOREACH(ue_p, s1ap_ue_map, &instance_p->s1ap_ue_head) {
+ if( ue_p->mme_ref == s1ap_mme_data_p ) {
+ if(cnt < NUMBER_OF_UE_MAX) {
+ enb_s1ap_id[cnt] = ue_p->eNB_ue_s1ap_id;
+ cnt++;
+
+ message_p = NULL;
+ message_p = itti_alloc_new_message(TASK_S1AP, 0, S1AP_UE_CONTEXT_RELEASE_COMMAND);
+
+ if( message_p != NULL ) {
+ S1AP_UE_CONTEXT_RELEASE_COMMAND(message_p).eNB_ue_s1ap_id = ue_p->eNB_ue_s1ap_id;
+
+ if( itti_send_msg_to_task(TASK_RRC_ENB, ue_p->eNB_instance->instance, message_p) < 0 ) {
+ S1AP_ERROR("UE Context Release Command Transmission Failure: eNB_ue_s1ap_id=%u\n", ue_p->eNB_ue_s1ap_id);
+ }
+ } else {
+ S1AP_ERROR("Invalid message_p : eNB_ue_s1ap_id=%u\n", ue_p->eNB_ue_s1ap_id);
+ }
+ }else{
+ S1AP_ERROR("s1ap_eNB_handle_sctp_association_resp: cnt %d > max\n", cnt);
+ }
+ }
+ }
+ for( ; cnt > 0 ; ) {
+ cnt--;
+ struct s1ap_eNB_ue_context_s *ue_context_p = NULL;
+ struct s1ap_eNB_ue_context_s *s1ap_ue_context_p = NULL;
+ ue_context_p = s1ap_eNB_get_ue_context(instance_p, (uint32_t)enb_s1ap_id[cnt]);
+ if (ue_context_p != NULL) {
+ s1ap_ue_context_p = RB_REMOVE(s1ap_ue_map, &instance_p->s1ap_ue_head, ue_context_p);
+ s1ap_eNB_free_ue_context(s1ap_ue_context_p);
+ }
+ }
+ s1ap_mme_data_p->mme_name = 0;
+ s1ap_mme_data_p->overload_state = S1AP_NO_OVERLOAD;
+ s1ap_mme_data_p->nextstream = 0;
+ s1ap_mme_data_p->in_streams = 0;
+ s1ap_mme_data_p->out_streams = 0;
+ s1ap_mme_data_p->assoc_id = -1;
+
+ while (!STAILQ_EMPTY(&s1ap_mme_data_p->served_gummei)) {
+ gummeiInfo = STAILQ_FIRST(&s1ap_mme_data_p->served_gummei);
+ STAILQ_REMOVE_HEAD(&s1ap_mme_data_p->served_gummei, next);
- /* Update parameters */
- s1ap_mme_data_p->assoc_id = sctp_new_association_resp->assoc_id;
- s1ap_mme_data_p->in_streams = sctp_new_association_resp->in_streams;
- s1ap_mme_data_p->out_streams = sctp_new_association_resp->out_streams;
- /* Prepare new S1 Setup Request */
- s1ap_eNB_generate_s1_setup_request(instance_p, s1ap_mme_data_p);
+ while (!STAILQ_EMPTY(&gummeiInfo->served_plmns)) {
+ plmnInfo = STAILQ_FIRST(&gummeiInfo->served_plmns);
+ STAILQ_REMOVE_HEAD(&gummeiInfo->served_plmns, next);
+ free(plmnInfo);
+ }
+ while (!STAILQ_EMPTY(&gummeiInfo->served_group_ids)) {
+ groupInfo = STAILQ_FIRST(&gummeiInfo->served_group_ids);
+ STAILQ_REMOVE_HEAD(&gummeiInfo->served_group_ids, next);
+ free(groupInfo);
+ }
+ while (!STAILQ_EMPTY(&gummeiInfo->mme_codes)) {
+ mmeCode = STAILQ_FIRST(&gummeiInfo->mme_codes);
+ STAILQ_REMOVE_HEAD(&gummeiInfo->mme_codes, next);
+ free(mmeCode);
+ }
+ free(gummeiInfo);
+ }
+
+ STAILQ_INIT(&s1ap_mme_data_p->served_gummei);
+
+ if( s1ap_mme_data_p->state == S1AP_ENB_STATE_DISCONNECTED ) {
+ if( (s1ap_mme_data_p->sctp_req_cnt <= instance_p->sctp_req_count) ||
+ (instance_p->sctp_req_count == 0xffff) ) {
+ timer_kind = s1ap_mme_data_p->cnx_id;
+ timer_kind = timer_kind | S1AP_MMEIND;
+ timer_kind = timer_kind | SCTP_REQ_WAIT;
+
+ if( s1ap_timer_setup( instance_p->sctp_req_timer, 0, TASK_S1AP, instance_p->instance,
+ timer_kind, S1AP_TIMER_ONE_SHOT, NULL, &s1ap_mme_data_p->timer_id) < 0 ) {
+ S1AP_ERROR("Timer Start NG(SCTP retransmission wait timer) : MME=%d\n",s1ap_mme_data_p->cnx_id);
+ s1ap_sctp_req( instance_p, s1ap_mme_data_p );
+ }
+ } else {
+ S1AP_ERROR("Retransmission count exceeded of SCTP : MME=%d\n",s1ap_mme_data_p->cnx_id);
+ }
+ } else {
+ S1AP_ERROR("SCTP disconnection reception : MME = %d\n",s1ap_mme_data_p->cnx_id);
+
+ if( (s1ap_mme_data_p->sctp_req_cnt <= instance_p->sctp_req_count) ||
+ (instance_p->sctp_req_count == 0xffff) ) {
+ s1ap_sctp_req( instance_p, s1ap_mme_data_p );
+ } else {
+ S1AP_ERROR("Retransmission count exceeded of SCTP : MME=%d\n",s1ap_mme_data_p->cnx_id);
+ }
+ s1ap_mme_data_p->state = S1AP_ENB_STATE_DISCONNECTED;
+ }
+ } else {
+ /* Update parameters */
+ s1ap_mme_data_p->assoc_id = sctp_new_association_resp->assoc_id;
+ s1ap_mme_data_p->in_streams = sctp_new_association_resp->in_streams;
+ s1ap_mme_data_p->out_streams = sctp_new_association_resp->out_streams;
+ /* Prepare new S1 Setup Request */
+ s1ap_mme_data_p->s1_setupreq_cnt = 0;
+ s1ap_mme_data_p->sctp_req_cnt = 0;
+ if (s1ap_eNB_generate_s1_setup_request(instance_p, s1ap_mme_data_p) == -1) {
+ S1AP_ERROR("s1ap eNB generate s1 setup request failed\n");
+ return;
+ }
+ }
}
static
@@ -282,13 +415,94 @@ void s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind) {
mme_test_s1_notify_sctp_data_ind(sctp_data_ind->assoc_id, sctp_data_ind->stream,
sctp_data_ind->buffer, sctp_data_ind->buffer_length);
#else
- s1ap_eNB_handle_message(sctp_data_ind->assoc_id, sctp_data_ind->stream,
- sctp_data_ind->buffer, sctp_data_ind->buffer_length);
+ if (s1ap_eNB_handle_message(sctp_data_ind->assoc_id, sctp_data_ind->stream,
+ sctp_data_ind->buffer, sctp_data_ind->buffer_length) == -1) {
+ S1AP_ERROR("Failed to handle s1ap eNB message\n");
+ }
#endif
result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer);
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
}
+void s1ap_eNB_timer_expired(
+ instance_t instance,
+ timer_has_expired_t *msg_p)
+{
+ uint32_t timer_kind = 0;
+ int16_t line_ind = 0;
+ s1ap_eNB_mme_data_t *mme_desc_p = NULL;
+ uint32_t timer_ind = 0;
+ s1ap_eNB_instance_t *instance_p = NULL;
+ long timer_id = S1AP_TIMERID_INIT;
+
+ instance_p = s1ap_eNB_get_instance(instance);
+ if(msg_p->arg!=NULL){
+ timer_kind = *((uint32_t*)msg_p->arg);
+ free(msg_p->arg);
+ }else{
+ S1AP_ERROR("s1 timer timer_kind is NULL\n");
+ return;
+ }
+ line_ind = (int16_t)(timer_kind & S1AP_LINEIND);
+ timer_id = msg_p->timer_id;
+
+ if( (timer_kind & S1AP_MMEIND) == S1AP_MMEIND ) {
+ mme_desc_p = s1ap_eNB_get_MME(instance_p, -1, line_ind);
+ if(mme_desc_p != NULL) {
+ if( timer_id == mme_desc_p->timer_id ) {
+ mme_desc_p->timer_id = S1AP_TIMERID_INIT;
+ timer_ind = timer_kind & S1AP_TIMERIND;
+
+ switch(timer_ind)
+ {
+ case S1_SETRSP_WAIT:
+ {
+ if( (instance_p->s1_setupreq_count >= mme_desc_p->s1_setupreq_cnt) ||
+ (instance_p->s1_setupreq_count == 0xffff) ) {
+ s1ap_eNB_generate_s1_setup_request( instance_p, mme_desc_p );
+ } else {
+ S1AP_ERROR("Retransmission count exceeded of S1 SETUP REQUEST : MME=%d\n",line_ind);
+ }
+ break;
+ }
+ case S1_SETREQ_WAIT:
+ {
+ if( (instance_p->s1_setupreq_count >= mme_desc_p->s1_setupreq_cnt) ||
+ (instance_p->s1_setupreq_count == 0xffff) ) {
+ s1ap_eNB_generate_s1_setup_request( instance_p, mme_desc_p );
+ } else {
+ S1AP_ERROR("Retransmission count exceeded of S1 SETUP REQUEST : MME=%d\n",line_ind);
+ }
+ break;
+ }
+ case SCTP_REQ_WAIT:
+ {
+ if( (instance_p->sctp_req_count >= mme_desc_p->sctp_req_cnt) ||
+ (instance_p->sctp_req_count == 0xffff) ) {
+ s1ap_sctp_req( instance_p, mme_desc_p );
+ } else {
+ S1AP_ERROR("Retransmission count exceeded of SCTP : MME=%d\n",line_ind);
+ }
+ break;
+ }
+ default:
+ {
+ S1AP_WARN("Invalid Timer indication\n");
+ break;
+ }
+ }
+ } else {
+ S1AP_DEBUG("Unmatch timer id\n");
+ return;
+ }
+ } else {
+ S1AP_WARN("Not applicable MME detected : connection id = %d\n", line_ind);
+ return;
+ }
+ }
+ return;
+}
+
void s1ap_eNB_init(void) {
S1AP_DEBUG("Starting S1AP layer\n");
s1ap_eNB_prepare_internal_data();
@@ -412,6 +626,13 @@ void *s1ap_eNB_process_itti_msg(void *notUsed) {
}
break;
+ case TIMER_HAS_EXPIRED:
+ {
+ s1ap_eNB_timer_expired(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
+ &received_msg->ittiMsg.timer_has_expired);
+ }
+ break;
+
default:
S1AP_ERROR("Received unhandled message: %d:%s\n",
ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg));
@@ -452,6 +673,7 @@ static int s1ap_eNB_generate_s1_setup_request(
uint8_t *buffer = NULL;
uint32_t len = 0;
int ret = 0;
+ uint32_t timer_kind = 0;
DevAssert(instance_p != NULL);
DevAssert(s1ap_mme_data_p != NULL);
s1ap_mme_data_p->state = S1AP_ENB_STATE_WAITING;
@@ -526,6 +748,17 @@ static int s1ap_eNB_generate_s1_setup_request(
return -1;
}
+ timer_kind = s1ap_mme_data_p->cnx_id;
+ timer_kind = timer_kind | S1AP_MMEIND;
+ timer_kind = timer_kind | S1_SETRSP_WAIT;
+
+ if( s1ap_timer_setup(instance_p->s1_setuprsp_wait_timer, 0, TASK_S1AP, instance_p->instance, timer_kind, S1AP_TIMER_ONE_SHOT,
+ NULL, &s1ap_mme_data_p->timer_id) < 0 )
+ {
+ S1AP_ERROR("Timer Start NG(S1 Setup Response) : MME=%d\n",s1ap_mme_data_p->cnx_id);
+ }
+ s1ap_mme_data_p->s1_setupreq_cnt++;
+
/* Non UE-Associated signalling -> stream = 0 */
s1ap_eNB_itti_send_sctp_data_req(instance_p->instance, s1ap_mme_data_p->assoc_id, buffer, len, 0);
return ret;
@@ -534,3 +767,55 @@ static int s1ap_eNB_generate_s1_setup_request(
+static int s1ap_sctp_req(s1ap_eNB_instance_t *instance_p,
+ s1ap_eNB_mme_data_t *s1ap_mme_data_p)
+{
+ MessageDef *message_p = NULL;
+ sctp_new_association_req_t *sctp_new_association_req_p = NULL;
+
+ if( instance_p == NULL )
+ {
+ S1AP_ERROR("Invalid instance_p\n");
+ return -1;
+ }
+
+ message_p = itti_alloc_new_message(TASK_S1AP, 0, SCTP_NEW_ASSOCIATION_REQ);
+ sctp_new_association_req_p = &message_p->ittiMsg.sctp_new_association_req;
+ sctp_new_association_req_p->port = S1AP_PORT_NUMBER;
+ sctp_new_association_req_p->ppid = S1AP_SCTP_PPID;
+ sctp_new_association_req_p->in_streams = instance_p->sctp_in_streams;
+ sctp_new_association_req_p->out_streams = instance_p->sctp_out_streams;
+ sctp_new_association_req_p->ulp_cnx_id = s1ap_mme_data_p->cnx_id;
+
+ if( s1ap_mme_data_p->mme_ip_address.ipv4 != 0 ) {
+ memcpy(&sctp_new_association_req_p->remote_address,
+ &s1ap_mme_data_p->mme_ip_address,
+ sizeof(net_ip_address_t));
+ if( instance_p->enb_ip_address.ipv4 != 0 ) {
+ memcpy(&sctp_new_association_req_p->local_address,
+ &instance_p->enb_ip_address,
+ sizeof(net_ip_address_t));
+ } else {
+ S1AP_ERROR("Invalid IP Address Format V4(MME):V6\n");
+ return -1;
+ }
+ } else {
+ memcpy(&sctp_new_association_req_p->remote_address,
+ &s1ap_mme_data_p->mme_ip_address,
+ sizeof(net_ip_address_t));
+ if( instance_p->enb_ip_address.ipv6 != 0 ) {
+ memcpy(&sctp_new_association_req_p->local_address,
+ &instance_p->enb_ip_address,
+ sizeof(net_ip_address_t));
+ } else {
+ S1AP_ERROR("Invalid IP Address Format V6(MME):V4\n");
+ return -1;
+ }
+ }
+
+ itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message_p);
+
+ s1ap_mme_data_p->sctp_req_cnt++;
+
+ return 0;
+}
diff --git a/openair3/S1AP/s1ap_eNB.h b/openair3/S1AP/s1ap_eNB.h
index 2abbc53ec9..2183587214 100644
--- a/openair3/S1AP/s1ap_eNB.h
+++ b/openair3/S1AP/s1ap_eNB.h
@@ -30,6 +30,22 @@
#ifndef S1AP_ENB_H_
#define S1AP_ENB_H_
+#define S1AP_MMEIND 0x80000000
+#define S1AP_UEIND 0x00000000
+#define S1_SETRSP_WAIT 0x00010000
+#define S1_SETREQ_WAIT 0x00020000
+#define SCTP_REQ_WAIT 0x00030000
+#define S1AP_LINEIND 0x0000ffff
+#define S1AP_TIMERIND 0x00ff0000
+
+#define S1AP_TIMERID_INIT 0xffffffffffffffff
+
+typedef enum s1ap_timer_type_s {
+ S1AP_TIMER_PERIODIC,
+ S1AP_TIMER_ONE_SHOT,
+ S1AP_TIMER_TYPE_MAX,
+} s1ap_timer_type_t;
+
typedef struct s1ap_eNB_config_s {
// MME related params
unsigned char mme_enabled; ///< MME enabled ?
@@ -43,6 +59,7 @@ void *s1ap_eNB_process_itti_msg(void*);
void s1ap_eNB_init(void);
void *s1ap_eNB_task(void *arg);
+int s1ap_timer_remove(long timer_id);
uint32_t s1ap_generate_eNB_id(void);
#endif /* S1AP_ENB_H_ */
diff --git a/openair3/S1AP/s1ap_eNB_decoder.c b/openair3/S1AP/s1ap_eNB_decoder.c
index 4635946a05..14e4b49238 100644
--- a/openair3/S1AP/s1ap_eNB_decoder.c
+++ b/openair3/S1AP/s1ap_eNB_decoder.c
@@ -89,8 +89,6 @@ static int s1ap_eNB_decode_initiating_message(S1AP_S1AP_PDU_t *pdu) {
default:
S1AP_ERROR("Unknown procedure ID (%d) for initiating message\n",
(int)pdu->choice.initiatingMessage.procedureCode);
- AssertFatal( 0, "Unknown procedure ID (%d) for initiating message\n",
- (int)pdu->choice.initiatingMessage.procedureCode);
return -1;
}
diff --git a/openair3/S1AP/s1ap_eNB_defs.h b/openair3/S1AP/s1ap_eNB_defs.h
index d8a8da8001..ed0909d66e 100644
--- a/openair3/S1AP/s1ap_eNB_defs.h
+++ b/openair3/S1AP/s1ap_eNB_defs.h
@@ -165,6 +165,12 @@ typedef struct s1ap_eNB_mme_data_s {
/* Only meaningfull in virtual mode */
struct s1ap_eNB_instance_s *s1ap_eNB_instance;
+
+ uint32_t nb_calls;
+ net_ip_address_t mme_ip_address;
+ long timer_id;
+ uint16_t s1_setupreq_cnt;
+ uint16_t sctp_req_cnt;
} s1ap_eNB_mme_data_t;
typedef struct s1ap_eNB_instance_s {
@@ -217,6 +223,14 @@ typedef struct s1ap_eNB_instance_s {
/* Default Paging DRX of the eNB as defined in TS 36.304 */
paging_drx_t default_drx;
+ net_ip_address_t enb_ip_address;
+ uint16_t s1_setuprsp_wait_timer;
+ uint16_t s1_setupreq_wait_timer;
+ uint16_t s1_setupreq_count;
+ uint16_t sctp_req_timer;
+ uint16_t sctp_req_count;
+ uint16_t sctp_in_streams;
+ uint16_t sctp_out_streams;
} s1ap_eNB_instance_t;
typedef struct {
diff --git a/openair3/S1AP/s1ap_eNB_handlers.c b/openair3/S1AP/s1ap_eNB_handlers.c
index 7c233d9e14..9ee3287b94 100644
--- a/openair3/S1AP/s1ap_eNB_handlers.c
+++ b/openair3/S1AP/s1ap_eNB_handlers.c
@@ -38,6 +38,9 @@
#include "s1ap_eNB_defs.h"
#include "s1ap_eNB_handlers.h"
#include "s1ap_eNB_decoder.h"
+#include "s1ap_eNB_encoder.h"
+
+#include "s1ap_eNB_itti_messaging.h"
#include "s1ap_eNB_ue_context.h"
#include "s1ap_eNB_trace.h"
@@ -109,6 +112,20 @@ int s1ap_eNB_handle_s1_ENDC_e_rab_modification_confirm(uint32_t as
uint32_t stream,
S1AP_S1AP_PDU_t *pdu);
+static int s1ap_eNB_snd_s1_setup_request(
+ s1ap_eNB_instance_t *instance_p,
+ s1ap_eNB_mme_data_t *s1ap_mme_data_p);
+
+int s1ap_timer_setup(
+ uint32_t interval_sec,
+ uint32_t interval_us,
+ task_id_t task_id,
+ int32_t instance,
+ uint32_t timer_kind,
+ timer_type_t type,
+ void *timer_arg,
+ long *timer_id);
+
/* Handlers matrix. Only eNB related procedure present here */
s1ap_message_decoded_callback messages_callback[][3] = {
{ 0, 0, 0 }, /* HandoverPreparation */
@@ -260,6 +277,10 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id,
S1AP_S1SetupFailure_t *container;
S1AP_S1SetupFailureIEs_t *ie;
s1ap_eNB_mme_data_t *mme_desc_p;
+ uint32_t interval_sec = 0;
+ uint32_t timer_kind = 0;
+ s1ap_eNB_instance_t *instance_p;
+
DevAssert(pdu != NULL);
container = &pdu->choice.unsuccessfulOutcome.value.choice.S1SetupFailure;
@@ -270,7 +291,7 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id,
}
if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
- S1AP_ERROR("[SCTP %d] Received S1 setup response for non existing "
+ S1AP_ERROR("[SCTP %d] Received S1 setup failure for non existing "
"MME context\n", assoc_id);
return -1;
}
@@ -278,6 +299,10 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id,
S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupFailureIEs_t, ie, container,
S1AP_ProtocolIE_ID_id_Cause,true);
+ if(ie == NULL) {
+ return -1;
+ }
+
if ((ie->value.choice.Cause.present == S1AP_Cause_PR_misc) &&
(ie->value.choice.Cause.choice.misc == S1AP_CauseMisc_unspecified)) {
S1AP_WARN("Received s1 setup failure for MME... MME is not ready\n");
@@ -285,8 +310,56 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id,
S1AP_ERROR("Received s1 setup failure for MME... please check your parameters\n");
}
- mme_desc_p->state = S1AP_ENB_STATE_WAITING;
- s1ap_handle_s1_setup_message(mme_desc_p, 0);
+ if( mme_desc_p->timer_id != S1AP_TIMERID_INIT ) {
+ s1ap_timer_remove( mme_desc_p->timer_id );
+ mme_desc_p->timer_id = S1AP_TIMERID_INIT;
+ }
+ instance_p = mme_desc_p->s1ap_eNB_instance;
+ if( ( instance_p->s1_setupreq_count >= mme_desc_p->s1_setupreq_cnt) ||
+ ( instance_p->s1_setupreq_count == 0xffff) ) {
+ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupFailureIEs_t, ie, container,
+ S1AP_ProtocolIE_ID_id_TimeToWait, false);
+ if( ie != NULL ) {
+ switch(ie->value.choice.TimeToWait)
+ {
+ case S1AP_TimeToWait_v1s:
+ interval_sec = 1;
+ break;
+ case S1AP_TimeToWait_v2s:
+ interval_sec = 2;
+ break;
+ case S1AP_TimeToWait_v5s:
+ interval_sec = 5;
+ break;
+ case S1AP_TimeToWait_v10s:
+ interval_sec = 10;
+ break;
+ case S1AP_TimeToWait_v20s:
+ interval_sec = 20;
+ break;
+ case S1AP_TimeToWait_v60s:
+ interval_sec = 60;
+ break;
+ default:
+ interval_sec = instance_p->s1_setupreq_wait_timer;
+ break;
+ }
+ } else {
+ interval_sec = instance_p->s1_setupreq_wait_timer;
+ }
+
+ timer_kind = mme_desc_p->cnx_id;
+ timer_kind = timer_kind | S1AP_MMEIND;
+ timer_kind = timer_kind | S1_SETREQ_WAIT;
+
+ if( s1ap_timer_setup(interval_sec, 0, TASK_S1AP, instance_p->instance, timer_kind, S1AP_TIMER_ONE_SHOT,
+ NULL, &mme_desc_p->timer_id) < 0 ) {
+ S1AP_ERROR("Timer Start NG(S1 Setup Request) : MME=%d\n",mme_desc_p->cnx_id);
+ s1ap_eNB_snd_s1_setup_request( instance_p, mme_desc_p );
+ }
+ } else {
+ S1AP_ERROR("Retransmission count exceeded of S1 SETUP REQUEST : MME=%d\n",mme_desc_p->cnx_id);
+ }
return 0;
}
@@ -314,9 +387,27 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id,
return -1;
}
+ /* Set the capacity of this MME */
+ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container,
+ S1AP_ProtocolIE_ID_id_RelativeMMECapacity, true);
+ if(ie == NULL) {
+ return -1;
+ }
+ mme_desc_p->relative_mme_capacity = ie->value.choice.RelativeMMECapacity;
+
S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container,
S1AP_ProtocolIE_ID_id_ServedGUMMEIs, true);
+ if(ie == NULL) {
+ return -1;
+ }
+ if( mme_desc_p->timer_id != S1AP_TIMERID_INIT )
+ {
+ s1ap_timer_remove( mme_desc_p->timer_id );
+ mme_desc_p->timer_id = S1AP_TIMERID_INIT;
+ }
+ mme_desc_p->s1_setupreq_cnt = 0;
+ mme_desc_p->sctp_req_cnt = 0;
/* The list of served gummei can contain at most 8 elements.
* LTE related gummei is the first element in the list, i.e with an id of 0.
*/
@@ -368,13 +459,7 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id,
STAILQ_INSERT_TAIL(&mme_desc_p->served_gummei, new_gummei_p, next);
}
-
- /* Set the capacity of this MME */
- S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container,
- S1AP_ProtocolIE_ID_id_RelativeMMECapacity, true);
-
- mme_desc_p->relative_mme_capacity = ie->value.choice.RelativeMMECapacity;
-
+
/* Optionaly set the mme name */
S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container,
S1AP_ProtocolIE_ID_id_MMEname, false);
@@ -392,7 +477,6 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id,
*/
mme_desc_p->state = S1AP_ENB_STATE_CONNECTED;
mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb ++;
- s1ap_handle_s1_setup_message(mme_desc_p, 0);
return 0;
}
@@ -725,6 +809,9 @@ int s1ap_eNB_handle_error_indication(uint32_t assoc_id,
S1AP_ProtocolIE_ID_id_CriticalityDiagnostics, false);
if (ie) {
+ if( ie->value.choice.CriticalityDiagnostics.procedureCode ) {
+ S1AP_WARN("Received S1 Error indication CriticalityDiagnostics procedureCode = %ld\n", *ie->value.choice.CriticalityDiagnostics.procedureCode);
+ }
// TODO continue
}
@@ -807,9 +894,11 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id,
&(S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).ue_ambr.br_dl));
/* id-E-RABToBeSetupListCtxtSUReq */
} else {
+ itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
return -1;
}
+
S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container,
S1AP_ProtocolIE_ID_id_E_RABToBeSetupListCtxtSUReq, true);
@@ -852,6 +941,7 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id,
item_p->e_RABlevelQoSParameters.allocationRetentionPriority.pre_emptionVulnerability;
} /* for i... */
} else {/* ie != NULL */
+ itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
return -1;
}
@@ -864,21 +954,37 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id,
BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.encryptionAlgorithms);
S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.integrity_algorithms =
BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.integrityProtectionAlgorithms);
- /* id-SecurityKey : Copy the security key */
} else {/* ie != NULL */
+ itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
return -1;
}
+ /* id-SecurityKey : Copy the security key */
S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container,
S1AP_ProtocolIE_ID_id_SecurityKey, true);
if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
memcpy(&S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_key,
ie->value.choice.SecurityKey.buf, ie->value.choice.SecurityKey.size);
- itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p);
} else {/* ie != NULL */
+ itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
return -1;
}
+
+ /* id-NRUESecurityCapabilities */
+ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container,
+ S1AP_ProtocolIE_ID_id_NRUESecurityCapabilities, false);
+ if (ie != NULL) {
+ S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.encryption_algorithms =
+ BIT_STRING_to_uint16(&ie->value.choice.NRUESecurityCapabilities.nRencryptionAlgorithms);
+ S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.integrity_algorithms =
+ BIT_STRING_to_uint16(&ie->value.choice.NRUESecurityCapabilities.nRintegrityProtectionAlgorithms);
+ } else {
+ S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.encryption_algorithms = 0;
+ S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nr_security_capabilities.integrity_algorithms = 0;
+ }
+
+ itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p);
return 0;
}
@@ -904,6 +1010,13 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id,
return -1;
}
+ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_UEContextReleaseCommand_IEs_t, ie, container,
+ S1AP_ProtocolIE_ID_id_Cause, true);
+ if( ie == NULL ) {
+ S1AP_ERROR( "Mandatory Element Nothing : UEContextReleaseCommand(Cause)\n" );
+ return -1;
+ }
+
S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_UEContextReleaseCommand_IEs_t, ie, container,
S1AP_ProtocolIE_ID_id_UE_S1AP_IDs, true);
@@ -951,9 +1064,26 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id,
//#warning "TODO mapping mme_ue_s1ap_id enb_ue_s1ap_id?"
case S1AP_UE_S1AP_IDs_PR_mME_UE_S1AP_ID:
- mme_ue_s1ap_id = ie->value.choice.UE_S1AP_IDs.choice.uE_S1AP_ID_pair.mME_UE_S1AP_ID;
- S1AP_ERROR("TO DO mapping mme_ue_s1ap_id enb_ue_s1ap_id");
- (void)mme_ue_s1ap_id; /* TODO: remove - it's to remove gcc warning about unused var */
+ mme_ue_s1ap_id = ie->value.choice.UE_S1AP_IDs.choice.mME_UE_S1AP_ID;
+
+ RB_FOREACH(ue_desc_p, s1ap_ue_map, &mme_desc_p->s1ap_eNB_instance->s1ap_ue_head)
+ {
+ if( ue_desc_p->mme_ue_s1ap_id == mme_ue_s1ap_id )
+ {
+ enb_ue_s1ap_id = ue_desc_p->eNB_ue_s1ap_id;
+
+ message_p = itti_alloc_new_message(TASK_S1AP, 0, S1AP_UE_CONTEXT_RELEASE_COMMAND);
+ S1AP_UE_CONTEXT_RELEASE_COMMAND(message_p).eNB_ue_s1ap_id = enb_ue_s1ap_id;
+ itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p);
+
+ return 0;
+ }
+ }
+ S1AP_ERROR("[SCTP %d] Received UE context release command(mME_UE_S1AP_ID) for non "
+ "existing UE context 0x%06lx\n",
+ assoc_id,
+ mme_ue_s1ap_id);
+ return -1;
case S1AP_UE_S1AP_IDs_PR_NOTHING:
default:
@@ -961,12 +1091,10 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id,
return -1;
}
} else {
+ S1AP_ERROR( "Mandatory Element Nothing : UEContextReleaseCommand(UE_S1AP_IDs)\n" );
return -1;
}
- S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_UEContextReleaseCommand_IEs_t, ie, container,
- S1AP_ProtocolIE_ID_id_Cause, true);
- /* TBD */
}
static
@@ -985,7 +1113,7 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t assoc_id,
container = &pdu->choice.initiatingMessage.value.choice.E_RABSetupRequest;
if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
- S1AP_ERROR("[SCTP %d] Received initial context setup request for non "
+ S1AP_ERROR("[SCTP %d] Received E-RAB setup request for non "
"existing MME context\n", assoc_id);
return -1;
}
@@ -1012,7 +1140,7 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t assoc_id,
if ((ue_desc_p = s1ap_eNB_get_ue_context(mme_desc_p->s1ap_eNB_instance,
enb_ue_s1ap_id)) == NULL) {
- S1AP_ERROR("[SCTP %d] Received initial context setup request for non "
+ S1AP_ERROR("[SCTP %d] Received E-RAB setup request for non "
"existing UE context 0x%06lx\n", assoc_id,
enb_ue_s1ap_id);
return -1;
@@ -1085,6 +1213,7 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t assoc_id,
itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p);
} else {
+ itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
return -1;
}
@@ -1105,13 +1234,6 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id,
// received Paging Message from MME
S1AP_DEBUG("[SCTP %d] Received Paging Message From MME\n",assoc_id);
- /* Paging procedure -> stream != 0 */
- if (stream == 0) {
- LOG_W(S1AP,"[SCTP %d] Received Paging procedure on stream (%d)\n",
- assoc_id, stream);
- return -1;
- }
-
if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
S1AP_ERROR("[SCTP %d] Received Paging for non "
"existing MME context\n", assoc_id);
@@ -1139,6 +1261,7 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id,
S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.mme_code = 0;
S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.m_tmsi = 0;
} else {
+ itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
return -1;
}
@@ -1166,6 +1289,7 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id,
if(i != ie->value.choice.UEPagingID.choice.iMSI.size - 1) {
/* invalid paging_p->uePagingID.choise.iMSI.buffer */
S1AP_ERROR("[SCTP %d] Received Paging : uePagingID.choise.iMSI error(i %d 0x0F)\n", assoc_id,i);
+ itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
return -1;
}
} else {
@@ -1176,14 +1300,17 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id,
if (S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length >= S1AP_IMSI_LENGTH) {
/* invalid paging_p->uePagingID.choise.iMSI.size */
S1AP_ERROR("[SCTP %d] Received Paging : uePagingID.choise.iMSI.size(%d) is over IMSI length(%d)\n", assoc_id, S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length, S1AP_IMSI_LENGTH);
+ itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
return -1;
}
} else { /* of if (ie->value.choice.UEPagingID.present == S1AP_UEPagingID_PR_iMSI) */
/* invalid paging_p->uePagingID.present */
S1AP_ERROR("[SCTP %d] Received Paging : uePagingID.present(%d) is unknown\n", assoc_id, ie->value.choice.UEPagingID.present);
+ itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
return -1;
}
} else { /* of ie != NULL */
+ itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
return -1;
}
@@ -1216,6 +1343,7 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id,
return -1;
}
} else {
+ itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
return -1;
}
@@ -1243,6 +1371,7 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id,
S1AP_PAGING_IND(message_p).tac[i]);
}
} else {
+ itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
return -1;
}
@@ -1337,6 +1466,7 @@ int s1ap_eNB_handle_e_rab_modify_request(uint32_t assoc_id,
S1AP_E_RAB_MODIFY_RESP(message_p).e_rabs_failed[nb_of_e_rabs_failed].cause_value = S1AP_CauseRadioNetwork_unknown_mme_ue_s1ap_id;
}
} else {
+ itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
return -1;
}
@@ -1389,6 +1519,7 @@ int s1ap_eNB_handle_e_rab_modify_request(uint32_t assoc_id,
itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p);
} else { /* of if (ie != NULL)*/
+ itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
return -1;
}
@@ -1462,6 +1593,24 @@ int s1ap_eNB_handle_e_rab_release_command(uint32_t assoc_id,
message_p = itti_alloc_new_message(TASK_S1AP, 0, S1AP_E_RAB_RELEASE_COMMAND);
S1AP_E_RAB_RELEASE_COMMAND(message_p).eNB_ue_s1ap_id = enb_ue_s1ap_id;
S1AP_E_RAB_RELEASE_COMMAND(message_p).mme_ue_s1ap_id = mme_ue_s1ap_id;
+ /* id-E-RABToBeReleasedList */
+ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABReleaseCommandIEs_t, ie, container,
+ S1AP_ProtocolIE_ID_id_E_RABToBeReleasedList, true);
+
+ if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
+ S1AP_E_RAB_RELEASE_COMMAND(message_p).nb_e_rabs_torelease = ie->value.choice.E_RABList.list.count;
+
+ for (i = 0; i < ie->value.choice.E_RABList.list.count; i++) {
+ S1AP_E_RABItem_t *item_p;
+ item_p = &(((S1AP_E_RABItemIEs_t *)ie->value.choice.E_RABList.list.array[i])->value.choice.E_RABItem);
+ S1AP_E_RAB_RELEASE_COMMAND(message_p).e_rab_release_params[i].e_rab_id = item_p->e_RAB_ID;
+ S1AP_DEBUG("[SCTP] Received E-RAB release command for e-rab id %ld\n", item_p->e_RAB_ID);
+ }
+ } else {
+ itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
+ return -1;
+ }
+
/* id-NAS-PDU */
S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABReleaseCommandIEs_t, ie, container,
S1AP_ProtocolIE_ID_id_NAS_PDU, false);
@@ -1477,24 +1626,6 @@ int s1ap_eNB_handle_e_rab_release_command(uint32_t assoc_id,
S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.length = 0;
S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.buffer = NULL;
}
-
- /* id-E-RABToBeReleasedList */
- S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABReleaseCommandIEs_t, ie, container,
- S1AP_ProtocolIE_ID_id_E_RABToBeReleasedList, true);
-
- if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
- S1AP_E_RAB_RELEASE_COMMAND(message_p).nb_e_rabs_torelease = ie->value.choice.E_RABList.list.count;
-
- for (i = 0; i < ie->value.choice.E_RABList.list.count; i++) {
- S1AP_E_RABItem_t *item_p;
- item_p = &(((S1AP_E_RABItemIEs_t *)ie->value.choice.E_RABList.list.array[i])->value.choice.E_RABItem);
- S1AP_E_RAB_RELEASE_COMMAND(message_p).e_rab_release_params[i].e_rab_id = item_p->e_RAB_ID;
- S1AP_DEBUG("[SCTP] Received E-RAB release command for e-rab id %ld\n", item_p->e_RAB_ID);
- }
- } else {
- return -1;
- }
-
itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p);
return 0;
}
@@ -1519,7 +1650,6 @@ int s1ap_eNB_handle_s1_path_switch_request_ack(uint32_t assoc_id,
if (stream == 0) {
S1AP_ERROR("[SCTP %d] Received s1 path switch request ack on stream (%d)\n",
assoc_id, stream);
- //return -1;
}
if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
@@ -1536,6 +1666,7 @@ int s1ap_eNB_handle_s1_path_switch_request_ack(uint32_t assoc_id,
if (ie == NULL) {
S1AP_ERROR("[SCTP %d] Received path switch request ack for non "
"ie context is NULL\n", assoc_id);
+ itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
return -1;
}
@@ -1558,6 +1689,7 @@ int s1ap_eNB_handle_s1_path_switch_request_ack(uint32_t assoc_id,
if (ie == NULL) {
S1AP_ERROR("[SCTP %d] Received path switch request ack for non "
"ie context is NULL\n", assoc_id);
+ itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
return -1;
}
@@ -1575,6 +1707,7 @@ int s1ap_eNB_handle_s1_path_switch_request_ack(uint32_t assoc_id,
if (ie == NULL) {
S1AP_ERROR("[SCTP %d] Received path switch request ack for non "
"ie context is NULL\n", assoc_id);
+ itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
return -1;
}
@@ -1588,14 +1721,10 @@ int s1ap_eNB_handle_s1_path_switch_request_ack(uint32_t assoc_id,
S1AP_ProtocolIE_ID_id_uEaggregateMaximumBitrate, false);
if (ie) {
- OCTET_STRING_TO_INT32 (
- &ie->value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateUL,
- S1AP_PATH_SWITCH_REQ_ACK(message_p).ue_ambr.br_ul
- );
- OCTET_STRING_TO_INT32 (
- &ie->value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateDL,
- S1AP_PATH_SWITCH_REQ_ACK(message_p).ue_ambr.br_dl
- );
+ asn_INTEGER2ulong(&ie->value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateUL,
+ &S1AP_PATH_SWITCH_REQ_ACK(message_p).ue_ambr.br_ul);
+ asn_INTEGER2ulong(&ie->value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateDL,
+ &S1AP_PATH_SWITCH_REQ_ACK(message_p).ue_ambr.br_dl);
} else {
S1AP_WARN("UEAggregateMaximumBitrate not supported\n");
S1AP_PATH_SWITCH_REQ_ACK(message_p).ue_ambr.br_ul = 0;
@@ -1674,9 +1803,8 @@ int s1ap_eNB_handle_s1_path_switch_request_failure(uint32_t assoc_
pathSwitchRequestFailure = &pdu->choice.unsuccessfulOutcome.value.choice.PathSwitchRequestFailure;
if (stream != 0) {
- S1AP_ERROR("[SCTP %d] Received s1 path switch request failure on stream != 0 (%d)\n",
+ S1AP_WARN("[SCTP %d] Received s1 path switch request failure on stream != 0 (%d)\n",
assoc_id, stream);
- return -1;
}
if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
@@ -1740,3 +1868,144 @@ int s1ap_eNB_handle_s1_ENDC_e_rab_modification_confirm(uint32_t as
return 0;
}
+//-----------------------------------------------------------------------------
+/*
+* eNB generate a S1 setup request towards MME
+*/
+static int s1ap_eNB_snd_s1_setup_request(
+ s1ap_eNB_instance_t *instance_p,
+ s1ap_eNB_mme_data_t *s1ap_mme_data_p)
+//-----------------------------------------------------------------------------
+{
+ S1AP_S1AP_PDU_t pdu;
+ S1AP_S1SetupRequest_t *out = NULL;
+ S1AP_S1SetupRequestIEs_t *ie = NULL;
+ S1AP_SupportedTAs_Item_t *ta = NULL;
+ S1AP_PLMNidentity_t *plmn = NULL;
+ uint8_t *buffer = NULL;
+ uint32_t len = 0;
+ int ret = 0;
+ uint32_t timer_kind = 0;
+
+ DevAssert(instance_p != NULL);
+ DevAssert(s1ap_mme_data_p != NULL);
+ s1ap_mme_data_p->state = S1AP_ENB_STATE_WAITING;
+ /* Prepare the S1AP message to encode */
+ memset(&pdu, 0, sizeof(pdu));
+ pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
+ pdu.choice.initiatingMessage.procedureCode = S1AP_ProcedureCode_id_S1Setup;
+ pdu.choice.initiatingMessage.criticality = S1AP_Criticality_reject;
+ pdu.choice.initiatingMessage.value.present = S1AP_InitiatingMessage__value_PR_S1SetupRequest;
+ out = &pdu.choice.initiatingMessage.value.choice.S1SetupRequest;
+ /* mandatory */
+ ie = (S1AP_S1SetupRequestIEs_t *)calloc(1, sizeof(S1AP_S1SetupRequestIEs_t));
+ ie->id = S1AP_ProtocolIE_ID_id_Global_ENB_ID;
+ ie->criticality = S1AP_Criticality_reject;
+ ie->value.present = S1AP_S1SetupRequestIEs__value_PR_Global_ENB_ID;
+ MCC_MNC_TO_PLMNID(instance_p->mcc[s1ap_mme_data_p->broadcast_plmn_index[0]],
+ instance_p->mnc[s1ap_mme_data_p->broadcast_plmn_index[0]],
+ instance_p->mnc_digit_length[s1ap_mme_data_p->broadcast_plmn_index[0]],
+ &ie->value.choice.Global_ENB_ID.pLMNidentity);
+ ie->value.choice.Global_ENB_ID.eNB_ID.present = S1AP_ENB_ID_PR_macroENB_ID;
+ MACRO_ENB_ID_TO_BIT_STRING(instance_p->eNB_id,
+ &ie->value.choice.Global_ENB_ID.eNB_ID.choice.macroENB_ID);
+ S1AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id,
+ ie->value.choice.Global_ENB_ID.eNB_ID.choice.macroENB_ID.buf[0],
+ ie->value.choice.Global_ENB_ID.eNB_ID.choice.macroENB_ID.buf[1],
+ ie->value.choice.Global_ENB_ID.eNB_ID.choice.macroENB_ID.buf[2]);
+ ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+ /* optional */
+ if (instance_p->eNB_name) {
+ ie = (S1AP_S1SetupRequestIEs_t *)calloc(1, sizeof(S1AP_S1SetupRequestIEs_t));
+ ie->id = S1AP_ProtocolIE_ID_id_eNBname;
+ ie->criticality = S1AP_Criticality_ignore;
+ ie->value.present = S1AP_S1SetupRequestIEs__value_PR_ENBname;
+ OCTET_STRING_fromBuf(&ie->value.choice.ENBname, instance_p->eNB_name,
+ strlen(instance_p->eNB_name));
+ ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+ }
+
+ /* mandatory */
+ ie = (S1AP_S1SetupRequestIEs_t *)calloc(1, sizeof(S1AP_S1SetupRequestIEs_t));
+ ie->id = S1AP_ProtocolIE_ID_id_SupportedTAs;
+ ie->criticality = S1AP_Criticality_reject;
+ ie->value.present = S1AP_S1SetupRequestIEs__value_PR_SupportedTAs;
+ {
+ ta = (S1AP_SupportedTAs_Item_t *)calloc(1, sizeof(S1AP_SupportedTAs_Item_t));
+ INT16_TO_OCTET_STRING(instance_p->tac, &ta->tAC);
+ {
+ for (int i = 0; i < s1ap_mme_data_p->broadcast_plmn_num; ++i) {
+ plmn = (S1AP_PLMNidentity_t *)calloc(1, sizeof(S1AP_PLMNidentity_t));
+ MCC_MNC_TO_TBCD(instance_p->mcc[s1ap_mme_data_p->broadcast_plmn_index[i]],
+ instance_p->mnc[s1ap_mme_data_p->broadcast_plmn_index[i]],
+ instance_p->mnc_digit_length[s1ap_mme_data_p->broadcast_plmn_index[i]],
+ plmn);
+ ASN_SEQUENCE_ADD(&ta->broadcastPLMNs.list, plmn);
+ }
+ }
+ ASN_SEQUENCE_ADD(&ie->value.choice.SupportedTAs.list, ta);
+ }
+ ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+ /* mandatory */
+ ie = (S1AP_S1SetupRequestIEs_t *)calloc(1, sizeof(S1AP_S1SetupRequestIEs_t));
+ ie->id = S1AP_ProtocolIE_ID_id_DefaultPagingDRX;
+ ie->criticality = S1AP_Criticality_ignore;
+ ie->value.present = S1AP_S1SetupRequestIEs__value_PR_PagingDRX;
+ ie->value.choice.PagingDRX = instance_p->default_drx;
+ ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+
+ /* optional */
+ if (0) {
+ ie = (S1AP_S1SetupRequestIEs_t *)calloc(1, sizeof(S1AP_S1SetupRequestIEs_t));
+ ie->id = S1AP_ProtocolIE_ID_id_CSG_IdList;
+ ie->criticality = S1AP_Criticality_reject;
+ ie->value.present = S1AP_S1SetupRequestIEs__value_PR_CSG_IdList;
+ // ie->value.choice.CSG_IdList = ;
+ ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+ }
+
+ /* optional */
+#if (S1AP_VERSION >= MAKE_VERSION(13, 0, 0))
+
+ if (0) {
+ ie = (S1AP_S1SetupRequestIEs_t *)calloc(1, sizeof(S1AP_S1SetupRequestIEs_t));
+ ie->id = S1AP_ProtocolIE_ID_id_UE_RetentionInformation;
+ ie->criticality = S1AP_Criticality_ignore;
+ ie->value.present = S1AP_S1SetupRequestIEs__value_PR_UE_RetentionInformation;
+ // ie->value.choice.UE_RetentionInformation = ;
+ ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+ }
+
+ /* optional */
+ if (0) {
+ ie = (S1AP_S1SetupRequestIEs_t *)calloc(1, sizeof(S1AP_S1SetupRequestIEs_t));
+ ie->id = S1AP_ProtocolIE_ID_id_NB_IoT_DefaultPagingDRX;
+ ie->criticality = S1AP_Criticality_ignore;
+ ie->value.present = S1AP_S1SetupRequestIEs__value_PR_NB_IoT_DefaultPagingDRX;
+ // ie->value.choice.NB_IoT_DefaultPagingDRX = ;
+ ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
+ }
+
+#endif /* #if (S1AP_VERSION >= MAKE_VERSION(14, 0, 0)) */
+
+ if (s1ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
+ S1AP_ERROR("Failed to encode S1 setup request\n");
+ return -1;
+ }
+
+ timer_kind = s1ap_mme_data_p->cnx_id;
+ timer_kind = timer_kind | S1AP_MMEIND;
+ timer_kind = timer_kind | S1_SETRSP_WAIT;
+
+ if( s1ap_timer_setup(instance_p->s1_setuprsp_wait_timer, 0, TASK_S1AP, instance_p->instance, timer_kind, S1AP_TIMER_ONE_SHOT,
+ NULL, &s1ap_mme_data_p->timer_id) < 0 )
+ {
+ S1AP_ERROR("Timer Start NG(S1 Setup Response) : MME=%d\n",s1ap_mme_data_p->cnx_id);
+ }
+ s1ap_mme_data_p->s1_setupreq_cnt++;
+
+ /* Non UE-Associated signalling -> stream = 0 */
+ s1ap_eNB_itti_send_sctp_data_req(instance_p->instance, s1ap_mme_data_p->assoc_id, buffer, len, 0);
+ return ret;
+}
diff --git a/openair3/S1AP/s1ap_eNB_management_procedures.c b/openair3/S1AP/s1ap_eNB_management_procedures.c
index fc7ae70e49..a870e975a2 100644
--- a/openair3/S1AP/s1ap_eNB_management_procedures.c
+++ b/openair3/S1AP/s1ap_eNB_management_procedures.c
@@ -95,23 +95,43 @@ struct s1ap_eNB_mme_data_s *s1ap_eNB_get_MME(
{
struct s1ap_eNB_mme_data_s temp;
struct s1ap_eNB_mme_data_s *found;
+ struct s1ap_eNB_mme_data_s *mme_p;
memset(&temp, 0, sizeof(struct s1ap_eNB_mme_data_s));
temp.assoc_id = assoc_id;
temp.cnx_id = cnx_id;
- if (instance_p == NULL) {
- STAILQ_FOREACH(instance_p, &s1ap_eNB_internal_data.s1ap_eNB_instances_head,
- s1ap_eNB_entries) {
- found = RB_FIND(s1ap_mme_map, &instance_p->s1ap_mme_head, &temp);
+ if( cnx_id != 0 ) {
+ if (instance_p == NULL) {
+ STAILQ_FOREACH(instance_p, &s1ap_eNB_internal_data.s1ap_eNB_instances_head,
+ s1ap_eNB_entries) {
+ found = RB_FIND(s1ap_mme_map, &instance_p->s1ap_mme_head, &temp);
- if (found != NULL) {
- return found;
+ if (found != NULL) {
+ return found;
+ }
}
+ } else {
+ return RB_FIND(s1ap_mme_map, &instance_p->s1ap_mme_head, &temp);
}
} else {
- return RB_FIND(s1ap_mme_map, &instance_p->s1ap_mme_head, &temp);
+ if (instance_p == NULL) {
+ STAILQ_FOREACH(instance_p, &s1ap_eNB_internal_data.s1ap_eNB_instances_head,
+ s1ap_eNB_entries) {
+ RB_FOREACH(mme_p, s1ap_mme_map, &instance_p->s1ap_mme_head) {
+ if( mme_p->assoc_id == assoc_id ) {
+ return mme_p;
+ }
+ }
+ }
+ } else {
+ RB_FOREACH(mme_p, s1ap_mme_map, &instance_p->s1ap_mme_head) {
+ if( mme_p->assoc_id == assoc_id ) {
+ return mme_p;
+ }
+ }
+ }
}
return NULL;
diff --git a/openair3/S1AP/s1ap_eNB_nas_procedures.c b/openair3/S1AP/s1ap_eNB_nas_procedures.c
index 919989897a..b55bc06e11 100644
--- a/openair3/S1AP/s1ap_eNB_nas_procedures.c
+++ b/openair3/S1AP/s1ap_eNB_nas_procedures.c
@@ -138,8 +138,8 @@ int s1ap_eNB_handle_nas_first_req(
* identity, selects the MME with the highest capacity.
*/
mme_desc_p = s1ap_eNB_nnsf_select_mme(
- instance_p,
- s1ap_nas_first_req_p->establishment_cause);
+ instance_p,
+ s1ap_nas_first_req_p->establishment_cause);
if (mme_desc_p) {
S1AP_INFO("[eNB %ld] Chose MME '%s' (assoc_id %d) through highest relative capacity\n",
@@ -358,10 +358,18 @@ int s1ap_eNB_handle_nas_downlink(uint32_t assoc_id,
container = &pdu->choice.initiatingMessage.value.choice.DownlinkNASTransport;
S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_DownlinkNASTransport_IEs_t, ie, container,
S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID, true);
+ if(ie == NULL)
+ {
+ return -1;
+ }
mme_ue_s1ap_id = ie->value.choice.MME_UE_S1AP_ID;
S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_DownlinkNASTransport_IEs_t, ie, container,
S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID, true);
+ if(ie == NULL)
+ {
+ return -1;
+ }
enb_ue_s1ap_id = ie->value.choice.ENB_UE_S1AP_ID;
if ((ue_desc_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance,
@@ -416,6 +424,10 @@ int s1ap_eNB_handle_nas_downlink(uint32_t assoc_id,
S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_DownlinkNASTransport_IEs_t, ie, container,
S1AP_ProtocolIE_ID_id_NAS_PDU, true);
+ if(ie == NULL)
+ {
+ return -1;
+ }
/* Forward the NAS PDU to RRC */
s1ap_eNB_itti_send_nas_downlink_ind(s1ap_eNB_instance->instance,
ue_desc_p->ue_initial_id,
@@ -494,9 +506,9 @@ int s1ap_eNB_nas_uplink(instance_t instance, s1ap_uplink_nas_t *s1ap_uplink_nas_
ie->criticality = S1AP_Criticality_ignore;
ie->value.present = S1AP_UplinkNASTransport_IEs__value_PR_EUTRAN_CGI;
MCC_MNC_TO_PLMNID(
- s1ap_eNB_instance_p->mcc[ue_context_p->selected_plmn_identity],
- s1ap_eNB_instance_p->mnc[ue_context_p->selected_plmn_identity],
- s1ap_eNB_instance_p->mnc_digit_length[ue_context_p->selected_plmn_identity],
+ s1ap_eNB_instance_p->mcc[ue_context_p->mme_ref->broadcast_plmn_index[0]],
+ s1ap_eNB_instance_p->mnc[ue_context_p->mme_ref->broadcast_plmn_index[0]],
+ s1ap_eNB_instance_p->mnc_digit_length[ue_context_p->mme_ref->broadcast_plmn_index[0]],
&ie->value.choice.EUTRAN_CGI.pLMNidentity);
//#warning "TODO get cell id from RRC"
MACRO_ENB_ID_TO_CELL_IDENTITY(s1ap_eNB_instance_p->eNB_id,
diff --git a/openair3/S1AP/s1ap_eNB_nnsf.c b/openair3/S1AP/s1ap_eNB_nnsf.c
index 6319f6e054..a5a4e74734 100644
--- a/openair3/S1AP/s1ap_eNB_nnsf.c
+++ b/openair3/S1AP/s1ap_eNB_nnsf.c
@@ -36,15 +36,29 @@
#include "s1ap_eNB_defs.h"
#include "s1ap_eNB_nnsf.h"
+
+typedef struct MME_nnsf_inf {
+ struct s1ap_eNB_mme_data_s *mme_p;
+ uint64_t weight;
+} MME_nnsf_inf_t;
+
struct s1ap_eNB_mme_data_s *
s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p,
rrc_establishment_cause_t cause)
{
struct s1ap_eNB_mme_data_s *mme_data_p = NULL;
struct s1ap_eNB_mme_data_s *mme_highest_capacity_p = NULL;
- uint8_t current_capacity = 0;
-
+
+ uint16_t capacity_sum = 0;
+ MME_nnsf_inf_t mme_inf[10];
+ int cnt;
+ int nb_mme = 0;
+ uint64_t weight = 0;
+
+ memset(mme_inf, 0, sizeof(mme_inf));
+
RB_FOREACH(mme_data_p, s1ap_mme_map, &instance_p->s1ap_mme_head) {
+ capacity_sum = capacity_sum + mme_data_p->relative_mme_capacity;
if (mme_data_p->state != S1AP_ENB_STATE_CONNECTED) {
/* The association between MME and eNB is not ready for the moment,
* go to the next known MME.
@@ -69,7 +83,8 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p,
|| (cause == RRC_CAUSE_HIGH_PRIO_ACCESS))) {
continue;
}
-
+ mme_inf[nb_mme].mme_p = mme_data_p;
+ nb_mme++;
/* At this point, the RRC establishment can be handled by the MME
* even if it is in overload state.
*/
@@ -78,14 +93,27 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p,
continue;
}
}
-
- if (current_capacity < mme_data_p->relative_mme_capacity) {
- /* We find a better MME, keep a reference to it */
- current_capacity = mme_data_p->relative_mme_capacity;
- mme_highest_capacity_p = mme_data_p;
- }
}
-
+
+ if( nb_mme != 0 ) {
+ for( cnt = 0 ; cnt < nb_mme ; cnt++ ) {
+ mme_inf[cnt].weight = (capacity_sum*10)/mme_inf[cnt].mme_p->relative_mme_capacity;
+ mme_inf[cnt].weight = (mme_inf[cnt].weight)*(mme_inf[cnt].mme_p->nb_calls + 1);
+ }
+ mme_highest_capacity_p = mme_inf[0].mme_p;
+ weight = mme_inf[0].weight;
+ for( cnt = 1 ; cnt < nb_mme ; cnt++ ) {
+ if( weight > mme_inf[cnt].weight ) {
+ mme_highest_capacity_p = mme_inf[cnt].mme_p;
+ weight = mme_inf[cnt].weight;
+ }
+ }
+ } else {
+ mme_highest_capacity_p = NULL;
+ }
+ if( mme_highest_capacity_p != NULL ) {
+ mme_highest_capacity_p->nb_calls++;
+ }
return mme_highest_capacity_p;
}
@@ -96,8 +124,15 @@ s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t *instance_p,
{
struct s1ap_eNB_mme_data_s *mme_data_p = NULL;
struct s1ap_eNB_mme_data_s *mme_highest_capacity_p = NULL;
- uint8_t current_capacity = 0;
-
+
+ uint16_t capacity_sum = 0;
+ MME_nnsf_inf_t mme_inf[10];
+ int cnt;
+ int nb_mme = 0;
+ uint64_t weight = 0;
+
+ memset(mme_inf, 0, sizeof(mme_inf));
+
RB_FOREACH(mme_data_p, s1ap_mme_map, &instance_p->s1ap_mme_head) {
struct served_gummei_s *gummei_p = NULL;
struct plmn_identity_s *served_plmn_p = NULL;
@@ -140,6 +175,8 @@ s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t *instance_p,
STAILQ_FOREACH(served_plmn_p, &gummei_p->served_plmns, next) {
if ((served_plmn_p->mcc == instance_p->mcc[selected_plmn_identity]) &&
(served_plmn_p->mnc == instance_p->mnc[selected_plmn_identity])) {
+ mme_inf[nb_mme].mme_p = mme_data_p;
+ nb_mme++;
break;
}
}
@@ -148,14 +185,27 @@ s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t *instance_p,
}
/* if we didn't find such a served PLMN, go on with the next MME */
if (!served_plmn_p) continue;
-
- if (current_capacity < mme_data_p->relative_mme_capacity) {
- /* We find a better MME, keep a reference to it */
- current_capacity = mme_data_p->relative_mme_capacity;
- mme_highest_capacity_p = mme_data_p;
- }
}
+ if( nb_mme != 0 ) {
+ for( cnt = 0 ; cnt < nb_mme ; cnt++ ) {
+ mme_inf[cnt].weight = (capacity_sum*10)/mme_inf[cnt].mme_p->relative_mme_capacity;
+ mme_inf[cnt].weight = (mme_inf[cnt].weight)*(mme_inf[cnt].mme_p->nb_calls + 1);
+ }
+ mme_highest_capacity_p = mme_inf[0].mme_p;
+ weight = mme_inf[0].weight;
+ for( cnt = 1 ; cnt < nb_mme ; cnt++ ) {
+ if( weight > mme_inf[cnt].weight ) {
+ mme_highest_capacity_p = mme_inf[cnt].mme_p;
+ weight = mme_inf[cnt].weight;
+ }
+ }
+ } else {
+ mme_highest_capacity_p = NULL;
+ }
+ if( mme_highest_capacity_p != NULL ) {
+ mme_highest_capacity_p->nb_calls++;
+ }
return mme_highest_capacity_p;
}
diff --git a/openair3/S1AP/s1ap_eNB_overload.c b/openair3/S1AP/s1ap_eNB_overload.c
index 9358ae62bd..64d3fcdf65 100644
--- a/openair3/S1AP/s1ap_eNB_overload.c
+++ b/openair3/S1AP/s1ap_eNB_overload.c
@@ -62,8 +62,16 @@ int s1ap_eNB_handle_overload_start(uint32_t assoc_id,
S1AP_OverloadResponse_PR_overloadAction,
S1AP_OverloadResponse_PR_overloadAction, 0, 0);
}
+ else
+ {
+ return -1;
+ }
/* Non UE-associated signalling -> stream 0 */
- DevCheck(stream == 0, stream, 0, 0);
+ if (stream != 0) {
+ S1AP_ERROR("[SCTP %d] Received s1 overload start on stream != 0 (%d)\n",
+ assoc_id, stream);
+ return -1;
+ }
if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
/* No MME context associated */
@@ -93,7 +101,11 @@ int s1ap_eNB_handle_overload_stop(uint32_t assoc_id,
s1ap_eNB_mme_data_t *mme_desc_p;
/* Non UE-associated signalling -> stream 0 */
- DevCheck(stream == 0, stream, 0, 0);
+ if (stream != 0) {
+ S1AP_ERROR("[SCTP %d] Received s1 overload stop on stream != 0 (%d)\n",
+ assoc_id, stream);
+ return -1;
+ }
if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
/* No MME context associated */
diff --git a/openair3/S1AP/s1ap_eNB_trace.c b/openair3/S1AP/s1ap_eNB_trace.c
index 19f5059238..695eeb4ef8 100644
--- a/openair3/S1AP/s1ap_eNB_trace.c
+++ b/openair3/S1AP/s1ap_eNB_trace.c
@@ -121,6 +121,10 @@ int s1ap_eNB_handle_trace_start(uint32_t assoc_id,
if (ie != NULL) {
ue_desc_p = s1ap_eNB_get_ue_context(mme_ref_p->s1ap_eNB_instance,
ie->value.choice.ENB_UE_S1AP_ID);
+ }
+ else
+ {
+ return -1;
}
if (ue_desc_p == NULL) {
/* Could not find context associated with this eNB_ue_s1ap_id -> generate
diff --git a/openair3/SCTP/sctp_default_values.h b/openair3/SCTP/sctp_default_values.h
index 528ffb5a05..0f8f94dca9 100644
--- a/openair3/SCTP/sctp_default_values.h
+++ b/openair3/SCTP/sctp_default_values.h
@@ -24,8 +24,8 @@
#define SCTP_OUT_STREAMS (16)
#define SCTP_IN_STREAMS (16)
-#define SCTP_MAX_ATTEMPTS (2)
-#define SCTP_TIMEOUT (5)
+#define SCTP_MAX_ATTEMPTS (8)
+#define SCTP_TIMEOUT (60000)
#define SCTP_RECV_BUFFER_SIZE (8192)
#endif /* SCTP_DEFAULT_VALUES_H_ */
diff --git a/openair3/SCTP/sctp_eNB_task.c b/openair3/SCTP/sctp_eNB_task.c
index 2f732443be..af49c5c350 100644
--- a/openair3/SCTP/sctp_eNB_task.c
+++ b/openair3/SCTP/sctp_eNB_task.c
@@ -270,7 +270,7 @@ sctp_handle_new_association_req_multi(
sctp_new_association_req_p->remote_address.ipv6_address);
//close(sd);
//return;
- exit(1);
+ exit_fun("sctp_handle_new_association_req_multi fatal: inet_pton error");
}
SCTP_DEBUG("Converted ipv6 address %*s to network type\n",
@@ -290,7 +290,7 @@ sctp_handle_new_association_req_multi(
sctp_new_association_req_p->remote_address.ipv4_address);
//close(sd);
//return;
- exit(1);
+ exit_fun("sctp_handle_new_association_req_multi fatal: inet_pton error");
}
SCTP_DEBUG("Converted ipv4 address %*s to network type\n",
@@ -329,7 +329,7 @@ sctp_handle_new_association_req_multi(
if (ns == -1) {
perror("sctp_peeloff");
printf("sctp_peeloff: sd=%d assoc_id=%d\n", sd, assoc_id);
- exit(1);
+ exit_fun("sctp_handle_new_association_req_multi fatal: sctp_peeloff error");
}
sctp_cnx = calloc(1, sizeof(*sctp_cnx));
@@ -943,10 +943,12 @@ sctp_eNB_read_from_socket(
&sinfo, &flags);
if (n < 0) {
- if (errno == ENOTCONN) {
+ if( (errno == ENOTCONN) || (errno == ECONNRESET) || (errno == ETIMEDOUT) || (errno == ECONNREFUSED) )
+ {
itti_unsubscribe_event_fd(TASK_SCTP, sctp_cnx->sd);
SCTP_DEBUG("Received not connected for sd %d\n", sctp_cnx->sd);
+ SCTP_ERROR("sctp_recvmsg (fd %d, len %d ): %s:%d\n", sctp_cnx->sd, n, strerror(errno), errno);
sctp_itti_send_association_resp(
sctp_cnx->task_id, sctp_cnx->instance, -1,
@@ -969,7 +971,7 @@ sctp_eNB_read_from_socket(
if (!(flags & MSG_EOR)) {
SCTP_ERROR("fatal: partial SCTP messages are not handled\n");
- exit(1);
+ exit_fun("fatal: partial SCTP messages are not handled" );
}
if (flags & MSG_NOTIFICATION) {
diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h
index 85ee80ea7c..93e9ffb52f 100644
--- a/targets/ARCH/COMMON/common_lib.h
+++ b/targets/ARCH/COMMON/common_lib.h
@@ -105,9 +105,10 @@ typedef enum {
ADRV9371_ZC706_DEV,
/*!\brief device is UEDv2 */
UEDv2_DEV,
+ RFSIMULATOR,
MAX_RF_DEV_TYPE
} dev_type_t;
-#define DEVTYPE_NAMES {"","EXMIMO","USRP B200","USRP X300","USRP N300","BLADERF","LMSSDR","IRIS","No HW","ADRV9371_ZC706","UEDv2"}
+#define DEVTYPE_NAMES {"","EXMIMO","USRP B200","USRP X300","USRP N300","BLADERF","LMSSDR","IRIS","No HW","ADRV9371_ZC706","UEDv2", "RFSIMULATOR"}
/*!\brief transport protocol types
*/
typedef enum {
@@ -491,15 +492,11 @@ struct openair0_device_t {
typedef int(*oai_device_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg);
/* type of transport init function, implemented in shared lib */
typedef int(*oai_transport_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t *eth_params);
-#define UE_MAGICDL_FDD 0xA5A5A5A5A5A5A5A5 // UE DL FDD record
-#define UE_MAGICUL_FDD 0x5A5A5A5A5A5A5A5A // UE UL FDD record
-#define UE_MAGICDL_TDD 0xA6A6A6A6A6A6A6A6 // UE DL TDD record
-#define UE_MAGICUL_TDD 0x6A6A6A6A6A6A6A6A // UE UL TDD record
+#define UE_MAGICDL 0xA5A5A5A5A5A5A5A5 // UE DL FDD record
+#define UE_MAGICUL 0x5A5A5A5A5A5A5A5A // UE UL FDD record
-#define ENB_MAGICDL_FDD 0xB5B5B5B5B5B5B5B5 // eNB DL FDD record
-#define ENB_MAGICUL_FDD 0x5B5B5B5B5B5B5B5B // eNB UL FDD record
-#define ENB_MAGICDL_TDD 0xB6B6B6B6B6B6B6B6 // eNB DL TDD record
-#define ENB_MAGICUL_TDD 0x6B6B6B6B6B6B6B6B // eNB UL TDD record
+#define ENB_MAGICDL 0xB5B5B5B5B5B5B5B5 // eNB DL FDD record
+#define ENB_MAGICUL 0x5B5B5B5B5B5B5B5B // eNB UL FDD record
#define OPTION_LZ4 0x00000001 // LZ4 compression (option_value is set to compressed size)
@@ -516,19 +513,6 @@ typedef struct {
uint32_t option_flag; // Option flag
} samplesBlockHeader_t;
-#define UE_MAGICDL_FDD 0xA5A5A5A5A5A5A5A5 // UE DL FDD record
-#define UE_MAGICUL_FDD 0x5A5A5A5A5A5A5A5A // UE UL FDD record
-#define UE_MAGICDL_TDD 0xA6A6A6A6A6A6A6A6 // UE DL TDD record
-#define UE_MAGICUL_TDD 0x6A6A6A6A6A6A6A6A // UE UL TDD record
-
-#define ENB_MAGICDL_FDD 0xB5B5B5B5B5B5B5B5 // eNB DL FDD record
-#define ENB_MAGICUL_FDD 0x5B5B5B5B5B5B5B5B // eNB UL FDD record
-#define ENB_MAGICDL_TDD 0xB6B6B6B6B6B6B6B6 // eNB DL TDD record
-#define ENB_MAGICUL_TDD 0x6B6B6B6B6B6B6B6B // eNB UL TDD record
-
-#define OPTION_LZ4 0x00000001 // LZ4 compression (option_value is set to compressed size)
-
-
#ifdef __cplusplus
extern "C"
{
diff --git a/targets/ARCH/ETHERNET/benetel/4g/benetel.c b/targets/ARCH/ETHERNET/benetel/4g/benetel.c
index 76855111e1..d3b72463b4 100644
--- a/targets/ARCH/ETHERNET/benetel/4g/benetel.c
+++ b/targets/ARCH/ETHERNET/benetel/4g/benetel.c
@@ -163,8 +163,8 @@ int trx_benetel_ctlrecv(openair0_device *device, void *msg, ssize_t msg_len)
cap->FH_fmt = OAI_IF4p5_only;
cap->num_bands = 1;
cap->band_list[0] = 7;
- cap->nb_rx[0] = 1;
- cap->nb_tx[0] = 1;
+ cap->nb_rx[0] = device->openair0_cfg->rx_num_channels;
+ cap->nb_tx[0] = device->openair0_cfg->tx_num_channels;
cap->max_pdschReferenceSignalPower[0] = -27;
cap->max_rxgain[0] = 90;
@@ -194,11 +194,12 @@ void benetel_fh_if4p5_south_in(RU_t *ru,
LTE_DL_FRAME_PARMS *fp;
int symbol;
int32_t *rxdata;
- int antenna = 0;
+ int antenna;
lock_ul_buffer(&s->buffers, *subframe);
next:
- while (!(s->buffers.ul_busy[*subframe] == 0x3fff ||
+ while (!((s->buffers.ul_busy[0][*subframe] == 0x3fff &&
+ s->buffers.ul_busy[1][*subframe] == 0x3fff) ||
s->buffers.prach_busy[*subframe] == 1))
wait_ul_buffer(&s->buffers, *subframe);
if (s->buffers.prach_busy[*subframe] == 1) {
@@ -217,24 +218,27 @@ next:
eNB = eNB_list[0];
fp = &eNB->frame_parms;
- for (symbol = 0; symbol < 14; symbol++) {
- int i;
- uint16_t *p = (uint16_t *)(&s->buffers.ul[*subframe][symbol*1200*4]);
- for (i = 0; i < 1200*2; i++) {
- p[i] = htons(p[i]);
- }
- rxdata = &ru->common.rxdataF[antenna][symbol * fp->ofdm_symbol_size];
+ for (antenna = 0; antenna < ru->nb_rx; antenna++) {
+ for (symbol = 0; symbol < 14; symbol++) {
+ int i;
+ uint16_t *p = (uint16_t *)(&s->buffers.ul[antenna][*subframe][symbol*1200*4]);
+ for (i = 0; i < 1200*2; i++) {
+ p[i] = htons(p[i]);
+ }
+ rxdata = &ru->common.rxdataF[antenna][symbol * fp->ofdm_symbol_size];
#if 1
- memcpy(rxdata + 2048 - 600,
- &s->buffers.ul[*subframe][symbol*1200*4],
- 600 * 4);
- memcpy(rxdata,
- &s->buffers.ul[*subframe][symbol*1200*4] + 600*4,
- 600 * 4);
+ memcpy(rxdata + 2048 - 600,
+ &s->buffers.ul[antenna][*subframe][symbol*1200*4],
+ 600 * 4);
+ memcpy(rxdata,
+ &s->buffers.ul[antenna][*subframe][symbol*1200*4] + 600*4,
+ 600 * 4);
#endif
+ }
}
- s->buffers.ul_busy[*subframe] = 0;
+ s->buffers.ul_busy[0][*subframe] = 0;
+ s->buffers.ul_busy[1][*subframe] = 0;
signal_ul_buffer(&s->buffers, *subframe);
unlock_ul_buffer(&s->buffers, *subframe);
@@ -272,45 +276,49 @@ void benetel_fh_if4p5_south_out(RU_t *ru,
LTE_DL_FRAME_PARMS *fp;
int symbol;
int32_t *txdata;
- int aa = 0;
+ int aa;
//printf("BENETEL: %s (f.sf %d.%d ts %ld)\n", __FUNCTION__, frame, subframe, timestamp);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
lock_dl_buffer(&s->buffers, subframe);
- if (s->buffers.dl_busy[subframe]) {
+ if (s->buffers.dl_busy[0][subframe] ||
+ s->buffers.dl_busy[1][subframe]) {
printf("%s: fatal: DL buffer busy for subframe %d\n", __FUNCTION__, subframe);
unlock_dl_buffer(&s->buffers, subframe);
return;
}
eNB = eNB_list[0];
fp = &eNB->frame_parms;
- if (ru->num_eNB != 1 || ru->nb_tx != 1 || fp->ofdm_symbol_size != 2048 ||
+ if (ru->num_eNB != 1 || fp->ofdm_symbol_size != 2048 ||
fp->Ncp != NORMAL || fp->symbols_per_tti != 14) {
printf("%s:%d:%s: unsupported configuration\n",
__FILE__, __LINE__, __FUNCTION__);
exit(1);
}
- for (symbol = 0; symbol < 14; symbol++) {
- txdata = &ru->common.txdataF_BF[aa][symbol * fp->ofdm_symbol_size];
+ for (aa = 0; aa < ru->nb_tx; aa++) {
+ for (symbol = 0; symbol < 14; symbol++) {
+ txdata = &ru->common.txdataF_BF[aa][symbol * fp->ofdm_symbol_size];
#if 1
- memcpy(&s->buffers.dl[subframe][symbol*1200*4],
- txdata + 2048 - 600,
- 600 * 4);
- memcpy(&s->buffers.dl[subframe][symbol*1200*4] + 600*4,
- txdata + 1,
- 600 * 4);
+ memcpy(&s->buffers.dl[aa][subframe][symbol*1200*4],
+ txdata + 2048 - 600,
+ 600 * 4);
+ memcpy(&s->buffers.dl[aa][subframe][symbol*1200*4] + 600*4,
+ txdata + 1,
+ 600 * 4);
#endif
- int i;
- uint16_t *p = (uint16_t *)(&s->buffers.dl[subframe][symbol*1200*4]);
- for (i = 0; i < 1200*2; i++) {
- p[i] = htons(p[i]);
+ int i;
+ uint16_t *p = (uint16_t *)(&s->buffers.dl[aa][subframe][symbol*1200*4]);
+ for (i = 0; i < 1200*2; i++) {
+ p[i] = htons(p[i]);
+ }
}
}
- s->buffers.dl_busy[subframe] = 0x3fff;
+ s->buffers.dl_busy[0][subframe] = 0x3fff;
+ s->buffers.dl_busy[1][subframe] = 0x3fff;
unlock_dl_buffer(&s->buffers, subframe);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_IF4P5_SOUTH_OUT_RU+ru->idx, ru->proc.frame_tx);
diff --git a/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c b/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c
index 42953d1d4a..2b6ef37e6f 100644
--- a/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c
+++ b/targets/ARCH/ETHERNET/benetel/4g/dpdk_driver.c
@@ -233,19 +233,20 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs)
}
- if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && ANT_NUM == 0x00) {
+ if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce) {
p.frame = FRAME;
p.subframe = SUBFRAME >> 4;
p.slot = 0; /* unused */
p.symbol = SYMBOL;
- p.antenna = 0;
+ p.antenna = ANT_NUM;
memcpy(p.iq, IQ_ptr, 4800);
store_ul(bs, &p);
}
- // U-PLANE UL ANT_0 PROCESSING
- if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && ANT_NUM == 0x00 && dl_start == 1)
+ // U-PLANE UL PROCESSING
+ if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && dl_start == 1)
{
+ int a = ANT_NUM;
int tx_frame = FRAME;
int tx_subframe = SUBFRAME >> 4;
int tx_symbol = SYMBOL + 5;
@@ -266,33 +267,20 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs)
SUBFRAME = tx_subframe << 4;
SYMBOL = tx_symbol;
- /* antenna 0 - send actual DL data (if available) */
+ /* send actual DL data (if available) */
lock_dl_buffer(bs->buffers, tx_subframe);
- if (!(bs->buffers->dl_busy[tx_subframe] & (1 << tx_symbol))) {
- printf("%s: warning, DL underflow (sf.symbol %d.%d)\n", __FUNCTION__,
+ if (!(bs->buffers->dl_busy[a][tx_subframe] & (1 << tx_symbol))) {
+ printf("%s: warning, DL underflow (antenna %d sf.symbol %d.%d)\n",
+ __FUNCTION__,
+ a,
tx_subframe, tx_symbol);
memset(IQ_ptr, 0, 1200 * 4);
} else {
- memcpy(IQ_ptr, bs->buffers->dl[tx_subframe] + tx_symbol * 1200*4,
+ memcpy(IQ_ptr, bs->buffers->dl[a][tx_subframe] + tx_symbol * 1200*4,
1200*4);
}
- bs->buffers->dl_busy[tx_subframe] &= ~(1 << tx_symbol);
+ bs->buffers->dl_busy[a][tx_subframe] &= ~(1 << tx_symbol);
unlock_dl_buffer(bs->buffers, tx_subframe);
-
- // fill DL Data for ant 0 with 0 value
-// memset(IQ_ptr, 0, 4800);
- }
-
- // U-PLANE UL ANT_1 PROCESSING
- else if(PAYLOAD_1 == 0x12 && PAYLOAD_2 == 0xce && ANT_NUM == 0x01 && dl_start == 1)
- {
-
-// ANT_NUM = 0x01;
- SYMBOL = (SYMBOL + 5) % 14;
- PAYLOAD_2 = 0xc8;
-
- // fill DL Data for ant 1 with 0 value
- memset(IQ_ptr, 0, 4800);
}
// U-PLANE PRACH PROCESSING
diff --git a/targets/ARCH/ETHERNET/benetel/4g/low.c b/targets/ARCH/ETHERNET/benetel/4g/low.c
index 038592d596..14783a700b 100644
--- a/targets/ARCH/ETHERNET/benetel/4g/low.c
+++ b/targets/ARCH/ETHERNET/benetel/4g/low.c
@@ -27,37 +27,36 @@
void store_ul(benetel_t *bs, ul_packet_t *ul)
{
- /* only antenna 0 for the moment */
- if (ul->antenna != 0)
- return;
+ int a = ul->antenna;
- if (ul->subframe != bs->next_subframe ||
- ul->symbol != bs->next_symbol) {
- printf("%s: fatal, expected frame.sf.symbol %d.%d.%d, got %d.%d.%d\n",
+ if (ul->subframe != bs->next_subframe[a] ||
+ ul->symbol != bs->next_symbol[a]) {
+ printf("%s: fatal, antenna %d expected frame.sf.symbol %d.%d.%d, got %d.%d.%d\n",
__FUNCTION__,
- bs->expected_benetel_frame, bs->next_subframe, bs->next_symbol,
+ a,
+ bs->expected_benetel_frame[a], bs->next_subframe[a], bs->next_symbol[a],
ul->frame, ul->subframe, ul->symbol);
exit(1);
}
- lock_ul_buffer(bs->buffers, bs->next_subframe);
- if (bs->buffers->ul_busy[bs->next_subframe] & (1 << bs->next_symbol)) {
+ lock_ul_buffer(bs->buffers, bs->next_subframe[a]);
+ if (bs->buffers->ul_busy[a][bs->next_subframe[a]] & (1 << bs->next_symbol[a])) {
printf("%s: warning, UL overflow (sf.symbol %d.%d)\n", __FUNCTION__,
- bs->next_subframe, bs->next_symbol);
+ bs->next_subframe[a], bs->next_symbol[a]);
}
- memcpy(bs->buffers->ul[bs->next_subframe] + bs->next_symbol * 1200*4,
+ memcpy(bs->buffers->ul[a][bs->next_subframe[a]] + bs->next_symbol[a] * 1200*4,
ul->iq, 1200*4);
- bs->buffers->ul_busy[bs->next_subframe] |= (1 << bs->next_symbol);
- signal_ul_buffer(bs->buffers, bs->next_subframe);
- unlock_ul_buffer(bs->buffers, bs->next_subframe);
+ bs->buffers->ul_busy[a][bs->next_subframe[a]] |= (1 << bs->next_symbol[a]);
+ signal_ul_buffer(bs->buffers, bs->next_subframe[a]);
+ unlock_ul_buffer(bs->buffers, bs->next_subframe[a]);
- bs->next_symbol++;
- if (bs->next_symbol == 14) {
- bs->next_symbol = 0;
- bs->next_subframe = (bs->next_subframe + 1) % 10;
- if (bs->next_subframe == 0) {
- bs->expected_benetel_frame++;
- bs->expected_benetel_frame &= 255;
+ bs->next_symbol[a]++;
+ if (bs->next_symbol[a] == 14) {
+ bs->next_symbol[a] = 0;
+ bs->next_subframe[a] = (bs->next_subframe[a] + 1) % 10;
+ if (bs->next_subframe[a] == 0) {
+ bs->expected_benetel_frame[a]++;
+ bs->expected_benetel_frame[a] &= 255;
}
}
}
diff --git a/targets/ARCH/ETHERNET/benetel/4g/low.h b/targets/ARCH/ETHERNET/benetel/4g/low.h
index 5e75d9181e..e74bf89163 100644
--- a/targets/ARCH/ETHERNET/benetel/4g/low.h
+++ b/targets/ARCH/ETHERNET/benetel/4g/low.h
@@ -26,9 +26,10 @@
typedef struct {
shared_buffers *buffers;
- int next_subframe;
- int next_symbol;
- int expected_benetel_frame;
+ /* [2] is for two antennas */
+ int next_subframe[2];
+ int next_symbol[2];
+ int expected_benetel_frame[2];
char *dpdk_main_command_line;
} benetel_t;
diff --git a/targets/ARCH/ETHERNET/benetel/4g/low_dpdk.c b/targets/ARCH/ETHERNET/benetel/4g/low_dpdk.c
index ecff473010..edf62a67e0 100644
--- a/targets/ARCH/ETHERNET/benetel/4g/low_dpdk.c
+++ b/targets/ARCH/ETHERNET/benetel/4g/low_dpdk.c
@@ -68,7 +68,8 @@ void *benetel_start_dpdk(char *ifname, shared_buffers *buffers, char *dpdk_main_
bs->buffers = buffers;
- bs->expected_benetel_frame = 255;
+ bs->expected_benetel_frame[0] = 255;
+ bs->expected_benetel_frame[1] = 255;
bs->dpdk_main_command_line = dpdk_main_command_line;
diff --git a/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.c b/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.c
index 492a15dfc3..380cbabc73 100644
--- a/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.c
+++ b/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.c
@@ -44,9 +44,12 @@ void init_buffers(shared_buffers *s)
/* in FDD the eNB's first transmitted DL subframe is 4 but the device
* needs to have subframes 1, 2 and 3 ready. Let's pretend there are ready.
*/
- s->dl_busy[1] = 0x3fff;
- s->dl_busy[2] = 0x3fff;
- s->dl_busy[3] = 0x3fff;
+ s->dl_busy[0][1] = 0x3fff;
+ s->dl_busy[0][2] = 0x3fff;
+ s->dl_busy[0][3] = 0x3fff;
+ s->dl_busy[1][1] = 0x3fff;
+ s->dl_busy[1][2] = 0x3fff;
+ s->dl_busy[1][3] = 0x3fff;
}
void lock_dl_buffer(shared_buffers *s, int subframe)
diff --git a/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.h b/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.h
index 1d5040b95b..ed174265c5 100644
--- a/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.h
+++ b/targets/ARCH/ETHERNET/benetel/4g/shared_buffers.h
@@ -26,10 +26,11 @@
#include
typedef struct {
- unsigned char dl[10][14*1200*4];
- unsigned char ul[10][14*1200*4];
- uint16_t dl_busy[10];
- uint16_t ul_busy[10];
+ /* [2] is for two antennas */
+ unsigned char dl[2][10][14*1200*4];
+ unsigned char ul[2][10][14*1200*4];
+ uint16_t dl_busy[2][10];
+ uint16_t ul_busy[2][10];
pthread_mutex_t m_ul[10];
pthread_cond_t c_ul[10];
diff --git a/targets/ARCH/ETHERNET/benetel/5g/benetel.c b/targets/ARCH/ETHERNET/benetel/5g/benetel.c
index 2f60e7dc49..cededa968e 100644
--- a/targets/ARCH/ETHERNET/benetel/5g/benetel.c
+++ b/targets/ARCH/ETHERNET/benetel/5g/benetel.c
@@ -162,8 +162,9 @@ int trx_benetel_ctlrecv(openair0_device *device, void *msg, ssize_t msg_len)
cap->FH_fmt = OAI_IF4p5_only;
cap->num_bands = 1;
cap->band_list[0] = 78;
- cap->nb_rx[0] = 1;
- cap->nb_tx[0] = 1;
+ /* TODO: hardcoded to 1 for the moment, get the real value somehow... */
+ cap->nb_rx[0] = 1; //device->openair0_cfg->rx_num_channels;
+ cap->nb_tx[0] = 1; //device->openair0_cfg->tx_num_channels;
cap->max_pdschReferenceSignalPower[0] = -27;
cap->max_rxgain[0] = 90;
@@ -201,12 +202,13 @@ void benetel_fh_if4p5_south_in(RU_t *ru,
NR_DL_FRAME_PARMS *fp;
int symbol;
int32_t *rxdata;
- int antenna = 0;
+ int antenna;
lock_ul_buffer(&s->buffers, *slot);
#if 1
next:
- while (!(s->buffers.ul_busy[*slot] == 0x3fff ||
+ while (!((s->buffers.ul_busy[0][*slot] == 0x3fff &&
+ s->buffers.ul_busy[1][*slot] == 0x3fff) ||
s->buffers.prach_busy[*slot] == 1))
wait_ul_buffer(&s->buffers, *slot);
if (s->buffers.prach_busy[*slot] == 1) {
@@ -226,24 +228,31 @@ next:
#endif
fp = ru->nr_frame_parms;
- for (symbol = 0; symbol < 14; symbol++) {
- int i;
- uint16_t *p = (uint16_t *)(&s->buffers.ul[*slot][symbol*1272*4]);
- for (i = 0; i < 1272*2; i++) {
- p[i] = htons(p[i]);
- }
- rxdata = &ru->common.rxdataF[antenna][symbol * fp->ofdm_symbol_size];
-#if 1
- memcpy(rxdata + 2048 - 1272/2,
- &s->buffers.ul[*slot][symbol*1272*4],
- (1272/2) * 4);
- memcpy(rxdata,
- &s->buffers.ul[*slot][symbol*1272*4] + (1272/2)*4,
- (1272/2) * 4);
+ for (antenna = 0; antenna < ru->nb_rx; antenna++) {
+ for (symbol = 0; symbol < 14; symbol++) {
+ int i;
+ int16_t *p = (int16_t *)(&s->buffers.ul[antenna][*slot][symbol*1272*4]);
+ for (i = 0; i < 1272*2; i++) {
+ p[i] = (int16_t)(ntohs(p[i])) / 16;
+ }
+ rxdata = &ru->common.rxdataF[antenna][symbol * fp->ofdm_symbol_size];
+#if 0
+if (*slot == 0 && symbol == 0)
+printf("rxdata in benetel_fh_if4p5_south_in %p\n", &ru->common.rxdataF[antenna][0]);
#endif
+#if 1
+ memcpy(rxdata + 2048 - 1272/2,
+ &s->buffers.ul[antenna][*slot][symbol*1272*4],
+ (1272/2) * 4);
+ memcpy(rxdata,
+ &s->buffers.ul[antenna][*slot][symbol*1272*4] + (1272/2)*4,
+ (1272/2) * 4);
+#endif
+ }
}
- s->buffers.ul_busy[*slot] = 0;
+ s->buffers.ul_busy[0][*slot] = 0;
+ s->buffers.ul_busy[1][*slot] = 0;
signal_ul_buffer(&s->buffers, *slot);
unlock_ul_buffer(&s->buffers, *slot);
@@ -281,43 +290,47 @@ void benetel_fh_if4p5_south_out(RU_t *ru,
NR_DL_FRAME_PARMS *fp;
int symbol;
int32_t *txdata;
- int aa = 0;
+ int aa;
//printf("BENETEL: %s (f.sf %d.%d ts %ld)\n", __FUNCTION__, frame, slot, timestamp);
lock_dl_buffer(&s->buffers, slot);
- if (s->buffers.dl_busy[slot]) {
+ if (s->buffers.dl_busy[0][slot] ||
+ s->buffers.dl_busy[1][slot]) {
printf("%s: fatal: DL buffer busy for subframe %d\n", __FUNCTION__, slot);
unlock_dl_buffer(&s->buffers, slot);
return;
}
fp = ru->nr_frame_parms;
- if (ru->num_gNB != 1 || ru->nb_tx != 1 || fp->ofdm_symbol_size != 2048 ||
+ if (ru->num_gNB != 1 || fp->ofdm_symbol_size != 2048 ||
fp->Ncp != NORMAL || fp->symbols_per_slot != 14) {
printf("%s:%d:%s: unsupported configuration\n",
__FILE__, __LINE__, __FUNCTION__);
exit(1);
}
- for (symbol = 0; symbol < 14; symbol++) {
- txdata = &ru->common.txdataF_BF[aa][symbol * fp->ofdm_symbol_size];
+ for (aa = 0; aa < ru->nb_tx; aa++) {
+ for (symbol = 0; symbol < 14; symbol++) {
+ txdata = &ru->common.txdataF_BF[aa][symbol * fp->ofdm_symbol_size];
#if 1
- memcpy(&s->buffers.dl[slot][symbol*1272*4],
- txdata + 2048 - (1272/2),
- (1272/2) * 4);
- memcpy(&s->buffers.dl[slot][symbol*1272*4] + (1272/2)*4,
- txdata,
- (1272/2) * 4);
+ memcpy(&s->buffers.dl[aa][slot][symbol*1272*4],
+ txdata + 2048 - (1272/2),
+ (1272/2) * 4);
+ memcpy(&s->buffers.dl[aa][slot][symbol*1272*4] + (1272/2)*4,
+ txdata,
+ (1272/2) * 4);
#endif
- int i;
- uint16_t *p = (uint16_t *)(&s->buffers.dl[slot][symbol*1272*4]);
- for (i = 0; i < 1272*2; i++) {
- p[i] = htons(p[i]);
+ int i;
+ uint16_t *p = (uint16_t *)(&s->buffers.dl[aa][slot][symbol*1272*4]);
+ for (i = 0; i < 1272*2; i++) {
+ p[i] = htons(p[i]);
+ }
}
}
- s->buffers.dl_busy[slot] = 0x3fff;
+ s->buffers.dl_busy[0][slot] = 0x3fff;
+ s->buffers.dl_busy[1][slot] = 0x3fff;
unlock_dl_buffer(&s->buffers, slot);
}
diff --git a/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c b/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c
index dd50603ec5..88f4ecb4cd 100644
--- a/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c
+++ b/targets/ARCH/ETHERNET/benetel/5g/dpdk_driver.c
@@ -243,21 +243,22 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs)
}
- if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4 && ANT_NUM == 0x00) {
+ if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4) {
int subframe = SUBFRAME >> 4;
int slot = ((SUBFRAME & 0x0f) << 2) | ((SYMBOL >> 6) & 0x03);
p.frame = FRAME;
p.slot = subframe * 2 + slot;
p.symbol = SYMBOL & 0x3f;
- p.antenna = 0;
+ p.antenna = ANT_NUM;
memcpy(p.iq, IQ_ptr, 5088);
store_ul(bs, &p);
// if (p.symbol==0) printf("store ul f.sl.sy %d.%d.%d\n", p.frame, p.slot, p.symbol);
}
- // U-PLANE UL ANT_0 PROCESSING
- if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4 && ANT_NUM == 0x00 && dl_start == 1)
+ // U-PLANE UL PROCESSING
+ if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4 && dl_start == 1)
{
+ int a = ANT_NUM & 0x01;
int frame = FRAME;
int subframe = SUBFRAME >> 4;
int slot = ((SUBFRAME & 0x0f) << 2) | ((SYMBOL >> 6) & 0x03);
@@ -282,66 +283,45 @@ l2fwd_simple_forward(struct rte_mbuf *m, unsigned portid, benetel_t *bs)
}
}
- ANT_NUM = 0x00;
-
// Mask the symbol bits from UL packet received and apply the shift.
SYMBOL = ((SYMBOL & 0b00111111) + 10) % 14;
- ANT_NUM = 0x00;
+ ANT_NUM = a;
SUBFRAME = sf;
+ if (a == 1)
+ slot_id_ctrl++;
+
// Slot id control for DL
- if(slot_id_ctrl > 13){
- SYMBOL = SYMBOL | 0b01000000;
+ if (slot_id_ctrl > 13) {
+ SYMBOL = SYMBOL | 0b01000000;
+
+ if (a == 1) {
+ if (slot_id_ctrl > 27) {
+ slot_id_ctrl = 0;
+ sf = sf + 0x10;
+
+ if (sf > 0x90){
+ sf = 0;
+ }
+ }
+ }
}
- /* antenna 0 - send actual DL data (if available) */
+ /* send actual DL data (if available) */
oai_slot = tx_subframe * 2 + tx_slot;
lock_dl_buffer(bs->buffers, oai_slot);
- if (!(bs->buffers->dl_busy[oai_slot] & (1 << tx_symbol))) {
- printf("%s: warning, DL underflow (sl.symbol %d.%d)\n", __FUNCTION__,
- oai_slot, tx_symbol);
+ if (!(bs->buffers->dl_busy[a][oai_slot] & (1 << tx_symbol))) {
+ printf("%s: warning, DL underflow (antenna %d sl.symbol %d.%d)\n", __FUNCTION__,
+ a, oai_slot, tx_symbol);
memset(IQ_ptr, 0, 1272 * 4);
} else {
- memcpy(IQ_ptr, bs->buffers->dl[oai_slot] + tx_symbol * 1272*4,
+ memcpy(IQ_ptr, bs->buffers->dl[a][oai_slot] + tx_symbol * 1272*4,
1272*4);
}
//printf("DL buffer f sf slot symbol %d %d %d %d (sf %d)\n", tx_frame, tx_subframe, tx_slot, tx_symbol, (int)sf);
- bs->buffers->dl_busy[oai_slot] &= ~(1 << tx_symbol);
+ bs->buffers->dl_busy[a][oai_slot] &= ~(1 << tx_symbol);
unlock_dl_buffer(bs->buffers, oai_slot);
-
- // fill DL Data for ant 0 with 0 value
-// memset(IQ_ptr, 0, 5088);
- }
-
- // U-PLANE UL ANT_1 PROCESSING
- if(PAYLOAD_1 == 0x13 && PAYLOAD_2 == 0xe4 && ANT_NUM == 0x01 && dl_start == 1)
- {
-
- // Mask the symbol bits from UL packet received and apply the shift.
- SYMBOL = ((SYMBOL & 0b00111111) +10) % 14;
-
- ANT_NUM = 0x01;
- SUBFRAME = sf;
-
- slot_id_ctrl++;
-
- // Slot id control for DL
- if(slot_id_ctrl > 13){
- SYMBOL = SYMBOL | 0b01000000;
-
- if(slot_id_ctrl > 27){
- slot_id_ctrl = 0;
- sf = sf + 0x10;
-
- if (sf >0x90){
- sf = 0;
- }
- }
- }
-
- // fill DL Data for ant 1 with 0 value
- memset(IQ_ptr, 0, 5088);
}
// U-PLANE PRACH PROCESSING
diff --git a/targets/ARCH/ETHERNET/benetel/5g/low.c b/targets/ARCH/ETHERNET/benetel/5g/low.c
index 52c9f24127..b34d69784f 100644
--- a/targets/ARCH/ETHERNET/benetel/5g/low.c
+++ b/targets/ARCH/ETHERNET/benetel/5g/low.c
@@ -35,63 +35,61 @@ printf("store_ul %d.%ld (%ld)\n", (int)(t.tv_sec % 60), t.tv_nsec, t.tv_nsec - o
old = t;
#endif
- /* only antenna 0 for the moment */
- if (ul->antenna != 0)
- return;
+ int a = ul->antenna;
- if (ul->slot != bs->next_slot ||
- ul->symbol != bs->next_symbol) {
- printf("%s: error, expected frame.sl.symbol %d.%d.%d, got %d.%d.%d\n",
+ if (ul->slot != bs->next_slot[a] ||
+ ul->symbol != bs->next_symbol[a]) {
+ printf("%s: error, antenna %d expected frame.sl.symbol %d.%d.%d, got %d.%d.%d\n",
__FUNCTION__,
- bs->expected_benetel_frame, bs->next_slot, bs->next_symbol,
+ a, bs->expected_benetel_frame[a], bs->next_slot[a], bs->next_symbol[a],
ul->frame, ul->slot, ul->symbol);
}
/* fill missing data with 0s */
- while (ul->slot != bs->next_slot ||
- ul->symbol != bs->next_symbol) {
- lock_ul_buffer(bs->buffers, bs->next_slot);
- if (bs->buffers->ul_busy[bs->next_slot] & (1 << bs->next_symbol)) {
- printf("%s: warning, UL overflow (sl.symbol %d.%d)\n", __FUNCTION__,
- bs->next_slot, bs->next_symbol);
+ while (ul->slot != bs->next_slot[a] ||
+ ul->symbol != bs->next_symbol[a]) {
+ lock_ul_buffer(bs->buffers, bs->next_slot[a]);
+ if (bs->buffers->ul_busy[a][bs->next_slot[a]] & (1 << bs->next_symbol[a])) {
+ printf("%s: warning, antenna %d UL overflow (sl.symbol %d.%d)\n", __FUNCTION__,
+ a, bs->next_slot[a], bs->next_symbol[a]);
}
- memset(bs->buffers->ul[bs->next_slot] + bs->next_symbol * 1272*4,
+ memset(bs->buffers->ul[a][bs->next_slot[a]] + bs->next_symbol[a] * 1272*4,
0, 1272*4);
- bs->buffers->ul_busy[bs->next_slot] |= (1 << bs->next_symbol);
- signal_ul_buffer(bs->buffers, bs->next_slot);
- unlock_ul_buffer(bs->buffers, bs->next_slot);
+ bs->buffers->ul_busy[a][bs->next_slot[a]] |= (1 << bs->next_symbol[a]);
+ signal_ul_buffer(bs->buffers, bs->next_slot[a]);
+ unlock_ul_buffer(bs->buffers, bs->next_slot[a]);
- bs->next_symbol++;
- if (bs->next_symbol == 14) {
- bs->next_symbol = 0;
- bs->next_slot = (bs->next_slot + 1) % 20;
- if (bs->next_slot == 0) {
- bs->expected_benetel_frame++;
- bs->expected_benetel_frame &= 255;
+ bs->next_symbol[a]++;
+ if (bs->next_symbol[a] == 14) {
+ bs->next_symbol[a] = 0;
+ bs->next_slot[a] = (bs->next_slot[a] + 1) % 20;
+ if (bs->next_slot[a] == 0) {
+ bs->expected_benetel_frame[a]++;
+ bs->expected_benetel_frame[a] &= 255;
}
}
}
- lock_ul_buffer(bs->buffers, bs->next_slot);
- if (bs->buffers->ul_busy[bs->next_slot] & (1 << bs->next_symbol)) {
- printf("%s: warning, UL overflow (sl.symbol %d.%d)\n", __FUNCTION__,
- bs->next_slot, bs->next_symbol);
+ lock_ul_buffer(bs->buffers, bs->next_slot[a]);
+ if (bs->buffers->ul_busy[a][bs->next_slot[a]] & (1 << bs->next_symbol[a])) {
+ printf("%s: warning, antenna %d UL overflow (sl.symbol %d.%d)\n", __FUNCTION__,
+ a, bs->next_slot[a], bs->next_symbol[a]);
}
- memcpy(bs->buffers->ul[bs->next_slot] + bs->next_symbol * 1272*4,
+ memcpy(bs->buffers->ul[a][bs->next_slot[a]] + bs->next_symbol[a] * 1272*4,
ul->iq, 1272*4);
- bs->buffers->ul_busy[bs->next_slot] |= (1 << bs->next_symbol);
- signal_ul_buffer(bs->buffers, bs->next_slot);
- unlock_ul_buffer(bs->buffers, bs->next_slot);
+ bs->buffers->ul_busy[a][bs->next_slot[a]] |= (1 << bs->next_symbol[a]);
+ signal_ul_buffer(bs->buffers, bs->next_slot[a]);
+ unlock_ul_buffer(bs->buffers, bs->next_slot[a]);
- bs->next_symbol++;
- if (bs->next_symbol == 14) {
- bs->next_symbol = 0;
- bs->next_slot = (bs->next_slot + 1) % 20;
- if (bs->next_slot == 0) {
- bs->expected_benetel_frame++;
- bs->expected_benetel_frame &= 255;
+ bs->next_symbol[a]++;
+ if (bs->next_symbol[a] == 14) {
+ bs->next_symbol[a] = 0;
+ bs->next_slot[a] = (bs->next_slot[a] + 1) % 20;
+ if (bs->next_slot[a] == 0) {
+ bs->expected_benetel_frame[a]++;
+ bs->expected_benetel_frame[a] &= 255;
}
}
}
diff --git a/targets/ARCH/ETHERNET/benetel/5g/low.h b/targets/ARCH/ETHERNET/benetel/5g/low.h
index 5e1daee9d1..659819296a 100644
--- a/targets/ARCH/ETHERNET/benetel/5g/low.h
+++ b/targets/ARCH/ETHERNET/benetel/5g/low.h
@@ -26,9 +26,10 @@
typedef struct {
shared_buffers *buffers;
- int next_slot;
- int next_symbol;
- int expected_benetel_frame;
+ /* [2] is for two antennas */
+ int next_slot[2];
+ int next_symbol[2];
+ int expected_benetel_frame[2];
char *dpdk_main_command_line;
} benetel_t;
diff --git a/targets/ARCH/ETHERNET/benetel/5g/low_dpdk.c b/targets/ARCH/ETHERNET/benetel/5g/low_dpdk.c
index 5e26f6782e..b26df07723 100644
--- a/targets/ARCH/ETHERNET/benetel/5g/low_dpdk.c
+++ b/targets/ARCH/ETHERNET/benetel/5g/low_dpdk.c
@@ -68,7 +68,8 @@ void *benetel_start_dpdk(char *ifname, shared_buffers *buffers, char *dpdk_main_
bs->buffers = buffers;
- bs->expected_benetel_frame = 255;
+ bs->expected_benetel_frame[0] = 255;
+ bs->expected_benetel_frame[1] = 255;
bs->dpdk_main_command_line = dpdk_main_command_line;
diff --git a/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.c b/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.c
index b9da10b380..a302400eb4 100644
--- a/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.c
+++ b/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.c
@@ -45,11 +45,16 @@ void init_buffers(shared_buffers *s)
* needs to have slots 1, 2 and 3, 4 and 5 ready. Let's pretend
* they are ready.
*/
- s->dl_busy[1] = 0x3fff;
- s->dl_busy[2] = 0x3fff;
- s->dl_busy[3] = 0x3fff;
- s->dl_busy[4] = 0x3fff;
- s->dl_busy[5] = 0x3fff;
+ s->dl_busy[0][1] = 0x3fff;
+ s->dl_busy[0][2] = 0x3fff;
+ s->dl_busy[0][3] = 0x3fff;
+ s->dl_busy[0][4] = 0x3fff;
+ s->dl_busy[0][5] = 0x3fff;
+ s->dl_busy[1][1] = 0x3fff;
+ s->dl_busy[1][2] = 0x3fff;
+ s->dl_busy[1][3] = 0x3fff;
+ s->dl_busy[1][4] = 0x3fff;
+ s->dl_busy[1][5] = 0x3fff;
}
void lock_dl_buffer(shared_buffers *s, int slot)
diff --git a/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.h b/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.h
index ca7dbd9c8f..9d51b8138d 100644
--- a/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.h
+++ b/targets/ARCH/ETHERNET/benetel/5g/shared_buffers.h
@@ -26,10 +26,11 @@
#include
typedef struct {
- unsigned char dl[20][14*1272*4];
- unsigned char ul[20][14*1272*4];
- uint16_t dl_busy[20];
- uint16_t ul_busy[20];
+ /* [2] is for two antennas */
+ unsigned char dl[2][20][14*1272*4];
+ unsigned char ul[2][20][14*1272*4];
+ uint16_t dl_busy[2][20];
+ uint16_t ul_busy[2][20];
pthread_mutex_t m_ul[20];
pthread_cond_t c_ul[20];
diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c
index b469211a35..96d9541db9 100644
--- a/targets/ARCH/rfsimulator/simulator.c
+++ b/targets/ARCH/rfsimulator/simulator.c
@@ -76,15 +76,16 @@ extern RAN_CONTEXT_t RC;
/* configuration parameters for the rfsimulator device */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
-#define RFSIMULATOR_PARAMS_DESC {\
- {"serveraddr", "\n", 0, strptr:&(rfsimulator->ip), defstrval:"127.0.0.1", TYPE_STRING, 0 },\
- {"serverport", "\n", 0, u16ptr:&(rfsimulator->port), defuintval:PORT, TYPE_UINT16, 0 },\
- {RFSIMU_OPTIONS_PARAMNAME, RFSIM_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST,0 },\
- {"IQfile", "\n", 0, strptr:&(saveF), defstrval:"/tmp/rfsimulator.iqs",TYPE_STRING, 0 },\
- {"modelname", "\n", 0, strptr:&(modelname), defstrval:"AWGN", TYPE_STRING, 0 },\
- {"ploss", "\n", 0, dblptr:&(rfsimulator->chan_pathloss), defdblval:0, TYPE_DOUBLE, 0 },\
- {"forgetfact", "\n", 0, dblptr:&(rfsimulator->chan_forgetfact), defdblval:0, TYPE_DOUBLE, 0 },\
- {"offset", "\n", 0, iptr:&(rfsimulator->chan_offset), defintval:0, TYPE_INT, 0 }\
+#define simOpt PARAMFLAG_NOFREE|PARAMFLAG_CMDLINE_NOPREFIXENABLED
+#define RFSIMULATOR_PARAMS_DESC { \
+ {"serveraddr", "\n", simOpt , strptr:&(rfsimulator->ip), defstrval:"127.0.0.1", TYPE_STRING, 0 },\
+ {"serverport", "\n", simOpt, u16ptr:&(rfsimulator->port), defuintval:PORT, TYPE_UINT16, 0 },\
+ {RFSIMU_OPTIONS_PARAMNAME, RFSIM_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST,0 },\
+ {"IQfile", "\n",simOpt, strptr:&(saveF), defstrval:"/tmp/rfsimulator.iqs",TYPE_STRING, 0 },\
+ {"modelname", "\n", simOpt, strptr:&(modelname), defstrval:"AWGN", TYPE_STRING, 0 },\
+ {"ploss", "\n", simOpt, dblptr:&(rfsimulator->chan_pathloss), defdblval:0, TYPE_DOUBLE, 0 },\
+ {"forgetfact", "\n", simOpt, dblptr:&(rfsimulator->chan_forgetfact), defdblval:0, TYPE_DOUBLE, 0 },\
+ {"offset", "\n", simOpt, iptr:&(rfsimulator->chan_offset), defintval:0, TYPE_INT, 0 }\
};
@@ -137,7 +138,7 @@ typedef struct {
} rfsimulator_state_t;
-void allocCirBuf(rfsimulator_state_t *bridge, int sock) {
+static void allocCirBuf(rfsimulator_state_t *bridge, int sock) {
buffer_t *ptr=&bridge->buf[sock];
AssertFatal ( (ptr->circularBuf=(sample_t *) malloc(sampleToByte(CirSize,1))) != NULL, "");
ptr->circularBufEnd=((char *)ptr->circularBuf)+sampleToByte(CirSize,1);
@@ -195,7 +196,7 @@ void allocCirBuf(rfsimulator_state_t *bridge, int sock) {
}
}
-void removeCirBuf(rfsimulator_state_t *bridge, int sock) {
+static void removeCirBuf(rfsimulator_state_t *bridge, int sock) {
AssertFatal( epoll_ctl(bridge->epollfd, EPOLL_CTL_DEL, sock, NULL) != -1, "");
close(sock);
free(bridge->buf[sock].circularBuf);
@@ -206,12 +207,12 @@ void removeCirBuf(rfsimulator_state_t *bridge, int sock) {
bridge->buf[sock].conn_sock=-1;
}
-void socketError(rfsimulator_state_t *bridge, int sock) {
+static void socketError(rfsimulator_state_t *bridge, int sock) {
if (bridge->buf[sock].conn_sock!=-1) {
LOG_W(HW,"Lost socket \n");
removeCirBuf(bridge, sock);
- if (bridge->typeStamp==UE_MAGICDL_FDD)
+ if (bridge->typeStamp==UE_MAGICDL)
exit(1);
}
}
@@ -229,7 +230,7 @@ enum blocking_t {
blocking
};
-void setblocking(int sock, enum blocking_t active) {
+static void setblocking(int sock, enum blocking_t active) {
int opts;
AssertFatal( (opts = fcntl(sock, F_GETFL)) >= 0,"");
@@ -243,7 +244,7 @@ void setblocking(int sock, enum blocking_t active) {
static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps);
-void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) {
+static void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) {
if (t->saveIQfile != -1) {
if (write(t->saveIQfile, _buf, count) != count )
LOG_E(HW,"write in save iq file failed (%s)\n",strerror(errno));
@@ -277,7 +278,7 @@ void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) {
}
}
-void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) {
+static void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) {
char *saveF=NULL;
char *modelname=NULL;
paramdef_t rfsimu_params[] = RFSIMULATOR_PARAMS_DESC;
@@ -312,9 +313,9 @@ void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) {
if ( strncasecmp(rfsimulator->ip,"enb",3) == 0 ||
strncasecmp(rfsimulator->ip,"server",3) == 0 )
- rfsimulator->typeStamp = ENB_MAGICDL_FDD;
+ rfsimulator->typeStamp = ENB_MAGICDL;
else
- rfsimulator->typeStamp = UE_MAGICDL_FDD;
+ rfsimulator->typeStamp = UE_MAGICDL;
}
static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg) {
@@ -358,9 +359,9 @@ static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt,
return CMDSTATUS_FOUND;
}
-int server_start(openair0_device *device) {
+static int startServer(openair0_device *device) {
rfsimulator_state_t *t = (rfsimulator_state_t *) device->priv;
- t->typeStamp=ENB_MAGICDL_FDD;
+ t->typeStamp=ENB_MAGICDL;
AssertFatal((t->listen_sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, "");
int enable = 1;
AssertFatal(setsockopt(t->listen_sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) == 0, "");
@@ -381,9 +382,9 @@ sin_addr:
return 0;
}
-int start_ue(openair0_device *device) {
+static int startClient(openair0_device *device) {
rfsimulator_state_t *t = device->priv;
- t->typeStamp=UE_MAGICDL_FDD;
+ t->typeStamp=UE_MAGICDL;
int sock;
AssertFatal((sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, "");
struct sockaddr_in addr = {
@@ -458,7 +459,7 @@ static int rfsimulator_write_internal(rfsimulator_state_t *t, openair0_timestamp
return nsamps;
}
-int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags) {
+static int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags) {
return rfsimulator_write_internal(device->priv, timestamp, samplesVoid, nsamps, nbAnt, flags, false);
}
@@ -483,7 +484,7 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi
AssertFatal( (conn_sock = accept(t->listen_sock,NULL,NULL)) != -1, "");
setblocking(conn_sock, notBlocking);
allocCirBuf(t, conn_sock);
- LOG_I(HW,"A ue connected, sending the current time\n");
+ LOG_I(HW,"A client connected, sending the current time\n");
struct complex16 v= {0};
void *samplesVoid[t->tx_num_channels];
@@ -534,8 +535,8 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi
// check the header and start block transfer
if ( b->headerMode==true && b->remainToTransfer==0) {
- AssertFatal( (t->typeStamp == UE_MAGICDL_FDD && b->th.magic==ENB_MAGICDL_FDD) ||
- (t->typeStamp == ENB_MAGICDL_FDD && b->th.magic==UE_MAGICDL_FDD), "Socket Error in protocol");
+ AssertFatal( (t->typeStamp == UE_MAGICDL && b->th.magic==ENB_MAGICDL) ||
+ (t->typeStamp == ENB_MAGICDL && b->th.magic==UE_MAGICDL), "Socket Error in protocol");
b->headerMode=false;
if ( t->nextTimestamp == 0 ) { // First block in UE, resync with the eNB current TS
@@ -606,7 +607,7 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi
return nfds>0;
}
-int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, void **samplesVoid, int nsamps, int nbAnt) {
+static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, void **samplesVoid, int nsamps, int nbAnt) {
if (nbAnt != 1) {
LOG_W(HW, "rfsimulator: only 1 antenna tested\n");
}
@@ -748,31 +749,24 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
signal_energy(samplesVoid[0], nsamps));
return nsamps;
}
-int rfsimulator_request(openair0_device *device, void *msg, ssize_t msg_len) {
- abort();
+
+static int rfsimulator_get_stats(openair0_device *device) {
return 0;
}
-int rfsimulator_reply(openair0_device *device, void *msg, ssize_t msg_len) {
- abort();
+static int rfsimulator_reset_stats(openair0_device *device) {
return 0;
}
-int rfsimulator_get_stats(openair0_device *device) {
+static void rfsimulator_end(openair0_device *device) {}
+static int rfsimulator_stop(openair0_device *device) {
return 0;
}
-int rfsimulator_reset_stats(openair0_device *device) {
+static int rfsimulator_set_freq(openair0_device *device, openair0_config_t *openair0_cfg,int exmimo_dump_config) {
return 0;
}
-void rfsimulator_end(openair0_device *device) {}
-int rfsimulator_stop(openair0_device *device) {
+static int rfsimulator_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) {
return 0;
}
-int rfsimulator_set_freq(openair0_device *device, openair0_config_t *openair0_cfg,int exmimo_dump_config) {
- return 0;
-}
-int rfsimulator_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) {
- return 0;
-}
-int rfsimulator_write_init(openair0_device *device) {
+static int rfsimulator_write_init(openair0_device *device) {
return 0;
}
__attribute__((__visibility__("default")))
@@ -782,10 +776,10 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
rfsimulator_state_t *rfsimulator = (rfsimulator_state_t *)calloc(sizeof(rfsimulator_state_t),1);
rfsimulator_readconfig(rfsimulator);
pthread_mutex_init(&Sockmutex, NULL);
- LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == ENB_MAGICDL_FDD ? "(eg)NB" : "UE");
- device->trx_start_func = rfsimulator->typeStamp == ENB_MAGICDL_FDD ?
- server_start :
- start_ue;
+ LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == ENB_MAGICDL ? "server waiting opposite rfsimulators to connect" : "client: will connect to a rfsimulator server side");
+ device->trx_start_func = rfsimulator->typeStamp == ENB_MAGICDL ?
+ startServer :
+ startClient;
device->trx_get_stats_func = rfsimulator_get_stats;
device->trx_reset_stats_func = rfsimulator_reset_stats;
device->trx_end_func = rfsimulator_end;
@@ -795,7 +789,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
device->trx_write_func = rfsimulator_write;
device->trx_read_func = rfsimulator_read;
/* let's pretend to be a b2x0 */
- device->type = USRP_B200_DEV;
+ device->type = RFSIMULATOR;
device->openair0_cfg=&openair0_cfg[0];
device->priv = rfsimulator;
device->trx_write_init = rfsimulator_write_init;
diff --git a/targets/ARCH/rfsimulator/stored_node.c b/targets/ARCH/rfsimulator/stored_node.c
index daf0133af2..dcea69b9dd 100644
--- a/targets/ARCH/rfsimulator/stored_node.c
+++ b/targets/ARCH/rfsimulator/stored_node.c
@@ -200,7 +200,10 @@ int main(int argc, char *argv[]) {
int bufSize=100000;
void *buff=malloc(bufSize);
uint64_t timestamp=0;
- const int blockSize=1000;
+ const int blockSize=1920;
+
+ // If fileSize is not multiple of blockSize*4 then discard remaining samples
+ fileSize = (fileSize/(blockSize<<2))*(blockSize<<2);
while (1) {
//Rewind the file to loop on the samples
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf
index 49b4e4441e..aab3876d96 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf
@@ -230,12 +230,12 @@ RUs = (
local_if_name = "dpdk";
sdr_addrs = "softmodem -m 2048 -l 35 -n 2 -b 0000:81:00.3 --proc-type auto --file-prefix ggg -- -p 0x1";
#sdr_addrs = "softmodem -l 8 -n 2 -- -p 0x2";
- remote_address = "127.0.0.2";
- local_address = "127.0.0.1";
- local_portc = 50000;
- remote_portc = 50000;
- local_portd = 50001;
- remote_portd = 50001;
+ #remote_address = "127.0.0.2";
+ #local_address = "127.0.0.1";
+ #local_portc = 50000;
+ #remote_portc = 50000;
+ #local_portd = 50001;
+ #remote_portd = 50001;
local_rf = "no"
tr_preference = "raw_if4p5"
nb_tx = 1
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf
index 037de199df..ad396e41f2 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf
@@ -23,6 +23,9 @@ gNBs =
ssb_SubcarrierOffset = 31; //0;
pdsch_AntennaPorts = 1;
+ pusch_AntennaPorts = 1;
+ #pusch_TargetSNRx10 = 200;
+ #pucch_TargetSNRx10 = 200;
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;
@@ -102,8 +105,9 @@ gNBs =
prach_msg1_FDM = 0;
prach_msg1_FrequencyStart = 74;
zeroCorrelationZoneConfig = 13;
- #preambleReceivedTargetPower = -118;
- preambleReceivedTargetPower = -104;
+ preambleReceivedTargetPower = -118;
+ #preambleReceivedTargetPower = -104;
+ #preambleReceivedTargetPower = -108;
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
preambleTransMax = 6;
#powerRampingStep
@@ -149,14 +153,16 @@ gNBs =
initialULBWPstartSymbolAndLength_2 = 52;
msg3_DeltaPreamble = 1;
- p0_NominalWithGrant =-90;
+ #p0_NominalWithGrant =-90;
+ p0_NominalWithGrant =-118;
# pucch-ConfigCommon setup :
# pucchGroupHopping
# 0 = neither, 1= group hopping, 2=sequence hopping
pucchGroupHopping = 0;
hoppingId = 40;
- p0_nominal = -90;
+ #p0_nominal = -90;
+ p0_nominal = -118;
# ssb_PositionsInBurs_BitmapPR
# 1=short, 2=medium, 3=long
ssb_PositionsInBurst_PR = 2;
@@ -189,7 +195,7 @@ gNBs =
nrofUplinkSymbols = 4; //0; //4;
#ssPBCH_BlockPower = 10;
- ssPBCH_BlockPower = 10;
+ ssPBCH_BlockPower = -35;
}
);
@@ -229,9 +235,9 @@ gNBs =
{
GNB_INTERFACE_NAME_FOR_S1_MME = "eth0";
- GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.18.195/24";
+ GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.18.187/24";
GNB_INTERFACE_NAME_FOR_S1U = "eth0";
- GNB_IPV4_ADDRESS_FOR_S1U = "192.168.18.195/24";
+ GNB_IPV4_ADDRESS_FOR_S1U = "192.168.18.187/24";
GNB_PORT_FOR_S1U = 2152; # Spec 2152
GNB_IPV4_ADDRESS_FOR_X2C = "127.0.0.2/24";
GNB_PORT_FOR_X2C = 36422; # Spec 36422
@@ -251,6 +257,7 @@ L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
+ pusch_proc_threads = 8;
}
);
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf
index f2e468c71b..39ee4c6907 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf
@@ -23,6 +23,7 @@ gNBs =
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
+ pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf
index 2737357851..182398cd88 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf
@@ -23,6 +23,7 @@ gNBs =
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
+ pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf
index f810dd546c..f252bd1967 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf
@@ -23,6 +23,7 @@ gNBs =
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
+ pusch_AntennaPorts = 1;
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf
index 9e13d493a8..632ae126cd 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf
@@ -23,6 +23,7 @@ gNBs =
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
+ pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
@@ -225,19 +226,20 @@ MACRLCs = (
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
- }
+ }
);
L1s = (
- {
+ {
num_cc = 1;
tr_n_preference = "local_mac";
- }
+ pusch_proc_threads = 8;
+ }
);
RUs = (
{
- local_rf = "yes"
+ local_rf = "yes"
nb_tx = 1;
nb_rx = 1;
att_tx = 0;
@@ -246,8 +248,14 @@ RUs = (
max_pdschReferenceSignalPower = -27;
max_rxgain = 75;
eNB_instances = [0];
- #beamforming 1x4 matrix:
- bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
+ ## beamforming 1x2 matrix: 1 layer x 2 antennas
+ bf_weights = [0x00007fff, 0x0000];
+ ## beamforming 1x4 matrix: 1 layer x 4 antennas
+ #bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
+ ## beamforming 2x2 matrix:
+ #bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
+ ## beamforming 4x4 matrix:
+ #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2";
clock_src = "external";
# if_freq = 3700000000L;
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf
index 831f9c7978..46868d0185 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf
@@ -23,6 +23,7 @@ gNBs =
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
+ pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
@@ -225,19 +226,20 @@ MACRLCs = (
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
- }
+ }
);
L1s = (
- {
+ {
num_cc = 1;
tr_n_preference = "local_mac";
- }
+ pusch_proc_threads = 8;
+ }
);
RUs = (
{
- local_rf = "yes"
+ local_rf = "yes"
nb_tx = 1;
nb_rx = 1;
att_tx = 0;
@@ -246,8 +248,14 @@ RUs = (
max_pdschReferenceSignalPower = -27;
max_rxgain = 114;
eNB_instances = [0];
- #beamforming 1x4 matrix:
- bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
+ ## beamforming 1x2 matrix: 1 layer x 2 antennas
+ bf_weights = [0x00007fff, 0x0000];
+ ## beamforming 1x4 matrix: 1 layer x 4 antennas
+ #bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
+ ## beamforming 2x2 matrix:
+ #bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
+ ## beamforming 4x4 matrix:
+ #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
sdr_addrs = "type=x300";
clock_src = "external";
# if_freq = 3700000000L;
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf
index 1cd16d0831..3333912418 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf
@@ -23,6 +23,7 @@ gNBs =
ssb_SubcarrierOffset = 31;
pdsch_AntennaPorts = 1;
+ pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf
index dfae41f0a6..96d7dbb9e9 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf
@@ -23,6 +23,7 @@ gNBs =
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
+ pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf
index dcdfa003a2..9bb9132917 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf
@@ -23,6 +23,7 @@ gNBs =
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
+ pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf
index 862f0e6303..3b384dd072 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf
@@ -23,6 +23,7 @@ gNBs =
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
+ pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
@@ -228,7 +229,7 @@ L1s = (
RUs = (
{
- local_rf = "yes"
+ local_rf = "yes"
nb_tx = 1
nb_rx = 1
att_tx = 0
@@ -237,7 +238,15 @@ RUs = (
max_pdschReferenceSignalPower = -27;
max_rxgain = 114;
eNB_instances = [0];
- sdr_addrs = "type=b200";
+ ## beamforming 1x2 matrix: 1 layer x 2 antennas
+ #bf_weights = [0x00007fff, 0x00007fff];
+ ## beamforming 1x4 matrix: 1 layer x 4 antennas
+ #bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
+ ## beamforming 2x2 matrix:
+ #bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
+ ## beamforming 4x4 matrix:
+ #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
+ sdr_addrs = "type=b200";
#clock_src = "external";
}
);
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf
index 58f6bcf709..9fdb5071d6 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf
@@ -227,20 +227,20 @@ MACRLCs = (
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
- }
+ }
);
L1s = (
- {
+ {
num_cc = 1;
tr_n_preference = "local_mac";
pusch_proc_threads = 8;
- }
+ }
);
RUs = (
{
- local_rf = "yes"
+ local_rf = "yes"
nb_tx = 1
nb_rx = 1
att_tx = 0
@@ -249,9 +249,9 @@ RUs = (
max_pdschReferenceSignalPower = -27;
max_rxgain = 50;
eNB_instances = [0];
- ##beamforming 1x2 matrix: 1 layer x 2 antennas
+ ## beamforming 1x2 matrix: 1 layer x 2 antennas
#bf_weights = [0x00007fff, 0x00007fff];
- ##beamforming 1x4 matrix: 1 layer x 4 antennas
+ ## beamforming 1x4 matrix: 1 layer x 4 antennas
#bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
## beamforming 2x2 matrix:
#bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf
index d38fff4241..0454bc1a71 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf
@@ -23,7 +23,8 @@ gNBs =
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
-
+ pusch_AntennaPorts = 1;
+
servingCellConfigCommon = (
{
#spCellConfigCommon
@@ -135,18 +136,17 @@ gNBs =
initialULBWPmappingType_0 = 1
# this is SS=0 L=11
initialULBWPstartSymbolAndLength_0 = 55;
-
- initialULBWPk2_1 = 6;
+
+ initialULBWPk2_1 = 6;
initialULBWPmappingType_1 = 1;
# this is SS=0 L=12
initialULBWPstartSymbolAndLength_1 = 69;
- initialULBWPk2_2 = 7;
+ initialULBWPk2_2 = 7;
initialULBWPmappingType_2 = 1;
# this is SS=10 L=4
initialULBWPstartSymbolAndLength_2 = 52;
-
msg3_DeltaPreamble = 1;
p0_NominalWithGrant =-90;
@@ -227,14 +227,15 @@ MACRLCs = (
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
- }
+ }
);
L1s = (
- {
+ {
num_cc = 1;
tr_n_preference = "local_mac";
- }
+ pusch_proc_threads = 8;
+ }
);
RUs = (
@@ -248,8 +249,14 @@ RUs = (
max_pdschReferenceSignalPower = -27;
max_rxgain = 114;
eNB_instances = [0];
- #beamforming 1x4 matrix:
- bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000];
+ ##beamforming 1x2 matrix: 1 layer x 2 antennas
+ bf_weights = [0x00007fff, 0x0000];
+ ##beamforming 1x4 matrix: 1 layer x 4 antennas
+ #bf_weights = [0x00007fff, 0x0000,0x0000, 0x0000];
+ ## beamforming 2x2 matrix:
+ # bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff];
+ ## beamforming 4x4 matrix:
+ #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff];
sdr_addrs = "type=x300";
clock_src = "external";
}
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf
index 0659641607..d6110e19d5 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf
@@ -23,6 +23,7 @@ gNBs =
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
+ pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
@@ -33,7 +34,7 @@ gNBs =
# downlinkConfigCommon
#frequencyInfoDL
# this is 3600 MHz + 84 PRBs@30kHz SCS (same as initial BWP)
- absoluteFrequencySSB = 642364;
+ absoluteFrequencySSB = 642016;#642364;
dl_frequencyBand = 78;
# this is 3600 MHz
dl_absoluteFrequencyPointA = 640000;
@@ -130,16 +131,21 @@ gNBs =
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0,
# pusch-ConfigCommon (up to 16 elements)
- initialULBWPk2_0 = 2;
+ initialULBWPk2_0 = 6; #2;
initialULBWPmappingType_0 = 1
# this is SS=0 L=11
initialULBWPstartSymbolAndLength_0 = 55;
- initialULBWPk2_1 = 2;
+ initialULBWPk2_1 = 6; #2;
initialULBWPmappingType_1 = 1;
# this is SS=0 L=12
initialULBWPstartSymbolAndLength_1 = 69;
+ initialULBWPk2_2 = 7;
+ initialULBWPmappingType_2 = 1;
+ # this is SS=10 L=4
+ initialULBWPstartSymbolAndLength_2 = 52;
+
msg3_DeltaPreamble = 1;
p0_NominalWithGrant =-90;
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf
index c907dcfe8d..07d04e65f9 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf
@@ -23,6 +23,7 @@ gNBs =
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
+ pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf
index 0a6268f8a8..a42da67df3 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf
@@ -23,6 +23,7 @@ gNBs =
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
+ pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
@@ -130,16 +131,21 @@ gNBs =
# 0=unrestricted, 1=restricted type A, 2=restricted type B
restrictedSetConfig = 0,
# pusch-ConfigCommon (up to 16 elements)
- initialULBWPk2_0 = 2;
+ initialULBWPk2_0 = 6;#2;
initialULBWPmappingType_0 = 1
# this is SS=0 L=11
initialULBWPstartSymbolAndLength_0 = 55;
- initialULBWPk2_1 = 2;
+ initialULBWPk2_1 = 6;#2;
initialULBWPmappingType_1 = 1;
# this is SS=0 L=12
initialULBWPstartSymbolAndLength_1 = 69;
+ initialULBWPk2_2 = 7;
+ initialULBWPmappingType_2 = 1;
+ # this is SS=10 L=4
+ initialULBWPstartSymbolAndLength_2 = 52;
+
msg3_DeltaPreamble = 1;
p0_NominalWithGrant =-90;
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpx300.conf
new file mode 100644
index 0000000000..5cfd4dc768
--- /dev/null
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpx300.conf
@@ -0,0 +1,46 @@
+log_config = {
+ global_log_level ="debug";
+ global_log_verbosity ="medium";
+ hw_log_level ="info";
+ hw_log_verbosity ="medium";
+ phy_log_level ="info";
+ phy_log_verbosity ="medium";
+ mac_log_level ="debug";
+ mac_log_verbosity ="medium";
+ rlc_log_level ="info";
+ rlc_log_verbosity ="medium";
+ pdcp_log_level ="info";
+ pdcp_log_verbosity ="medium";
+ rrc_log_level ="debug";
+ rrc_log_verbosity ="full";
+};
+
+
+
+L1s = (
+ {
+ num_cc = 1;
+ tr_n_preference = "nfapi";
+ local_n_if_name = "lo";
+ remote_n_address = "127.0.0.2"; // vnf addr
+ local_n_address = "127.0.0.1"; // pnf addr
+ local_n_portc = 50000; // pnf p5 port [!]
+ remote_n_portc = 50001; // vnf p5 port
+ local_n_portd = 50010; // pnf p7 port
+ remote_n_portd = 50011; // vnf p7 port
+ }
+);
+
+RUs = (
+ {
+ local_rf = "yes"
+ nb_tx = 1
+ nb_rx = 1
+ att_tx = 0
+ att_rx = 0;
+ bands = [7];
+ max_pdschReferenceSignalPower = -27;
+ max_rxgain = 114;
+ sdr_addrs = "type=x300"; // USRP type
+ }
+);
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf
new file mode 100644
index 0000000000..e541607559
--- /dev/null
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf
@@ -0,0 +1,291 @@
+Active_gNBs = ( "gNB-Eurecom-5GNRBox");
+# Asn1_verbosity, choice in: none, info, annoying
+Asn1_verbosity = "none";
+
+gNBs =
+(
+ {
+ ////////// Identification parameters:
+ gNB_ID = 0xe00;
+
+ cell_type = "CELL_MACRO_GNB";
+
+ gNB_name = "gNB-Eurecom-5GNRBox";
+
+ // Tracking area code, 0x0000 and 0xfffe are reserved values
+ tracking_area_code = 1;
+
+ plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;});
+
+ tr_s_preference = "local_mac"
+
+ ////////// Physical parameters:
+
+ ssb_SubcarrierOffset = 0;
+ pdsch_AntennaPorts = 1;
+ pusch_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.12.26";
+ ipv6 = "192:168:30::17";
+ active = "yes";
+ preference = "ipv4";
+ }
+ );
+
+ NETWORK_INTERFACES :
+ {
+
+ GNB_INTERFACE_NAME_FOR_S1_MME = "eth0";
+ GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24";
+ GNB_INTERFACE_NAME_FOR_S1U = "eth0";
+ GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24";
+ GNB_PORT_FOR_S1U = 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 = 50001; // vnf p5 port
+ remote_s_portc = 50000; // pnf p5 port [!]
+ local_s_portd = 50011; // vnf p7 port [!]
+ remote_s_portd = 50010; // pnf p7 port [!]
+ tr_s_preference = "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/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf
index 8aab7abfa0..d769fe5d09 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf
@@ -23,6 +23,7 @@ gNBs =
ssb_SubcarrierOffset = 31; //0;
pdsch_AntennaPorts = 1;
+ pusch_AntennaPorts = 1;
pusch_TargetSNRx10 = 200;
pucch_TargetSNRx10 = 200;
@@ -278,6 +279,18 @@ THREAD_STRUCT = (
}
);
+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", "nea2" );
+
+ # preferred integrity algorithms
+ # the first one of the list that an UE supports in chosen
+ # valid values: nia0, nia1, nia2, nia3
+ integrity_algorithms = ( "nia0" );
+};
+
log_config :
{
global_log_level ="info";
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf
index 6a3f008ec1..f2423c2ae9 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf
@@ -23,6 +23,7 @@ gNBs =
ssb_SubcarrierOffset = 31; //0;
pdsch_AntennaPorts = 1;
+ pusch_AntennaPorts = 1;
servingCellConfigCommon = (
{
diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf
index 4373f38e7b..d28427dbf3 100644
--- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf
+++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf
@@ -75,17 +75,12 @@ gNBs =
initialDLBWPk0_2 = 0;
initialDLBWPmappingType_2 = 0;
#this is SS=1,L=12
- initialDLBWPstartSymbolAndLength_2 = 95;
+ initialDLBWPstartSymbolAndLength_2 = 54;
initialDLBWPk0_3 = 0;
initialDLBWPmappingType_3 = 0;
- #this is SS=2,L=7
- initialDLBWPstartSymbolAndLength_3 = 86;
-
- initialDLBWPk0_4 = 0;
- initialDLBWPmappingType_4 = 0;
- #this is SS=2,L=5
- initialDLBWPstartSymbolAndLength_4 = 58;
+ #this is SS=1,L=5
+ initialDLBWPstartSymbolAndLength_3 = 57;
#uplinkConfigCommon
#frequencyInfoUL
diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c
index 56c2cb23dd..368fd78f9e 100644
--- a/targets/RT/USER/lte-ru.c
+++ b/targets/RT/USER/lte-ru.c
@@ -2986,6 +2986,7 @@ void RCconfig_RU(void) {
RC.ru[j]->if_south = LOCAL_RF;
RC.ru[j]->function = NGFI_RRU_IF4p5;
RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE;
+ RC.ru[j]->has_ctrl_prt =1;
LOG_I(PHY,"Setting function for RU %d to NGFI_RRU_IF4p5 (raw)\n",j);
}
@@ -3039,6 +3040,7 @@ else {
RC.ru[j]->if_south = REMOTE_IF4p5;
RC.ru[j]->function = NGFI_RAU_IF4p5;
RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE;
+ RC.ru[j]->has_ctrl_prt = 1;
if (strcmp(*(RUParamList.paramarray[j][RU_IS_SLAVE_IDX].strptr), "yes") == 0) RC.ru[j]->is_slave=1;
else RC.ru[j]->is_slave=0;
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index a602e762f1..2e6f148e00 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -583,6 +583,7 @@ int main ( int argc, char **argv )
if (RC.nb_inst > 0) {
/* Start the agent. If it is turned off in the configuration, it won't start */
for (i = 0; i < RC.nb_inst; i++) {
+ if(NFAPI_MODE != NFAPI_MODE_PNF)
flexran_agent_start(i);
}