diff --git a/NOTICE.md b/NOTICE.md index 96b5d4c552..39dd33795d 100644 --- a/NOTICE.md +++ b/NOTICE.md @@ -21,3 +21,7 @@ The Regents of the University of California: BSD 3-Clause Licence. Niels Provos : BSD 2-Clause Licence. +## Credits for source code openair3/GTPV1-U/nw-gtpv1u: ## + +Amit Chawre : BSD 2-Clause Licence. + diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index c3b997a4e8..7e9e3800db 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -30,7 +30,6 @@ def sendSocialMediaMessage(pipeChannel, pipeColor, pipeMessage) { } } -def doRedHatBuild = false def doFlexranCtrlTest = false // Location of the executor node @@ -85,21 +84,6 @@ pipeline { echo "Platform is ${env.TESTPLATFORM_OWNER}" } - if (params.RedHatRemoteServer == null) { - allParametersPresent = false - } - if (params.RedHatRemoteCredentials == null) { - allParametersPresent = false - } - if (params.RedHatWorkingPath == null) { - allParametersPresent = false - } - if (allParametersPresent) { - echo "Performing Red Hat Build" - doRedHatBuild = true - } else { - doRedHatBuild = false - } if (params.FlexRanRtcGitLabRepository_Credentials != null) { doFlexranCtrlTest = true } @@ -279,7 +263,7 @@ pipeline { 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} --keep-vm-alive" + sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant enb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID}" } } } @@ -311,28 +295,6 @@ pipeline { } } } - stage ("Build eNB-USRP on Red Hat") { - when { - expression {doRedHatBuild} - } - steps { - gitlabCommitStatus(name: "Build eNB-USRP-RHE") { - script { - try { - withCredentials([ - [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.RedHatRemoteCredentials}", usernameVariable: 'RH_Username', passwordVariable: 'RH_Password'] - ]) { - timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/buildOnRH.sh --workspace $WORKSPACE --job-name ${JOB_NAME} --build-id ${BUILD_ID} --remote-host ${params.RedHatRemoteServer} --remote-path ${params.RedHatWorkingPath} --remote-user-name ${RH_Username} --remote-password ${RH_Password}" - } - } - } catch (Exception e) { - echo "Red Hat build failed but we could keep running pipeline if all ubuntu-based build passed" - } - } - } - } - } } post { failure { diff --git a/ci-scripts/checkCodingFormattingRules.sh b/ci-scripts/checkCodingFormattingRules.sh index fb159d4da0..d47b90a9dd 100755 --- a/ci-scripts/checkCodingFormattingRules.sh +++ b/ci-scripts/checkCodingFormattingRules.sh @@ -77,7 +77,7 @@ then IS_NFAPI=`echo $FILE | egrep -c "nfapi/open-nFAPI|nfapi/oai_integration/vendor_ext"` IS_OAI_LICENCE_PRESENT=`egrep -c "OAI Public License" $FILE` IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence" $FILE` - IS_EXCEPTION=`echo $FILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|common/utils/itti_analyzer/common/queue.h|openair3/UTILS/tree.h|openair3/UTILS/queue.h"` + IS_EXCEPTION=`echo $FILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|common/utils/itti_analyzer/common/queue.h|openair3/UTILS/tree.h|openair3/UTILS/queue.h|openair3/GTPV1-U/nw-gtpv1u|openair2/UTIL/OPT/ws_"` if [ $IS_OAI_LICENCE_PRESENT -eq 0 ] && [ $IS_BSD_LICENCE_PRESENT -eq 0 ] then if [ $IS_NFAPI -eq 0 ] && [ $IS_EXCEPTION -eq 0 ] @@ -194,12 +194,12 @@ do IS_NFAPI=`echo $FULLFILE | egrep -c "nfapi/open-nFAPI|nfapi/oai_integration/vendor_ext"` IS_OAI_LICENCE_PRESENT=`egrep -c "OAI Public License" $FULLFILE` IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence" $FULLFILE` - IS_EXCEPTION=`echo $FILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|common/utils/itti_analyzer/common/queue.h|openair3/UTILS/tree.h|openair3/UTILS/queue.h"` + IS_EXCEPTION=`echo $FULLFILE | egrep -c "common/utils/collection/tree.h|common/utils/collection/queue.h|common/utils/itti_analyzer/common/queue.h|openair3/UTILS/tree.h|openair3/UTILS/queue.h|openair3/GTPV1-U/nw-gtpv1u|openair2/UTIL/OPT/ws_"` if [ $IS_OAI_LICENCE_PRESENT -eq 0 ] && [ $IS_BSD_LICENCE_PRESENT -eq 0 ] then if [ $IS_NFAPI -eq 0 ] && [ $IS_EXCEPTION -eq 0 ] then - echo $FILE >> ./files-w-suspect-banner.txt + echo $FULLFILE >> ./files-w-suspect-banner.txt fi fi fi diff --git a/ci-scripts/conf_files/enb.band13.tm1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band13.tm1.25PRB.usrpb210.conf index 2a7783da08..49926c3e60 100644 --- a/ci-scripts/conf_files/enb.band13.tm1.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band13.tm1.25PRB.usrpb210.conf @@ -184,6 +184,8 @@ eNBs = enable_x2 = "yes"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/ci-scripts/conf_files/enb.band13.tm1.50PRB.emtc.conf b/ci-scripts/conf_files/enb.band13.tm1.50PRB.emtc.conf index ab89d13193..673c506dfa 100644 --- a/ci-scripts/conf_files/enb.band13.tm1.50PRB.emtc.conf +++ b/ci-scripts/conf_files/enb.band13.tm1.50PRB.emtc.conf @@ -367,6 +367,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/ci-scripts/conf_files/enb.band17.tm1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band17.tm1.25PRB.usrpb210.conf index d834b23e30..cf508a1e95 100644 --- a/ci-scripts/conf_files/enb.band17.tm1.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band17.tm1.25PRB.usrpb210.conf @@ -188,6 +188,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf index a9ccb9f783..d26ab5d1b4 100644 --- a/ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf @@ -189,6 +189,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ ///M2 target_mce_m2_ip_address = ( { ipv4 = "127.0.0.7"; diff --git a/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf index f6a22c8375..55127e1c53 100644 --- a/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf @@ -147,6 +147,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf index 15a7fa6fa8..88e4c88685 100644 --- a/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf @@ -147,6 +147,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf index 7d2ee42185..5794310fad 100644 --- a/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf @@ -147,6 +147,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/ci-scripts/conf_files/enb.band40.tm2.25PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm2.25PRB.FairScheduler.usrpb210.conf index 475ffe9218..5348c25c0e 100644 --- a/ci-scripts/conf_files/enb.band40.tm2.25PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm2.25PRB.FairScheduler.usrpb210.conf @@ -145,6 +145,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf index 517c916c85..7ea8839b8a 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf @@ -184,6 +184,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/ci-scripts/conf_files/enb.band7.tm1.25PRB.slave.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.25PRB.slave.usrpb210.conf index 46ab966017..36f0fdf7b1 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.25PRB.slave.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.25PRB.slave.usrpb210.conf @@ -187,6 +187,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ target_enb_x2_ip_address = ( { ipv4 = "CI_RCC_IP_ADDR"; ipv6 = "192:168:30::17"; diff --git a/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf index 6560fa41c5..b61201440b 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf @@ -187,6 +187,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf index bdcc201fd9..8a2cedfd05 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf @@ -192,6 +192,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf index 5b2c90a714..b2d5801efc 100755 --- a/ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf @@ -144,6 +144,8 @@ eNBs = discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + //SSB central frequency of NR secondary cell group (for ENDC NSA) + nr_scg_ssb_freq = 641272; } ); @@ -190,6 +192,8 @@ eNBs = enable_x2 = "yes"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/ci-scripts/conf_files/enb.band7.tm2.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm2.25PRB.usrpb210.conf index e045ec4ca9..08dd300329 100644 --- a/ci-scripts/conf_files/enb.band7.tm2.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm2.25PRB.usrpb210.conf @@ -187,6 +187,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/ci-scripts/conf_files/enb.slave.band13.tm1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.slave.band13.tm1.25PRB.usrpb210.conf index c76a664c15..371a6b4610 100644 --- a/ci-scripts/conf_files/enb.slave.band13.tm1.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.slave.band13.tm1.25PRB.usrpb210.conf @@ -183,6 +183,8 @@ eNBs = enable_x2 = "yes"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ target_enb_x2_ip_address = ( { ipv4 = "CI_RCC_IP_ADDR"; ipv6 = "192:168:30::17"; diff --git a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf index 92af74c300..7a4b5f54c1 100755 --- a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf @@ -210,6 +210,8 @@ gNBs = enable_x2 = "yes"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ target_enb_x2_ip_address = ( { ipv4 = "CI_FR1_CTL_ENB_IP_ADDR"; ipv6 = "192:168:30::17"; diff --git a/ci-scripts/conf_files/lte-fdd-basic-sim.conf b/ci-scripts/conf_files/lte-fdd-basic-sim.conf index 24a2b400e6..163047d7b9 100644 --- a/ci-scripts/conf_files/lte-fdd-basic-sim.conf +++ b/ci-scripts/conf_files/lte-fdd-basic-sim.conf @@ -184,6 +184,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/ci-scripts/conf_files/lte-fdd-fembms-basic-sim.conf b/ci-scripts/conf_files/lte-fdd-fembms-basic-sim.conf index e3adedbf4a..bb49d68bb4 100644 --- a/ci-scripts/conf_files/lte-fdd-fembms-basic-sim.conf +++ b/ci-scripts/conf_files/lte-fdd-fembms-basic-sim.conf @@ -185,6 +185,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ ////////// MCE parameters: target_mce_m2_ip_address = ( { ipv4 = "127.0.0.7"; diff --git a/ci-scripts/conf_files/lte-fdd-mbms-basic-sim.conf b/ci-scripts/conf_files/lte-fdd-mbms-basic-sim.conf index 3d5a859156..2e211d86b8 100644 --- a/ci-scripts/conf_files/lte-fdd-mbms-basic-sim.conf +++ b/ci-scripts/conf_files/lte-fdd-mbms-basic-sim.conf @@ -185,6 +185,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ ////////// MCE parameters: target_mce_m2_ip_address = ( { ipv4 = "127.0.0.7"; diff --git a/ci-scripts/conf_files/lte-tdd-basic-sim.conf b/ci-scripts/conf_files/lte-tdd-basic-sim.conf index 3afdb5df60..ad7e9d9f86 100644 --- a/ci-scripts/conf_files/lte-tdd-basic-sim.conf +++ b/ci-scripts/conf_files/lte-tdd-basic-sim.conf @@ -147,6 +147,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf index 8ad65b6278..0547590c29 100644 --- a/ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf @@ -150,6 +150,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf index 891301128f..3441690e6d 100644 --- a/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf @@ -150,6 +150,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf index 76df9ffde5..23709444bd 100644 --- a/ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf @@ -150,6 +150,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf index b842480e5d..33d00b8908 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf @@ -187,6 +187,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf index 98a546e8b5..a939c66cba 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf @@ -187,6 +187,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf index 2a8506a660..473496defa 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf @@ -187,6 +187,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/ci-scripts/conf_files/rcc.band7.tm1.mbms-s1ap.if4p5.50PRB.lo.conf b/ci-scripts/conf_files/rcc.band7.tm1.mbms-s1ap.if4p5.50PRB.lo.conf index b61e5e05b1..bf2db71152 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.mbms-s1ap.if4p5.50PRB.lo.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.mbms-s1ap.if4p5.50PRB.lo.conf @@ -155,6 +155,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ ////////// MCE parameters: diff --git a/ci-scripts/conf_files/rcc.band7.tm1.mbms.if4p5.50PRB.lo.conf b/ci-scripts/conf_files/rcc.band7.tm1.mbms.if4p5.50PRB.lo.conf index 5daaa8d13a..3bcd038d70 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.mbms.if4p5.50PRB.lo.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.mbms.if4p5.50PRB.lo.conf @@ -155,6 +155,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ ////////// MCE parameters: diff --git a/ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf b/ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf index 28bfd91560..ad113d0ffc 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf @@ -185,6 +185,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 549c8342e2..218ca18a4b 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -2772,7 +2772,7 @@ if (NOT ${NOS1}) endif() target_link_libraries (lte-uesoftmodem -Wl,--start-group - RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP F1AP_LIB + 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 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${ATLAS_LIBRARIES} @@ -3023,12 +3023,15 @@ add_executable(nr_dlsim ${OPENAIR_DIR}/common/utils/system.c ${OPENAIR_DIR}/common/utils/nr/nr_common.c ${OPENAIR_DIR}/executables/softmodem-common.c + ${OPENAIR2_DIR}/RRC/NAS/nas_config.c + ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c + ${NFAPI_USER_DIR}/nfapi.c ${UTIL_SRC} ${T_SOURCE} ${SHLIB_LOADER_SOURCES} ) target_link_libraries(nr_dlsim - -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR -Wl,--end-group + -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR HASHTABLE -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl ) target_compile_definitions(nr_dlsim PUBLIC -DPHYSICAL_SIMULATOR) @@ -3039,11 +3042,14 @@ add_executable(nr_prachsim ${OPENAIR_DIR}/common/utils/system.c ${OPENAIR_DIR}/common/utils/nr/nr_common.c ${OPENAIR1_DIR}/SCHED_NR/phy_procedures_nr_common.c + ${OPENAIR2_DIR}/RRC/NAS/nas_config.c + ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c + ${NFAPI_USER_DIR}/nfapi.c ${UTIL_SRC} ${T_SOURCE} ${SHLIB_LOADER_SOURCES}) target_link_libraries(nr_prachsim - -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB MAC_UE_NR SCHED_NR_UE_LIB RRC_LIB NR_RRC_LIB L2_NR CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl) + -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB MAC_UE_NR SCHED_NR_UE_LIB RRC_LIB NR_RRC_LIB L2_NR CONFIG_LIB HASHTABLE -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl) add_executable(nr_ulschsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulschsim.c @@ -3065,12 +3071,15 @@ add_executable(nr_ulsim ${OPENAIR_DIR}/common/utils/system.c ${OPENAIR_DIR}/common/utils/nr/nr_common.c ${OPENAIR_DIR}/executables/softmodem-common.c + ${OPENAIR2_DIR}/RRC/NAS/nas_config.c + ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c + ${NFAPI_USER_DIR}/nfapi.c ${UTIL_SRC} ${T_SOURCE} ${SHLIB_LOADER_SOURCES} ) target_link_libraries(nr_ulsim - -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR PHY_NR_COMMON PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR -Wl,--end-group + -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR PHY_NR_COMMON PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_NR HASHTABLE -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl ) target_compile_definitions(nr_ulsim PUBLIC -DPHYSICAL_SIMULATOR) diff --git a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf index 7f920e7e38..7158790b28 100644 --- a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf @@ -147,6 +147,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf index e5c57ffda5..70819d0e29 100644 --- a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf @@ -147,6 +147,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf index 17a3380567..7381fefc1a 100644 --- a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf @@ -147,6 +147,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf index 6721504f36..8eecfa2ac5 100644 --- a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf @@ -147,6 +147,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf index 4919ad3117..ce2b71bdd2 100644 --- a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf @@ -147,6 +147,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf index c26a0ad698..11e6e24418 100644 --- a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf +++ b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf @@ -147,6 +147,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf index ff0d3d7a00..11f6adbb4d 100644 --- a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf +++ b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf @@ -147,6 +147,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf index 8195b21157..3bf79f94bf 100644 --- a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf +++ b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf @@ -147,6 +147,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf index 8b172a7d73..67a2bae08c 100644 --- a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf +++ b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf @@ -147,6 +147,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf index 0d9a243b31..02f29c4c2e 100644 --- a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf +++ b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf @@ -149,6 +149,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf index ac8591841e..71a479a512 100644 --- a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf +++ b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf @@ -149,6 +149,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf index 93bfc2449f..09958d62e4 100644 --- a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf +++ b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf @@ -149,6 +149,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/common/utils/T/defs.h b/common/utils/T/defs.h index 69b379ce0b..a194e621db 100644 --- a/common/utils/T/defs.h +++ b/common/utils/T/defs.h @@ -1,5 +1,5 @@ -#ifndef _TRACER_DEFS_H_ -#define _TRACER_DEFS_H_ +#ifndef _COMMON_UTILS_T_DEFS_H_ +#define _COMMON_UTILS_T_DEFS_H_ /* types of plots */ #define PLOT_VS_TIME 0 @@ -27,4 +27,4 @@ void *forwarder(char *ip, int port); void forward(void *forwarder, char *buf, int size); void forward_start_client(void *forwarder, int socket); -#endif /* _TRACER_DEFS_H_ */ +#endif /* _COMMON_UTILS_T_DEFS_H_ */ diff --git a/common/utils/T/tracer/defs.h b/common/utils/T/tracer/defs.h index 443fabdde8..394351eab0 100644 --- a/common/utils/T/tracer/defs.h +++ b/common/utils/T/tracer/defs.h @@ -1,5 +1,5 @@ -#ifndef _TRACER_DEFS_H_ -#define _TRACER_DEFS_H_ +#ifndef _COMMON_UTILS_T_TRACER_DEFS_H_ +#define _COMMON_UTILS_T_TRACER_DEFS_H_ /* types of plots */ #define PLOT_VS_TIME 0 @@ -21,4 +21,4 @@ void t_gui_start(void); void t_gui_set_input_signal(int eNB, int frame, int subframe, int antenna, int size, void *buf); -#endif /* _TRACER_DEFS_H_ */ +#endif /* _COMMON_UTILS_T_TRACER_DEFS_H_ */ diff --git a/configuration/bladeRF/enb-band7-5mhz.conf b/configuration/bladeRF/enb-band7-5mhz.conf index df9b1cbc85..9156a74fb0 100644 --- a/configuration/bladeRF/enb-band7-5mhz.conf +++ b/configuration/bladeRF/enb-band7-5mhz.conf @@ -187,6 +187,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/doc/TESTING_GNB_W_COTS_UE.md b/doc/TESTING_GNB_W_COTS_UE.md index 198f6bb115..17f37ad2d7 100644 --- a/doc/TESTING_GNB_W_COTS_UE.md +++ b/doc/TESTING_GNB_W_COTS_UE.md @@ -12,6 +12,7 @@ STATUS 2020/09/10 : updated the status of interop (end to end UL/DL traffic) 7. [Log file monitoring](#log-file-monitoring) 6. [Required tools for debug](#required-tools-for-debug) 7. [Status of interoperability](#status-of-interoperability) +8. [CI integration](#ci-integration) ## Configuration Overview @@ -70,7 +71,7 @@ cd cmake_targets/ - **EPC** for reference: -https://github.com/OPENAIRINTERFACE/openair-epc-fed/blob/master-documentation/docs/DEPLOY_HOME.md +https://github.com/OPENAIRINTERFACE/openair-epc-fed/blob/master/docs/DEPLOY_HOME.md @@ -204,7 +205,7 @@ The test takes typically a few seconds, max 10-15 seconds. If it takes more than - **EPC** (on EPC host): for reference: -https://github.com/OPENAIRINTERFACE/openair-epc-fed/blob/master-documentation/docs/DEPLOY_HOME.md +https://github.com/OPENAIRINTERFACE/openair-epc-fed/blob/master/docs/DEPLOY_HOME.md @@ -384,3 +385,16 @@ The following parts have been validated with FR1 COTS UE: some packet losses might still occur even in ideal channel conditions +## CI integration +The automation scripts are available on ILIADE. +The end-to-end test is integrated in the CI flow in a semi-automated manner, comprising 3 steps: +- update a YAML file comprising the IT resources definition, branch and commit number the test has to run on +- run the python script that generates the test from the YAML file +``` +python3 obj_build_from_yaml.py py_params_template.yaml fr1.sh +``` +- run the test (fr1.sh) + +At the date of writing, the test comprises the deployment of the components (epc, eNB, gNB, cots ue) and the execution of 2 pings procedures (20 pings in 20sec, then 5 pings in 1sec) + +This automation is run for every integration branch to be merged into develop. diff --git a/doc/testing_gnb_w_cots_ue_resources/enb.conf b/doc/testing_gnb_w_cots_ue_resources/enb.conf index 58e4e86873..35249aac25 100755 --- a/doc/testing_gnb_w_cots_ue_resources/enb.conf +++ b/doc/testing_gnb_w_cots_ue_resources/enb.conf @@ -187,6 +187,8 @@ eNBs = enable_x2 = "yes"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/doc/testing_gnb_w_cots_ue_resources/gnb.conf b/doc/testing_gnb_w_cots_ue_resources/gnb.conf index db8aef33ba..c4a8d512b8 100755 --- a/doc/testing_gnb_w_cots_ue_resources/gnb.conf +++ b/doc/testing_gnb_w_cots_ue_resources/gnb.conf @@ -212,6 +212,8 @@ gNBs = enable_x2 = "yes"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ target_enb_x2_ip_address = ( { ipv4 = "192.168.18.199"; ipv6 = "192:168:30::17"; diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 27b0ed08dd..2eb0b0692d 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -139,7 +139,6 @@ 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) { sl_ahead = sf_ahead*gNB->frame_parms.slots_per_subframe; @@ -178,6 +177,59 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t T(T_GNB_PHY_DL_TICK, T_INT(gNB->Mod_id), T_INT(frame_tx), T_INT(slot_tx)); + /* hack to remove UEs */ + extern int rnti_to_remove[10]; + extern volatile int rnti_to_remove_count; + extern pthread_mutex_t rnti_to_remove_mutex; + if (pthread_mutex_lock(&rnti_to_remove_mutex)) exit(1); + int up_removed = 0; + int down_removed = 0; + int pucch_removed = 0; + for (int i = 0; i < rnti_to_remove_count; i++) { + LOG_W(PHY, "to remove rnti %d\n", rnti_to_remove[i]); + void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch); + void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch); + int j; + for (j = 0; j < NUMBER_OF_NR_ULSCH_MAX; j++) + if (gNB->ulsch[j][0]->rnti == rnti_to_remove[i]) { + gNB->ulsch[j][0]->rnti = 0; + gNB->ulsch[j][0]->harq_mask = 0; + //clean_gNB_ulsch(gNB->ulsch[j][0]); + int h; + for (h = 0; h < NR_MAX_ULSCH_HARQ_PROCESSES; h++) { + gNB->ulsch[j][0]->harq_processes[h]->status = SCH_IDLE; + gNB->ulsch[j][0]->harq_processes[h]->round = 0; + gNB->ulsch[j][0]->harq_processes[h]->handled = 0; + } + up_removed++; + } + for (j = 0; j < NUMBER_OF_NR_DLSCH_MAX; j++) + if (gNB->dlsch[j][0]->rnti == rnti_to_remove[i]) { + gNB->dlsch[j][0]->rnti = 0; + gNB->dlsch[j][0]->harq_mask = 0; + //clean_gNB_dlsch(gNB->dlsch[j][0]); + down_removed++; + } + for (j = 0; j < NUMBER_OF_NR_PUCCH_MAX; j++) + if (gNB->pucch[j]->active > 0 && + gNB->pucch[j]->pucch_pdu.rnti == rnti_to_remove[i]) { + gNB->pucch[j]->active = 0; + gNB->pucch[j]->pucch_pdu.rnti = 0; + pucch_removed++; + } +#if 0 + for (j = 0; j < NUMBER_OF_NR_PDCCH_MAX; j++) + gNB->pdcch_pdu[j].frame = -1; + for (j = 0; j < NUMBER_OF_NR_PDCCH_MAX; j++) + gNB->ul_pdcch_pdu[j].frame = -1; + for (j = 0; j < NUMBER_OF_NR_PRACH_MAX; j++) + gNB->prach_vars.list[j].frame = -1; +#endif + } + if (rnti_to_remove_count) LOG_W(PHY, "to remove rnti_to_remove_count=%d, up_removed=%d down_removed=%d pucch_removed=%d\n", rnti_to_remove_count, up_removed, down_removed, pucch_removed); + 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) { diff --git a/executables/stats.h b/executables/stats.h index 6c847a2860..9bd4c6f080 100644 --- a/executables/stats.h +++ b/executables/stats.h @@ -21,8 +21,8 @@ /* Header file generated by fdesign on Thu Aug 28 12:13:51 2014 */ -#ifndef FD_stats_form_h_ -#define FD_stats_form_h_ +#ifndef _EXECUTABLES_STATS_H_ +#define _EXECUTABLES_STATS_H_ #include @@ -43,4 +43,4 @@ typedef struct { extern FD_stats_form *create_form_stats_form( void ); -#endif /* FD_stats_form_h_ */ +#endif /* _EXECUTABLES_STATS_H_ */ diff --git a/executables/threads_t.h b/executables/threads_t.h index 0671f40988..c4b233ccc9 100644 --- a/executables/threads_t.h +++ b/executables/threads_t.h @@ -1,5 +1,5 @@ -#ifndef _THREADS_T_H_ -#define _THREADS_T_H_ +#ifndef _EXECUTABLES_THREADS_T_H_ +#define _EXECUTABLES_THREADS_T_H_ typedef struct threads_s { int main; @@ -18,4 +18,4 @@ typedef struct threads_s { //int dlsch_td1_three; } threads_t; -#endif /* _THREADS_T_H_ */ +#endif /* _EXECUTABLES_THREADS_T_H_ */ diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index 3fd7966ce7..b27e7496f7 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -1147,9 +1147,9 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, //--------------------- RBs extraction --------------------- //---------------------------------------------------------- - if (nb_re_pusch > 0) { + gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol] = nb_re_pusch; - gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol] = nb_re_pusch; + if (nb_re_pusch > 0) { start_meas(&gNB->ulsch_rbs_extraction_stats); nr_ulsch_extract_rbs_single(gNB->common_vars.rxdataF, diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index 71132b64c5..bee868b5a5 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -67,7 +67,7 @@ int nr_find_pucch(uint16_t rnti, AssertFatal(gNB!=NULL,"gNB is null\n"); int index = -1; - for (int i=0; ipucch[i]!=NULL,"gNB->pucch[%d] is null\n",i); if ((gNB->pucch[i]->active >0) && (gNB->pucch[i]->pucch_pdu.rnti==rnti) && @@ -414,7 +414,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, uci_pdu->harq->harq_confidence_level = (no_conf) ? 1 : 0; uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(1); uci_pdu->harq->harq_list[0].harq_value = index&0x01; - LOG_I(PHY, "HARQ value %d with confidence level (0 is good, 1 is bad) %d\n", + LOG_D(PHY, "HARQ value %d with confidence level (0 is good, 1 is bad) %d\n", uci_pdu->harq->harq_list[0].harq_value,uci_pdu->harq->harq_confidence_level); if (pucch_pdu->sr_flag == 1) { uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr)); @@ -429,7 +429,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(2); uci_pdu->harq->harq_list[1].harq_value = index&0x01; uci_pdu->harq->harq_list[0].harq_value = (index>>1)&0x01; - LOG_I(PHY, "HARQ values %d and %d with confidence level (0 is good, 1 is bad) %d\n", + LOG_D(PHY, "HARQ values %d and %d with confidence level (0 is good, 1 is bad) %d\n", uci_pdu->harq->harq_list[1].harq_value,uci_pdu->harq->harq_list[0].harq_value,uci_pdu->harq->harq_confidence_level); if (pucch_pdu->sr_flag == 1) { uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr)); diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 5d67dcd3e4..d24c88fd1f 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -1669,7 +1669,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, // looking for pbch only in slot where it is supposed to be if ((ue->decode_MIB == 1) && slot_pbch) { - LOG_I(PHY," ------ PBCH ChannelComp/LLR: frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx); + LOG_D(PHY," ------ PBCH ChannelComp/LLR: frame.slot %d.%d ------ \n", frame_rx%1024, nr_tti_rx); for (int i=1; i<4; i++) { nr_slot_fep(ue, @@ -1690,7 +1690,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, nr_ue_pbch_procedures(gNB_id, ue, proc, 0); if (ue->no_timing_correction==0) { - LOG_I(PHY,"start adjust sync slot = %d no timing %d\n", nr_tti_rx, ue->no_timing_correction); + LOG_D(PHY,"start adjust sync slot = %d no timing %d\n", nr_tti_rx, ue->no_timing_correction); nr_adjust_synch_ue(fp, ue, gNB_id, diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 200508cc67..e78c769623 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -67,6 +67,9 @@ #include "SIMULATION/LTE_PHY/common_sim.h" +unsigned char NB_eNB_INST=0; +LCHAN_DESC DCCH_LCHAN_DESC,DTCH_DL_LCHAN_DESC,DTCH_UL_LCHAN_DESC; +rlc_info_t Rlc_info_um,Rlc_info_am_config; PHY_VARS_gNB *gNB; PHY_VARS_NR_UE *UE; @@ -84,8 +87,6 @@ uint64_t downlink_frequency[MAX_NUM_CCs][4]; // dummy functions int dummy_nr_ue_ul_indication(nr_uplink_indication_t *ul_info) { return(0); } -void pdcp_run (const protocol_ctxt_t *const ctxt_pP) { return;} - int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, @@ -96,19 +97,33 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, return 0; } - -void pdcp_layer_init(void) {} -boolean_t -pdcp_data_ind( +void +rrc_data_ind( const protocol_ctxt_t *const ctxt_pP, - const srb_flag_t srb_flagP, - const MBMS_flag_t MBMS_flagP, - const rb_id_t rb_idP, - const sdu_size_t sdu_buffer_sizeP, - mem_block_t *const sdu_buffer_pP -) { return(false);} + const rb_id_t Srb_id, + const sdu_size_t sdu_sizeP, + const uint8_t *const buffer_pP +) +{ +} -int rrc_init_nr_global_param(void){return(0);} +int +gtpv1u_create_s1u_tunnel( + const instance_t instanceP, + const gtpv1u_enb_create_tunnel_req_t *const create_tunnel_req_pP, + gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP +) { + return 0; +} + +int +rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( + const protocol_ctxt_t *const ctxt_pP, + const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP, + uint8_t *inde_list +) { + return 0; +} void config_common(int Mod_idP, int pdsch_AntennaPorts, @@ -124,7 +139,6 @@ int generate_dlsch_header(unsigned char *mac_header, unsigned char *ue_cont_res_id, unsigned char short_padding, unsigned short post_padding){return 0;} -void nr_DRB_preconfiguration(void){} // needed for some functions openair0_config_t openair0_cfg[MAX_CARDS]; @@ -697,7 +711,7 @@ int main(int argc, char **argv) nr_ue_phy_config_request(&UE_mac->phy_config); - NR_UE_list_t *UE_list = &RC.nrmac[0]->UE_list; + NR_UE_info_t *UE_info = &RC.nrmac[0]->UE_info; //NR_COMMON_channels_t *cc = RC.nrmac[0]->common_channels; snrRun = 0; @@ -758,11 +772,11 @@ int main(int argc, char **argv) memset(RC.nrmac[0]->cce_list[1][1],0,MAX_NUM_CCE*sizeof(int)); clear_nr_nfapi_information(RC.nrmac[0], 0, frame, slot); - UE_list->UE_sched_ctrl[0].harq_processes[harq_pid].ndi = !(trial&1); + UE_info->UE_sched_ctrl[0].harq_processes[harq_pid].ndi = !(trial&1); - UE_list->UE_sched_ctrl[0].harq_processes[harq_pid].round = round; - UE_list->UE_sched_ctrl[0].current_harq_pid = harq_pid; + UE_info->UE_sched_ctrl[0].harq_processes[harq_pid].round = round; + UE_info->UE_sched_ctrl[0].current_harq_pid = harq_pid; gNB->dlsch[0][0]->harq_processes[harq_pid]->round = round; if (css_flag == 0) nr_schedule_uss_dlsch_phytest(0,frame,slot,&pucch_sched,&dlsch_config); diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 7d96e70809..cb196afe9a 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -49,6 +49,10 @@ #define NR_PRACH_DEBUG 1 #define PRACH_WRITE_OUTPUT_DEBUG 1 +unsigned char NB_eNB_INST=0; +LCHAN_DESC DCCH_LCHAN_DESC,DTCH_DL_LCHAN_DESC,DTCH_UL_LCHAN_DESC; +rlc_info_t Rlc_info_um,Rlc_info_am_config; + PHY_VARS_gNB *gNB; PHY_VARS_NR_UE *UE; RAN_CONTEXT_t RC; @@ -66,17 +70,34 @@ int sl_ahead = 0; uint64_t get_softmodem_optmask(void) {return 0;} softmodem_params_t *get_softmodem_params(void) {return 0;} -void pdcp_run (const protocol_ctxt_t *const ctxt_pP) { return;} +void +rrc_data_ind( + const protocol_ctxt_t *const ctxt_pP, + const rb_id_t Srb_id, + const sdu_size_t sdu_sizeP, + const uint8_t *const buffer_pP +) +{ +} -boolean_t pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP, - const srb_flag_t srb_flagP, - const MBMS_flag_t MBMS_flagP, - const rb_id_t rb_idP, - const sdu_size_t sdu_buffer_sizeP, - mem_block_t *const sdu_buffer_pP) {return(false);} +int +gtpv1u_create_s1u_tunnel( + const instance_t instanceP, + const gtpv1u_enb_create_tunnel_req_t *const create_tunnel_req_pP, + gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP +) { + return 0; +} + +int +rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( + const protocol_ctxt_t *const ctxt_pP, + const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP, + uint8_t *inde_list +) { + return 0; +} -void nr_DRB_preconfiguration(void){} -void pdcp_layer_init(void) {} 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;} int main(int argc, char **argv){ diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index fafd1fd22c..106ae112db 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -60,6 +60,10 @@ //#define DEBUG_ULSIM +unsigned char NB_eNB_INST=0; +LCHAN_DESC DCCH_LCHAN_DESC,DTCH_DL_LCHAN_DESC,DTCH_UL_LCHAN_DESC; +rlc_info_t Rlc_info_um,Rlc_info_am_config; + PHY_VARS_gNB *gNB; PHY_VARS_NR_UE *UE; RAN_CONTEXT_t RC; @@ -84,20 +88,34 @@ int generate_dlsch_header(unsigned char *mac_header, unsigned char *ue_cont_res_id, unsigned char short_padding, unsigned short post_padding){return 0;} -void pdcp_layer_init (void) {} -boolean_t pdcp_data_ind( + +void +rrc_data_ind( const protocol_ctxt_t *const ctxt_pP, - const srb_flag_t srb_flagP, - const MBMS_flag_t MBMS_flagP, - const rb_id_t rb_idP, - const sdu_size_t sdu_buffer_sizeP, - mem_block_t *const sdu_buffer_pP -) { return(false);} + const rb_id_t Srb_id, + const sdu_size_t sdu_sizeP, + const uint8_t *const buffer_pP +) +{ +} -void pdcp_run (const protocol_ctxt_t *const ctxt_pP) { return;} -void nr_DRB_preconfiguration(void){} -int rrc_init_nr_global_param(void){return(0);} +int +gtpv1u_create_s1u_tunnel( + const instance_t instanceP, + const gtpv1u_enb_create_tunnel_req_t *const create_tunnel_req_pP, + gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP +) { + return 0; +} +int +rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( + const protocol_ctxt_t *const ctxt_pP, + const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP, + uint8_t *inde_list +) { + return 0; +} // needed for some functions uint16_t n_rnti = 0x1234; diff --git a/openair2/COMMON/gtpv1_u_messages_types.h b/openair2/COMMON/gtpv1_u_messages_types.h index 054f3f3734..14b6e7c0b1 100644 --- a/openair2/COMMON/gtpv1_u_messages_types.h +++ b/openair2/COMMON/gtpv1_u_messages_types.h @@ -98,6 +98,7 @@ typedef struct gtpv1u_enb_delete_tunnel_req_s { uint8_t num_erab; ebi_t eps_bearer_id[GTPV1U_MAX_BEARERS_PER_UE]; //teid_t enb_S1u_teid; ///< local SGW S11 Tunnel Endpoint Identifier + int from_gnb; ///< Indicates if the message comes from gNB or eNB (1 = comes from gNB, 0 from eNB) } gtpv1u_enb_delete_tunnel_req_t; typedef struct gtpv1u_enb_delete_tunnel_resp_s { @@ -170,4 +171,5 @@ typedef struct { in_addr_t enb_ip_address_for_S1u_S12_S4_up; tcp_udp_port_t enb_port_for_S1u_S12_S4_up; } Gtpv1uS1Req; + #endif /* GTPV1_U_MESSAGES_TYPES_H_ */ diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index 0b143fe07e..6f37c8be1c 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -323,6 +323,8 @@ typedef struct RrcConfigurationReq_s { char *discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[MAX_NUM_CCs]; long discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size[MAX_NUM_CCs]; long discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused[MAX_NUM_CCs]; + //Nr secondary cell group SSB central frequency (for ENDC NSA) + int nr_scg_ssb_freq; } RrcConfigurationReq; #define MAX_NUM_NBIOT_CELEVELS 3 diff --git a/openair2/COMMON/x2ap_messages_def.h b/openair2/COMMON/x2ap_messages_def.h index 8438fd1037..14fc0d3ac9 100644 --- a/openair2/COMMON/x2ap_messages_def.h +++ b/openair2/COMMON/x2ap_messages_def.h @@ -48,10 +48,19 @@ MESSAGE_DEF(X2AP_HANDOVER_CANCEL , MESSAGE_PRIORITY_MED, x2ap_han /* handover messages X2AP <-> S1AP */ MESSAGE_DEF(X2AP_UE_CONTEXT_RELEASE , MESSAGE_PRIORITY_MED, x2ap_ue_context_release_t , x2ap_ue_context_release) -/*Senb bearer addition messages X2AP <-> RRC */ +/* Senb bearer addition messages X2AP <-> RRC */ MESSAGE_DEF(X2AP_SENB_ADDITION_REQ , MESSAGE_PRIORITY_MED, x2ap_senb_addition_req_t , x2ap_senb_addition_req) -/*SGnb bearer addition messages X2AP <-> RRC */ -MESSAGE_DEF(X2AP_ENDC_SGNB_ADDITION_REQ , MESSAGE_PRIORITY_MED, x2ap_ENDC_sgnb_addition_req_t , x2ap_ENDC_sgnb_addition_req) -MESSAGE_DEF(X2AP_ENDC_SGNB_ADDITION_REQ_ACK , MESSAGE_PRIORITY_MED, x2ap_ENDC_sgnb_addition_req_ACK_t , x2ap_ENDC_sgnb_addition_req_ACK) -MESSAGE_DEF(X2AP_ENDC_SGNB_RECONF_COMPLETE , MESSAGE_PRIORITY_MED, x2ap_ENDC_reconf_complete_t , x2ap_ENDC_sgnb_reconf_complete) +/* SGnb bearer addition messages X2AP <-> RRC */ +MESSAGE_DEF(X2AP_ENDC_SETUP_REQ , MESSAGE_PRIORITY_MED, x2ap_ENDC_setup_req_t , x2ap_ENDC_setup_req) +MESSAGE_DEF(X2AP_ENDC_SGNB_ADDITION_REQ , MESSAGE_PRIORITY_MED, x2ap_ENDC_sgnb_addition_req_t , x2ap_ENDC_sgnb_addition_req) +MESSAGE_DEF(X2AP_ENDC_SGNB_ADDITION_REQ_ACK , MESSAGE_PRIORITY_MED, x2ap_ENDC_sgnb_addition_req_ACK_t, x2ap_ENDC_sgnb_addition_req_ACK) +MESSAGE_DEF(X2AP_ENDC_SGNB_RECONF_COMPLETE , MESSAGE_PRIORITY_MED, x2ap_ENDC_reconf_complete_t , x2ap_ENDC_sgnb_reconf_complete) + +/* SGnb UE releases ('request' is for enb starting the process, 'required' for gnb) */ +MESSAGE_DEF(X2AP_ENDC_SGNB_RELEASE_REQUEST , MESSAGE_PRIORITY_MED, x2ap_ENDC_sgnb_release_request_t , x2ap_ENDC_sgnb_release_request) +MESSAGE_DEF(X2AP_ENDC_SGNB_RELEASE_REQUIRED , MESSAGE_PRIORITY_MED, x2ap_ENDC_sgnb_release_required_t, x2ap_ENDC_sgnb_release_required) + +/* ENDC timers' timeout X2AP <-> RRC */ +MESSAGE_DEF(X2AP_ENDC_DC_PREP_TIMEOUT , MESSAGE_PRIORITY_MED, x2ap_ENDC_dc_prep_timeout_t , x2ap_ENDC_dc_prep_timeout) +MESSAGE_DEF(X2AP_ENDC_DC_OVERALL_TIMEOUT , MESSAGE_PRIORITY_MED, x2ap_ENDC_dc_overall_timeout_t , x2ap_ENDC_dc_overall_timeout) diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h index f0743e60a5..08ecde26a0 100644 --- a/openair2/COMMON/x2ap_messages_types.h +++ b/openair2/COMMON/x2ap_messages_types.h @@ -25,22 +25,34 @@ #include "s1ap_messages_types.h" #include "LTE_PhysCellId.h" +typedef enum { + X2AP_CAUSE_T_DC_PREP_TIMEOUT, + X2AP_CAUSE_T_DC_OVERALL_TIMEOUT, + X2AP_CAUSE_RADIO_CONNECTION_WITH_UE_LOST, +} x2ap_cause_t; + //-------------------------------------------------------------------------------------------// // Defines to access message fields. -#define X2AP_REGISTER_ENB_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_req -#define X2AP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_setup_req -#define X2AP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.x2ap_setup_resp -#define X2AP_HANDOVER_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_req -#define X2AP_HANDOVER_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_req_ack -#define X2AP_REGISTER_ENB_CNF(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_cnf -#define X2AP_DEREGISTERED_ENB_IND(mSGpTR) (mSGpTR)->ittiMsg.x2ap_deregistered_enb_ind -#define X2AP_UE_CONTEXT_RELEASE(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ue_context_release -#define X2AP_HANDOVER_CANCEL(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_cancel -#define X2AP_SENB_ADDITION_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_senb_addition_req -#define X2AP_ENDC_SGNB_ADDITION_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ENDC_sgnb_addition_req -#define X2AP_ENDC_SGNB_ADDITION_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ENDC_sgnb_addition_req_ACK -#define X2AP_ENDC_SGNB_RECONF_COMPLETE(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ENDC_sgnb_reconf_complete + +#define X2AP_REGISTER_ENB_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_req +#define X2AP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_setup_req +#define X2AP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.x2ap_setup_resp +#define X2AP_HANDOVER_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_req +#define X2AP_HANDOVER_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_req_ack +#define X2AP_REGISTER_ENB_CNF(mSGpTR) (mSGpTR)->ittiMsg.x2ap_register_enb_cnf +#define X2AP_DEREGISTERED_ENB_IND(mSGpTR) (mSGpTR)->ittiMsg.x2ap_deregistered_enb_ind +#define X2AP_UE_CONTEXT_RELEASE(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ue_context_release +#define X2AP_HANDOVER_CANCEL(mSGpTR) (mSGpTR)->ittiMsg.x2ap_handover_cancel +#define X2AP_SENB_ADDITION_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_senb_addition_req +#define X2AP_ENDC_SGNB_ADDITION_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ENDC_sgnb_addition_req +#define X2AP_ENDC_SGNB_ADDITION_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ENDC_sgnb_addition_req_ACK +#define X2AP_ENDC_SGNB_RECONF_COMPLETE(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ENDC_sgnb_reconf_complete +#define X2AP_ENDC_SGNB_RELEASE_REQUEST(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ENDC_sgnb_release_request +#define X2AP_ENDC_SGNB_RELEASE_REQUIRED(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ENDC_sgnb_release_required +#define X2AP_ENDC_DC_PREP_TIMEOUT(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ENDC_dc_prep_timeout +#define X2AP_ENDC_DC_OVERALL_TIMEOUT(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ENDC_dc_overall_timeout +#define X2AP_ENDC_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.x2ap_ENDC_setup_req #define X2AP_MAX_NB_ENB_IP_ADDRESS 2 @@ -144,6 +156,8 @@ typedef struct x2ap_register_enb_req_s { /* timers (unit: millisecond) */ int t_reloc_prep; int tx2_reloc_overall; + int t_dc_prep; + int t_dc_overall; } x2ap_register_enb_req_t; typedef struct x2ap_subframe_process_s { @@ -288,10 +302,6 @@ typedef struct x2ap_senb_addition_req_s { }x2ap_senb_addition_req_t; - - - -//Panos: Have to see what should be the additional/different elements comparing to handover req ack typedef struct x2ap_senb_addition_req_ack_s { int MeNB_UE_X2_id; @@ -313,6 +323,13 @@ typedef struct x2ap_senb_addition_req_ack_s { } x2ap_senb_addition_req_ack_t; + +typedef struct x2ap_ENDC_setup_req_s { + uint32_t Nid_cell[MAX_NUM_CCs]; + int num_cc; + uint32_t servedNrCell_band[MAX_NUM_CCs]; +} x2ap_ENDC_setup_req_t; + typedef struct x2ap_ENDC_sgnb_addition_req_s { int ue_x2_id; LTE_PhysCellId_t target_physCellId; @@ -357,6 +374,8 @@ typedef struct x2ap_ENDC_sgnb_addition_req_ACK_s { int SgNB_ue_x2_id; + int gnb_x2_assoc_id; // to be stored in the rrc's ue context, used when sending 'sgnb reconfiguration complete' + /* used for X2AP->RRC in source eNB */ int rnti; @@ -384,16 +403,26 @@ typedef struct x2ap_ENDC_sgnb_addition_req_ACK_s { typedef struct x2ap_ENDC_reconf_complete_s { int MeNB_ue_x2_id; - int SgNB_ue_x2_id; - LTE_PhysCellId_t target_physCellId; - - x2ap_sgNB_reconf_response_information_t reconf_response; - - uint8_t rrc_buffer[4096 /* arbitrary, big enough */]; - int rrc_buffer_size; - + int gnb_x2_assoc_id; } x2ap_ENDC_reconf_complete_t; +typedef struct x2ap_ENDC_sgnb_release_request_s { + int rnti; + x2ap_cause_t cause; + int assoc_id; +} x2ap_ENDC_sgnb_release_request_t; + +typedef struct x2ap_ENDC_sgnb_release_required_s { + int gnb_rnti; +} x2ap_ENDC_sgnb_release_required_t; + +typedef struct x2ap_ENDC_dc_prep_timeout_s { + int rnti; +} x2ap_ENDC_dc_prep_timeout_t; + +typedef struct x2ap_ENDC_dc_overall_timeout_s { + int rnti; +} x2ap_ENDC_dc_overall_timeout_t; #endif /* X2AP_MESSAGES_TYPES_H_ */ diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 4c6a7885c3..cf8ba78a81 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -1576,6 +1576,8 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { } // !NODE_IS_DU(node_type) } + RRC_CONFIGURATION_REQ (msg_p).nr_scg_ssb_freq = ccparams_lte.nr_scg_ssb_freq; + if (!NODE_IS_DU(rrc->node_type)) { char srb1path[MAX_OPTNAME_SIZE*2 + 8]; sprintf(srb1path,"%s.%s",enbpath,ENB_CONFIG_STRING_SRB1); @@ -2731,20 +2733,28 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) { { int t_reloc_prep = 0; int tx2_reloc_overall = 0; + int t_dc_prep = 0; + int t_dc_overall = 0; paramdef_t p[] = { { "t_reloc_prep", "t_reloc_prep", 0, iptr:&t_reloc_prep, defintval:0, TYPE_INT, 0 }, - { "tx2_reloc_overall", "tx2_reloc_overall", 0, iptr:&tx2_reloc_overall, defintval:0, TYPE_INT, 0 } + { "tx2_reloc_overall", "tx2_reloc_overall", 0, iptr:&tx2_reloc_overall, defintval:0, TYPE_INT, 0 }, + { "t_dc_prep", "t_dc_prep", 0, iptr:&t_dc_prep, defintval:0, TYPE_INT, 0 }, + { "t_dc_overall", "t_dc_overall", 0, iptr:&t_dc_overall, defintval:0, TYPE_INT, 0 } }; config_get(p, sizeof(p)/sizeof(paramdef_t), aprefix); if (t_reloc_prep <= 0 || t_reloc_prep > 10000 || - tx2_reloc_overall <= 0 || tx2_reloc_overall > 20000) { - LOG_E(X2AP, "timers in configuration file have wrong values. We must have [0 < t_reloc_prep <= 10000] and [0 < tx2_reloc_overall <= 20000]\n"); + tx2_reloc_overall <= 0 || tx2_reloc_overall > 20000 || + t_dc_prep <= 0 || t_dc_prep > 10000 || + t_dc_overall <= 0 || t_dc_overall > 20000) { + LOG_E(X2AP, "timers in configuration file have wrong values. We must have [0 < t_reloc_prep <= 10000] and [0 < tx2_reloc_overall <= 20000] and [0 < t_dc_prep <= 10000] and [0 < t_dc_overall <= 20000]\n"); exit(1); } X2AP_REGISTER_ENB_REQ (msg_p).t_reloc_prep = t_reloc_prep; X2AP_REGISTER_ENB_REQ (msg_p).tx2_reloc_overall = tx2_reloc_overall; + X2AP_REGISTER_ENB_REQ (msg_p).t_dc_prep = t_dc_prep; + X2AP_REGISTER_ENB_REQ (msg_p).t_dc_overall = t_dc_overall; } // SCTP SETTING X2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = SCTP_OUT_STREAMS; diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h index 344214a1f1..d2372c944c 100644 --- a/openair2/ENB_APP/enb_paramdef.h +++ b/openair2/ENB_APP/enb_paramdef.h @@ -429,6 +429,9 @@ typedef enum { //SIB1-MBMS #define ENB_CONFIG_STRING_MBMS_DEDICATED_SERVING_CELL "mbms_dedicated_serving_cell" +//NSA NR Cell SSB Absolute Frequency +#define ENB_CONFIG_STRING_NR_SCG_SSB_FREQ "nr_scg_ssb_freq" + #define ENB_CONFIG_STRING_PDSCH_MAX_NUM_REPETITION_CE_MODE_A_R13 "pdsch_maxNumRepetitionCEmodeA_r13" @@ -577,6 +580,7 @@ typedef struct ccparams_lte_s { int32_t srb1_poll_pdu; int32_t srb1_poll_byte; int32_t srb1_max_retx_threshold; + int32_t nr_scg_ssb_freq; } ccparams_lte_t; #define CCPARAMS_CHECK { \ @@ -780,7 +784,8 @@ typedef struct ccparams_lte_s { {ENB_CONFIG_STRING_UETIMERS_N311, NULL, 0, iptr:&ccparams.ue_TimersAndConstants_n311, defintval:1, TYPE_UINT, 0}, \ {ENB_CONFIG_STRING_UE_TRANSMISSION_MODE, NULL, 0, iptr:&ccparams.ue_TransmissionMode, defintval:1, TYPE_UINT, 0}, \ {ENB_CONFIG_STRING_UE_MULTIPLE_MAX, NULL, 0, iptr:&ccparams.ue_multiple_max, defintval:4, TYPE_UINT, 0}, \ - {ENB_CONFIG_STRING_MBMS_DEDICATED_SERVING_CELL, NULL, 0, strptr:&ccparams.mbms_dedicated_serving_cell, defstrval:"DISABLE", TYPE_STRING, 0} \ + {ENB_CONFIG_STRING_MBMS_DEDICATED_SERVING_CELL, NULL, 0, strptr:&ccparams.mbms_dedicated_serving_cell, defstrval:"DISABLE", TYPE_STRING, 0}, \ + {ENB_CONFIG_STRING_NR_SCG_SSB_FREQ, NULL, 0, iptr:&ccparams.nr_scg_ssb_freq, defintval:641272, TYPE_INT, 0} \ } diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 716134ad8a..8c8e78bbd0 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -1123,20 +1123,28 @@ int RCconfig_NR_X2(MessageDef *msg_p, uint32_t i) { { int t_reloc_prep = 0; int tx2_reloc_overall = 0; + int t_dc_prep = 0; + int t_dc_overall = 0; paramdef_t p[] = { { "t_reloc_prep", "t_reloc_prep", 0, iptr:&t_reloc_prep, defintval:0, TYPE_INT, 0 }, - { "tx2_reloc_overall", "tx2_reloc_overall", 0, iptr:&tx2_reloc_overall, defintval:0, TYPE_INT, 0 } + { "tx2_reloc_overall", "tx2_reloc_overall", 0, iptr:&tx2_reloc_overall, defintval:0, TYPE_INT, 0 }, + { "t_dc_prep", "t_dc_prep", 0, iptr:&t_dc_prep, defintval:0, TYPE_INT, 0 }, + { "t_dc_overall", "t_dc_overall", 0, iptr:&t_dc_overall, defintval:0, TYPE_INT, 0 } }; config_get(p, sizeof(p)/sizeof(paramdef_t), aprefix); if (t_reloc_prep <= 0 || t_reloc_prep > 10000 || - tx2_reloc_overall <= 0 || tx2_reloc_overall > 20000) { - LOG_E(X2AP, "timers in configuration file have wrong values. We must have [0 < t_reloc_prep <= 10000] and [0 < tx2_reloc_overall <= 20000]\n"); + tx2_reloc_overall <= 0 || tx2_reloc_overall > 20000 || + t_dc_prep <= 0 || t_dc_prep > 10000 || + t_dc_overall <= 0 || t_dc_overall > 20000) { + LOG_E(X2AP, "timers in configuration file have wrong values. We must have [0 < t_reloc_prep <= 10000] and [0 < tx2_reloc_overall <= 20000] and [0 < t_dc_prep <= 10000] and [0 < t_dc_overall <= 20000]\n"); exit(1); } X2AP_REGISTER_ENB_REQ (msg_p).t_reloc_prep = t_reloc_prep; X2AP_REGISTER_ENB_REQ (msg_p).tx2_reloc_overall = tx2_reloc_overall; + X2AP_REGISTER_ENB_REQ (msg_p).t_dc_prep = t_dc_prep; + X2AP_REGISTER_ENB_REQ (msg_p).t_dc_overall = t_dc_overall; } // SCTP SETTING X2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = SCTP_OUT_STREAMS; diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index bc105b9080..8fe83dd40d 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -1603,11 +1603,9 @@ uint16_t Table_51312[28][2] = {{2,120},{2,193},{2,308},{2,449},{2,602},{4,378},{ uint16_t Table_51313[29][2] = {{2,30},{2,40},{2,50},{2,64},{2,78},{2,99},{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{4,340}, {4,378},{4,434},{4,490},{4,553},{4,616},{6,438},{6,466},{6,517},{6,567},{6,616},{6,666}, {6,719}, {6,772}}; -//Table 6.1.4.1-1 of 38.214 TODO fix for tp-pi2BPSK uint16_t Table_61411[28][2] = {{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{2,679},{4,340},{4,378},{4,434},{4,490},{4,553},{4,616}, {4,658},{6,466},{6,517},{6,567},{6,616},{6,666},{6,719},{6,772},{6,822},{6,873}, {6,910}, {6,948}}; -//Table 6.1.4.1-2 of 38.214 TODO fix for tp-pi2BPSK uint16_t Table_61412[28][2] = {{2,30},{2,40},{2,50},{2,64},{2,78},{2,99},{2,120},{2,157},{2,193},{2,251},{2,308},{2,379},{2,449},{2,526},{2,602},{2,679}, {4,378},{4,434},{4,490},{4,553},{4,616},{4,658},{4,699},{4,772},{6,567},{6,616},{6,666}, {6,772}}; @@ -2471,6 +2469,40 @@ int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,i return(-1); } +uint8_t get_pusch_mcs_table(long *mcs_Table, + int is_tp, + int dci_format, + int rnti_type, + int target_ss, + bool config_grant) { + + // implementing 6.1.4.1 in 38.214 + if (mcs_Table != NULL) { + if (config_grant || (rnti_type == NR_RNTI_CS)) { + if (*mcs_Table == NR_PUSCH_Config__mcs_Table_qam256) + return 1; + else + return (2+(is_tp<<1)); + } + else { + if ((*mcs_Table == NR_PUSCH_Config__mcs_Table_qam256) && + (dci_format == NR_UL_DCI_FORMAT_0_1) && + ((rnti_type == NR_RNTI_C ) || (rnti_type == NR_RNTI_SP_CSI))) + return 1; + // TODO take into account UE configuration + if ((*mcs_Table == NR_PUSCH_Config__mcs_Table_qam64LowSE) && + (target_ss == NR_SearchSpace__searchSpaceType_PR_ue_Specific) && + ((rnti_type == NR_RNTI_C ) || (rnti_type == NR_RNTI_SP_CSI))) + return (2+(is_tp<<1)); + if (rnti_type == NR_RNTI_MCS_C) + return (2+(is_tp<<1)); + AssertFatal(1==0,"Invalid configuration to set MCS table"); + } + } + else + return (0+(is_tp*3)); +} + int binomial(int n, int k) { int c = 1, i; diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index a5e38bf128..f19a46cb34 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -60,7 +60,8 @@ typedef enum { NR_RNTI_INT, NR_RNTI_TPC_PUSCH, NR_RNTI_TPC_PUCCH, - NR_RNTI_TPC_SRS + NR_RNTI_TPC_SRS, + NR_RNTI_MCS_C, } nr_rnti_type_t; uint16_t config_bandwidth(int mu, int nb_rb, int nr_band); @@ -100,6 +101,13 @@ int get_nr_prach_info_from_index(uint8_t index, uint8_t *N_t_slot, uint8_t *N_dur); +uint8_t get_pusch_mcs_table(long *mcs_Table, + int is_tp, + int dci_format, + int rnti_type, + int target_ss, + bool config_grant); + uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config, uint8_t nb_preambles, uint8_t unpaired); diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 4e46603dc9..ad8409de69 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -46,6 +46,9 @@ #include "NR_MIB.h" #include "LAYER2/NR_MAC_COMMON/nr_mac_common.h" +/* Softmodem params */ +#include "executables/softmodem-common.h" + extern RAN_CONTEXT_t RC; //extern int l2_init_gNB(void); extern void mac_top_init_gNB(void); @@ -346,22 +349,34 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, if (secondaryCellGroup) { - NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list; - int UE_id; - if (add_ue == 1) { - UE_id = add_new_nr_ue(Mod_idP,rnti); - UE_list->secondaryCellGroup[UE_id] = secondaryCellGroup; - uint8_t num_preamble = secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list.count; - UE_list->preambles[UE_id].num_preambles = num_preamble; - UE_list->preambles[UE_id].preamble_list = (uint8_t *) malloc(num_preamble*sizeof(uint8_t)); - for (int i=0; ipreambles[UE_id].preamble_list[i] = secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list.array[i]->ra_PreambleIndex; - } + NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; + if (add_ue == 1 && get_softmodem_params()->phy_test) { + const int UE_id = add_new_nr_ue(Mod_idP,rnti); + UE_info->secondaryCellGroup[UE_id] = secondaryCellGroup; + struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = + secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList; + AssertFatal(bwpList->list.count == 1, + "downlinkBWP_ToAddModList has %d BWP!\n", + bwpList->list.count); + const int bwp_id = 1; + UE_info->UE_sched_ctrl[UE_id].active_bwp = bwpList->list.array[bwp_id - 1]; LOG_I(PHY,"Added new UE_id %d/%x with initial secondaryCellGroup\n",UE_id,rnti); - } - else { // secondaryCellGroup has been updated - UE_id = find_nr_UE_id(Mod_idP,rnti); - UE_list->secondaryCellGroup[UE_id] = secondaryCellGroup; + } 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; + ra->secondaryCellGroup = secondaryCellGroup; + ra->crnti = rnti; + uint8_t num_preamble = secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->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] = secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list.array[i]->ra_PreambleIndex; + LOG_I(PHY,"Added new RA process for UE RNTI %04x with initial secondaryCellGroup\n", rnti); + } else { // secondaryCellGroup has been updated + const int UE_id = find_nr_UE_id(Mod_idP,rnti); + UE_info->secondaryCellGroup[UE_id] = secondaryCellGroup; LOG_I(PHY,"Modified UE_id %d/%x with secondaryCellGroup\n",UE_id,rnti); } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 548845eae5..58de000ac5 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -63,19 +63,19 @@ const uint8_t slots_per_frame[5] = {10, 20, 40, 80, 160}; uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 }; void clear_mac_stats(gNB_MAC_INST *gNB) { - memset((void*)gNB->UE_list.mac_stats,0,MAX_MOBILES_PER_GNB*sizeof(NR_mac_stats_t)); + memset((void*)gNB->UE_info.mac_stats,0,MAX_MOBILES_PER_GNB*sizeof(NR_mac_stats_t)); } void dump_mac_stats(gNB_MAC_INST *gNB) { - NR_UE_list_t *UE_list = &gNB->UE_list; + NR_UE_info_t *UE_info = &gNB->UE_info; NR_mac_stats_t *stats; int lc_id; for (int UE_id=0;UE_idactive[UE_id] == TRUE) { - LOG_I(MAC,"UE %x\n",UE_list->rnti[UE_id]); - stats = &UE_list->mac_stats[UE_id]; + if (UE_info->active[UE_id]) { + LOG_I(MAC, "UE %x\n", UE_info->rnti[UE_id]); + stats = &UE_info->mac_stats[UE_id]; LOG_I(MAC,"dlsch_rounds %d/%d/%d/%d, dlsch_errors %d\n",stats->dlsch_rounds[0],stats->dlsch_rounds[1],stats->dlsch_rounds[2],stats->dlsch_rounds[3],stats->dlsch_errors); LOG_I(MAC,"dlsch_total_bytes %d\n",stats->dlsch_total_bytes); LOG_I(MAC,"ulsch_rounds %d/%d/%d/%d, ulsch_errors %d\n",stats->ulsch_rounds[0],stats->ulsch_rounds[1],stats->ulsch_rounds[2],stats->ulsch_rounds[3],stats->ulsch_errors); @@ -130,18 +130,18 @@ void check_nr_ul_failure(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) { - UE_list_t *UE_list = &RC.nrmac[module_idP]->UE_list; + NR_UE_info_t *UE_info = &RC.nrmac[module_idP]->UE_info; nfapi_nr_dl_dci_request_t *DL_req = &RC.nrmac[module_idP]->DL_req[0]; uint16_t rnti = UE_RNTI(module_idP, UE_id); NR_COMMON_channels_t *cc = RC.nrmac[module_idP]->common_channels; // check uplink failure - if ((UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 0) && - (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 0)) { + if ((UE_info->UE_sched_ctrl[UE_id].ul_failure_timer > 0) && + (UE_info->UE_sched_ctrl[UE_id].ul_out_of_sync == 0)) { LOG_I(MAC, "UE %d rnti %x: UL Failure timer %d \n", UE_id, rnti, - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer); - if (UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent == 0) { - UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 1; + UE_info->UE_sched_ctrl[UE_id].ul_failure_timer); + if (UE_info->UE_sched_ctrl[UE_id].ra_pdcch_order_sent == 0) { + UE_info->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 1; // add a format 1A dci for this UE to request an RA procedure (only one UE per subframe) nfapi_nr_dl_dci_request_pdu_t *dl_config_pdu = &DL_req[CC_id].dl_tti_request_body.dl_config_pdu_list[DL_req[CC_id].dl_tti_request_body.number_pdu]; @@ -151,7 +151,7 @@ void check_nr_ul_failure(module_id_t module_idP, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_DCI_REQUEST_DCI_DL_PDU_REL8_TAG; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = get_aggregation(get_bw_index(module_idP, CC_id), - UE_list->UE_sched_ctrl[UE_id]. + UE_info->UE_sched_ctrl[UE_id]. dl_cqi[CC_id], format1A); dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications @@ -167,27 +167,27 @@ void check_nr_ul_failure(module_id_t module_idP, LOG_I(MAC, "UE %d rnti %x: sending PDCCH order for RAPROC (failure timer %d), resource_block_coding %d \n", UE_id, rnti, - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer, + UE_info->UE_sched_ctrl[UE_id].ul_failure_timer, dl_config_pdu->dci_dl_pdu. dci_dl_pdu_rel8.resource_block_coding); } else { // ra_pdcch_sent==1 LOG_I(MAC, "UE %d rnti %x: sent PDCCH order for RAPROC waiting (failure timer %d) \n", UE_id, rnti, - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer); - if ((UE_list->UE_sched_ctrl[UE_id].ul_failure_timer % 40) == 0) UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 0; // resend every 4 frames + UE_info->UE_sched_ctrl[UE_id].ul_failure_timer); + if ((UE_info->UE_sched_ctrl[UE_id].ul_failure_timer % 40) == 0) UE_info->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 0; // resend every 4 frames } - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer++; + UE_info->UE_sched_ctrl[UE_id].ul_failure_timer++; // check threshold - if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 20000) { + if (UE_info->UE_sched_ctrl[UE_id].ul_failure_timer > 20000) { // inform RRC of failure and clear timer LOG_I(MAC, "UE %d rnti %x: UL Failure after repeated PDCCH orders: Triggering RRC \n", UE_id, rnti); mac_eNB_rrc_ul_failure(module_idP, CC_id, frameP, subframeP,rnti); - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; - UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 1; + UE_info->UE_sched_ctrl[UE_id].ul_failure_timer = 0; + UE_info->UE_sched_ctrl[UE_id].ul_out_of_sync = 1; //Inform the controller about the UE deactivation. Should be moved to RRC agent in the future if (rrc_agent_registered[module_idP]) { @@ -204,7 +204,7 @@ void check_nr_ul_failure(module_id_t module_idP, void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { gNB_MAC_INST *gNB = RC.nrmac[module_idP]; - UE_list_t *UE_list = &gNB->UE_list; + NR_UE_info_t *UE_info = &gNB->UE_info; nfapi_ul_config_request_body_t *ul_req; int CC_id, UE_id; NR_COMMON_channels_t *cc = RC.nrmac[module_idP]->common_channels; @@ -238,16 +238,16 @@ void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subfram if ((1 << tmp) & deltaTSFC) { // This is an SRS subframe, loop over UEs for (UE_id = 0; UE_id < MAX_MOBILES_PER_GNB; UE_id++) { - if (!RC.nrmac[module_idP]->UE_list.active[UE_id]) continue; + if (!RC.nrmac[module_idP]->UE_info.active[UE_id]) continue; ul_req = &RC.nrmac[module_idP]->UL_req[CC_id].ul_config_request_body; // drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet if (mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP, UE_id)) < RRC_CONNECTED) continue; - AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, + AssertFatal(UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n", UE_id); - if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated) != NULL) { + if ((soundingRS_UL_ConfigDedicated = UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated) != NULL) { if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) { get_srs_pos(&cc[CC_id], soundingRS_UL_ConfigDedicated->choice. @@ -262,7 +262,7 @@ void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subfram ul_config_pdu->pdu_size = 2 + (uint8_t) (2 + sizeof(nfapi_ul_config_srs_pdu)); ul_config_pdu->srs_pdu.srs_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL8_TAG; ul_config_pdu->srs_pdu.srs_pdu_rel8.size = (uint8_t)sizeof(nfapi_ul_config_srs_pdu); - ul_config_pdu->srs_pdu.srs_pdu_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti; + ul_config_pdu->srs_pdu.srs_pdu_rel8.rnti = UE_info->UE_template[CC_id][UE_id].rnti; ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_bandwidth = soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth; ul_config_pdu->srs_pdu.srs_pdu_rel8.frequency_domain_position = soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition; ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_hopping_bandwidth = soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth;; @@ -275,7 +275,7 @@ void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subfram ul_req->number_of_pdus++; } // if (((10*frameP+subframeP) % srsPeriodicity) == srsOffset) } // if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) - } // if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL) + } // if ((soundingRS_UL_ConfigDedicated = UE_info->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL) } // for (UE_id ... } // if((1<UL_tti_req[0]; - NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list; + NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; int k = slotP + ul_slots - num_slots_per_tdd; - NR_sched_pusch *pusch = &UE_list->UE_sched_ctrl[UE_id].sched_pusch[k]; + NR_sched_pusch *pusch = &UE_info->UE_sched_ctrl[UE_id].sched_pusch[k]; if ((pusch->active == true) && (frameP == pusch->frame) && (slotP == pusch->slot)) { UL_tti_req->SFN = pusch->frame; UL_tti_req->Slot = pusch->slot; @@ -332,7 +332,7 @@ void nr_schedule_pusch(int Mod_idP, UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t); UL_tti_req->pdus_list[UL_tti_req->n_pdus].pusch_pdu = pusch->pusch_pdu; UL_tti_req->n_pdus+=1; - memset((void *) &UE_list->UE_sched_ctrl[UE_id].sched_pusch[k], + memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pusch[k], 0, sizeof(NR_sched_pusch)); } } @@ -348,10 +348,10 @@ void nr_schedule_pucch(int Mod_idP, uint16_t O_ack; uint8_t SR_flag = 0; // no SR in PUCCH implemented for now NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon; - NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list; - AssertFatal(UE_list->active[UE_id] >=0,"Cannot find UE_id %d is not active\n",UE_id); + NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; + AssertFatal(UE_info->active[UE_id],"Cannot find UE_id %d is not active\n",UE_id); - NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id]; + NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id]; int bwp_id=1; NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1]; nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[Mod_idP]->UL_tti_req[0]; @@ -359,7 +359,7 @@ void nr_schedule_pucch(int Mod_idP, NR_sched_pucch *curr_pucch; for (int k=0; kUE_sched_ctrl[UE_id].sched_pucch[k]; + curr_pucch = &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k]; if ((curr_pucch->dai_c > 0) && (frameP == curr_pucch->frame) && (slotP == curr_pucch->ul_slot)) { UL_tti_req->SFN = curr_pucch->frame; UL_tti_req->Slot = curr_pucch->ul_slot; @@ -381,59 +381,46 @@ void nr_schedule_pucch(int Mod_idP, O_ack, SR_flag); - memset((void *) &UE_list->UE_sched_ctrl[UE_id].sched_pucch[k], + memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k], 0, sizeof(NR_sched_pucch)); } } } - - -bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot){ - - if((bitmap>>slot)&0x01) - return true; - else - return false; +bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot) { + return (bitmap >> slot) & 0x01; } void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame, sub_frame_t slot){ - - protocol_ctxt_t ctxt; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frame, slot,module_idP); - int CC_id; - int UE_id; - uint64_t *dlsch_in_slot_bitmap=NULL; - uint64_t *ulsch_in_slot_bitmap=NULL; - int pucch_sched; - - UE_id=0; - int bwp_id = 1; + const int UE_id = 0; + const int bwp_id = 1; gNB_MAC_INST *gNB = RC.nrmac[module_idP]; - NR_UE_list_t *UE_list = &gNB->UE_list; - NR_UE_sched_ctrl_t *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + NR_UE_info_t *UE_info = &gNB->UE_info; + NR_UE_sched_ctrl_t *ue_sched_ctl = &UE_info->UE_sched_ctrl[UE_id]; NR_COMMON_channels_t *cc = gNB->common_channels; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - int num_slots_per_tdd = (slots_per_frame[*scc->ssbSubcarrierSpacing])>>(7-scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity); - int nr_ulmix_slots = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots; - if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols!=0) - nr_ulmix_slots++; + NR_TDD_UL_DL_Pattern_t *tdd_pattern = &scc->tdd_UL_DL_ConfigurationCommon->pattern1; + const int num_slots_per_tdd = slots_per_frame[*scc->ssbSubcarrierSpacing] >> (7 - tdd_pattern->dl_UL_TransmissionPeriodicity); + const int nr_ulmix_slots = tdd_pattern->nrofUplinkSlots + (tdd_pattern->nrofUplinkSymbols!=0); - if (slot== 0 && (UE_list->fiveG_connected[UE_id] || get_softmodem_params()->phy_test)) { + if (slot == 0 && UE_info->active[UE_id]) { for (int k=0; kUE_sched_ctrl[UE_id].sched_pucch[k], + /* Seems to be covered 384? */ + /*memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k], 0, - sizeof(NR_sched_pucch)); - memset((void *) &UE_list->UE_sched_ctrl[UE_id].sched_pusch[k], + sizeof(NR_sched_pucch));*/ + /* Seems to be covered in line 335? */ + /*memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pusch[k], 0, - sizeof(NR_sched_pusch)); + sizeof(NR_sched_pusch));*/ } } @@ -441,49 +428,28 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_IN); pdcp_run(&ctxt); - //rrc_rx_tx(&ctxt, CC_id); - - dlsch_in_slot_bitmap = &RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[UE_id].dlsch_in_slot_bitmap; // static bitmap signaling which slot in a tdd period contains dlsch - ulsch_in_slot_bitmap = &RC.nrmac[module_idP]->UE_list.UE_sched_ctrl[UE_id].ulsch_in_slot_bitmap; // static bitmap signaling which slot in a tdd period contains ulsch - - // hardcoding dlsch to be in slot 1 - if (!(slot%num_slots_per_tdd)) { - if(slot==0) { - *dlsch_in_slot_bitmap = 0x02; - *ulsch_in_slot_bitmap = 0x100; - } - else { - *dlsch_in_slot_bitmap = 0x00; - *ulsch_in_slot_bitmap = 0x00; - } + /* send tick to RLC and RRC every ms */ + if ((slot & ((1 << *scc->ssbSubcarrierSpacing) - 1)) == 0) { + void nr_rlc_tick(int frame, int subframe); + nr_rlc_tick(frame, slot >> *scc->ssbSubcarrierSpacing); + nr_rrc_trigger(&ctxt, 0 /*CC_id*/, frame, slot >> *scc->ssbSubcarrierSpacing); } + const uint64_t dlsch_in_slot_bitmap = (1 << 1); + const uint64_t ulsch_in_slot_bitmap = (1 << 8); + 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 - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { //mbsfn_status[CC_id] = 0; // clear vrb_maps - memset(cc[CC_id].vrb_map, 0, 100); - memset(cc[CC_id].vrb_map_UL, 0, 100); + memset(cc[CC_id].vrb_map, 0, 275); + memset(cc[CC_id].vrb_map_UL, 0, 275); clear_nr_nfapi_information(RC.nrmac[module_idP], CC_id, frame, slot); } - // refresh UE list based on UEs dropped by PHY in previous subframe - /* - for (i = 0; i < MAX_MOBILES_PER_GNB; i++) { - if (UE_list->active[i]) { - - nfapi_nr_config_request_t *cfg = &RC.nrmac[module_idP]->config[CC_id]; - - rnti = 0;//UE_RNTI(module_idP, i); - CC_id = 0;//UE_PCCID(module_idP, i); - - } //END if (UE_list->active[i]) - } //END for (i = 0; i < MAX_MOBILES_PER_GNB; i++) - */ - if ((slot == 0) && (frame & 127) == 0) dump_mac_stats(RC.nrmac[module_idP]); // This schedules MIB @@ -506,50 +472,44 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, if (get_softmodem_params()->phy_test == 0) { nr_schedule_RA(module_idP, frame, slot); nr_schedule_reception_msg3(module_idP, 0, frame, slot); - } else - UE_list->fiveG_connected[UE_id] = true; - - if (get_softmodem_params()->phy_test) { + } + if (UE_info->active[UE_id]) { // TbD once RACH is available, start ta_timer when UE is connected if (ue_sched_ctl->ta_timer) ue_sched_ctl->ta_timer--; if (ue_sched_ctl->ta_timer == 0) { - gNB->ta_command = ue_sched_ctl->ta_update; + ue_sched_ctl->ta_apply = true; /* if time is up, then set the timer to not send it for 5 frames // regardless of the TA value */ ue_sched_ctl->ta_timer = 100; - /* reset ta_update */ - ue_sched_ctl->ta_update = 31; - /* MAC CE flag indicating TA length */ - gNB->ta_len = 2; } } // This schedules the DCI for Uplink and subsequently PUSCH - if (UE_list->fiveG_connected[UE_id]) { + // The decision about whether to schedule is done for each UE independently + // inside + if (UE_info->active[UE_id] && slot < 10) { int tda = 1; // time domain assignment hardcoded for now - schedule_fapi_ul_pdu(module_idP, frame, slot, num_slots_per_tdd, nr_ulmix_slots, tda); + schedule_fapi_ul_pdu(module_idP, frame, slot, num_slots_per_tdd, nr_ulmix_slots, tda, ulsch_in_slot_bitmap); nr_schedule_pusch(module_idP, UE_id, num_slots_per_tdd, nr_ulmix_slots, frame, slot); } - if (UE_list->fiveG_connected[UE_id] && (is_xlsch_in_slot(*dlsch_in_slot_bitmap,slot%num_slots_per_tdd))) { + if (UE_info->active[UE_id] + && (is_xlsch_in_slot(dlsch_in_slot_bitmap, slot % num_slots_per_tdd)) + && (!get_softmodem_params()->phy_test || slot == 1) + && slot < 10) { ue_sched_ctl->current_harq_pid = slot % num_slots_per_tdd; - nr_update_pucch_scheduling(module_idP, UE_id, frame, slot, num_slots_per_tdd,&pucch_sched); - nr_schedule_uss_dlsch_phytest(module_idP, frame, slot, &UE_list->UE_sched_ctrl[UE_id].sched_pucch[pucch_sched], NULL); - // resetting ta flag - gNB->ta_len = 0; + //int pucch_sched; + //nr_update_pucch_scheduling(module_idP, UE_id, frame, slot, num_slots_per_tdd,&pucch_sched); + //nr_schedule_uss_dlsch_phytest(module_idP, frame, slot, &UE_info->UE_sched_ctrl[UE_id].sched_pucch[pucch_sched], NULL); + nr_schedule_ue_spec(module_idP, frame, slot, num_slots_per_tdd); + ue_sched_ctl->ta_apply = false; } - if (UE_list->fiveG_connected[UE_id]) + if (UE_info->active[UE_id]) nr_schedule_pucch(module_idP, UE_id, nr_ulmix_slots, frame, slot); - /* - // Allocate CCEs for good after scheduling is done - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) - allocate_CCEs(module_idP, CC_id, subframeP, 0); - */ - stop_meas(&RC.nrmac[module_idP]->eNB_scheduler); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_OUT); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 4c17ee3a0f..413727b9cb 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -247,14 +247,11 @@ void nr_initiate_ra_proc(module_id_t module_idP, uint8_t ul_carrier_id = 0; // 0 for NUL 1 for SUL NR_SearchSpace_t *ss; - int UE_id = 0; // ra_rnti from 5.1.3 in 38.321 uint16_t ra_rnti=1+symbol+(slotP*14)+(freq_index*14*80)+(ul_carrier_id*14*80*8); uint16_t msg2_frame, msg2_slot,monitoring_slot_period,monitoring_offset; gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; - NR_UE_list_t *UE_list = &nr_mac->UE_list; - NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id]; NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; NR_RA_t *ra = &cc->ra[0]; @@ -262,23 +259,21 @@ void nr_initiate_ra_proc(module_id_t module_idP, // 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;ipreambles[UE_id].num_preambles;i++) { - if (preamble_index == UE_list->preambles[UE_id].preamble_list[i]) { + for (int i = 0; i < ra->preambles.num_preambles; i++) { + if (preamble_index == ra->preambles.preamble_list[i]) { pr_found=1; break; } } - if (pr_found) - UE_list->fiveG_connected[UE_id] = false; - else { - LOG_E(MAC, "[gNB %d][RAPROC] FAILURE: preamble %d does not correspond to any of the ones in rach_ConfigDedicated for UE_id %d\n", - module_idP, preamble_index, UE_id); + 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=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[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); @@ -325,7 +320,6 @@ void nr_initiate_ra_proc(module_id_t module_idP, ra->RA_rnti = ra_rnti; ra->preamble_index = preamble_index; - UE_list->tc_rnti[UE_id] = ra->rnti; LOG_I(MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x\n", module_idP, @@ -423,7 +417,6 @@ void nr_schedule_reception_msg3(module_id_t module_idP, int CC_id, frame_t frame ul_req->pdus_list[ul_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t); ul_req->pdus_list[ul_req->n_pdus].pusch_pdu = ra->pusch_pdu; ul_req->n_pdus+=1; - ra->state = RA_IDLE; } } } @@ -434,8 +427,6 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; NR_RA_t *ra = &cc->ra[0]; - NR_UE_list_t *UE_list = &mac->UE_list; - int UE_id = 0; if (ra->state == RA_IDLE) { LOG_W(MAC,"RA is not active for RA %X. skipping msg3 scheduling\n", ra->rnti); @@ -447,13 +438,12 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t nfapi_nr_pusch_pdu_t *pusch_pdu = &ra->pusch_pdu; memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t)); - - AssertFatal(UE_list->active[UE_id] >=0,"Cannot find UE_id %d is not active\n", UE_id); - - NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id]; - AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1, - "downlinkBWP_ToAddModList has %d BWP!\n", secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count); - NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1]; + 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_D(MAC, "Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d,%d) for rnti: %d\n", frameP, slotP, @@ -542,17 +532,15 @@ void nr_generate_Msg2(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){ - int UE_id = 0, dci_formats[2], rnti_types[2], mcsIndex; + int dci_formats[2], rnti_types[2], 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[0]; NR_RA_t *ra = &cc->ra[0]; - NR_UE_list_t *UE_list = &nr_mac->UE_list; NR_SearchSpace_t *ss = ra->ra_ss; uint16_t RA_rnti = ra->RA_rnti; long locationAndBandwidth; - // uint8_t *vrb_map = cc[CC_id].vrb_map, CC_id; // check if UE is doing RA on CORESET0 , InitialBWP or configured BWP from SCD // get the BW of the PDCCH for PDCCH size and RAR PDSCH size @@ -597,11 +585,13 @@ void nr_generate_Msg2(module_id_t module_idP, // 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"); - NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id]; - AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1, - "downlinkBWP_ToAddModList has %d BWP!\n", secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count); - NR_BWP_Downlink_t *bwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id - 1]; - NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1]; + 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_Downlink_t *bwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id - 1]; + NR_BWP_Uplink_t *ubwp=ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1]; LOG_D(MAC, "[RAPROC] Scheduling common search space DCI type 1 dlBWP BW %d\n", dci10_bw); @@ -681,7 +671,30 @@ void nr_generate_Msg2(module_id_t module_idP, dci_pdu_rel15[0].mcs, dci_pdu_rel15[0].tb_scaling); - nr_configure_pdcch(nr_mac, pdcch_pdu_rel15, RA_rnti, 0, ss, scc, bwp); + uint8_t nr_of_candidates, aggregation_level; + find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss); + NR_ControlResourceSet_t *coreset = get_coreset(bwp, ss, 0 /* common */); + int CCEIndex = allocate_nr_CCEs( + nr_mac, + bwp, + coreset, + aggregation_level, + 0, /* n_RNTI 0: common search space */ + 0); // m + + if (CCEIndex < 0) { + LOG_E(MAC, "%s(): cannot find free CCE for RA RNTI %04x!\n", __func__, ra->rnti); + return; + } + nr_configure_pdcch(nr_mac, + pdcch_pdu_rel15, + RA_rnti, + ss, + coreset, + scc, + bwp, + aggregation_level, + CCEIndex); LOG_I(MAC, "Frame %d: Subframe %d : Adding common DL DCI for RA_RNTI %x\n", frameP, slotP, RA_rnti); @@ -696,7 +709,7 @@ void nr_generate_Msg2(module_id_t module_idP, pdcch_pdu_rel15->StartSymbolIndex, pdcch_pdu_rel15->DurationSymbols); - fill_dci_pdu_rel15(scc,secondaryCellGroup,pdcch_pdu_rel15, &dci_pdu_rel15[0], dci_formats, rnti_types,dci10_bw,ra->bwp_id); + fill_dci_pdu_rel15(scc,ra->secondaryCellGroup,pdcch_pdu_rel15, &dci_pdu_rel15[0], dci_formats, rnti_types,dci10_bw,ra->bwp_id); dl_req->nPDUs+=2; @@ -719,6 +732,11 @@ void nr_generate_Msg2(module_id_t module_idP, 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); + + /* mark the corresponding RBs as used */ + uint8_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; } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 5fa77c6ca7..989d6fb952 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -82,7 +82,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){ if (mib_sdu_length > 0) { - LOG_I(MAC, "Frame %d, slot %d: Adding BCH PDU in position %d (length %d)\n", frameP, slotP, dl_req->nPDUs, mib_sdu_length); + LOG_D(MAC, "Frame %d, slot %d: Adding BCH PDU in position %d (length %d)\n", frameP, slotP, dl_req->nPDUs, mib_sdu_length); if ((frameP & 1023) < 80){ LOG_I(MAC,"[gNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes\n",module_idP, frameP, CC_id, mib_sdu_length); @@ -137,6 +137,11 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){ dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag = 1; dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload = (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1); dl_req->nPDUs++; + + uint8_t *vrb_map = cc[CC_id].vrb_map; + const int rbStart = dl_config_pdu->ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA; + for (int rb = 0; rb < 20; rb++) + vrb_map[rbStart + rb] = 1; } } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 495095ce9e..ed142a42c8 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -32,6 +32,7 @@ /*PHY*/ #include "PHY/CODING/coding_defs.h" #include "PHY/defs_nr_common.h" +#include "common/utils/nr/nr_common.h" #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h" /*MAC*/ #include "NR_MAC_COMMON/nr_mac.h" @@ -45,6 +46,9 @@ /*TAG*/ #include "NR_TAG-Id.h" +/*Softmodem params*/ +#include "executables/softmodem-common.h" + //////////////////////////////////////////////////////// /////* DLSCH MAC PDU generation (6.1.2 TS 38.321) *///// //////////////////////////////////////////////////////// @@ -54,6 +58,7 @@ //#define SIZE_OF_POINTER sizeof (void *) int nr_generate_dlsch_pdu(module_id_t module_idP, + NR_UE_sched_ctrl_t *ue_sched_ctl, unsigned char *sdus_payload, unsigned char *mac_pdu, unsigned char num_sdus, @@ -70,14 +75,6 @@ int nr_generate_dlsch_pdu(module_id_t module_idP, // MAC CEs uint8_t mac_header_control_elements[16], *ce_ptr; ce_ptr = &mac_header_control_elements[0]; - uint16_t UE_id = 0; //TODO need to get as a function parameter or need to invoke api to UE_id using module Id and RNTI - gNB_MAC_INST *gNB_mac = RC.nrmac[module_idP]; - NR_UE_list_t *UE_list = &gNB_mac->UE_list; - NR_UE_sched_ctrl_t *ue_sched_ctl = NULL; - //NR_CellGroupConfig_t *config = UE_list->secondaryCellGroup[UE_id]; - ue_sched_ctl = &(UE_list->UE_sched_ctrl[UE_id]); - - NR_mac_stats_t *mac_stats = &(UE_list->mac_stats[UE_id]); // 1) Compute MAC CE and related subheaders @@ -94,13 +91,13 @@ int nr_generate_dlsch_pdu(module_id_t module_idP, // now TA is always send when ta_timer resets regardless of its value // this is done to avoid issues with the timeAlignmentTimer which is // supposed to monitor if the UE received TA or not */ - if (gNB->ta_len) { + if (ue_sched_ctl->ta_apply) { mac_pdu_ptr->R = 0; mac_pdu_ptr->LCID = DL_SCH_LCID_TA_COMMAND; //last_size = 1; mac_pdu_ptr++; // TA MAC CE (1 octet) - timing_advance_cmd = gNB->ta_command; + timing_advance_cmd = ue_sched_ctl->ta_update; AssertFatal(timing_advance_cmd < 64, "timing_advance_cmd %d > 63\n", timing_advance_cmd); ((NR_MAC_CE_TA *) ce_ptr)->TA_COMMAND = timing_advance_cmd; //(timing_advance_cmd+31)&0x3f; @@ -329,8 +326,6 @@ int nr_generate_dlsch_pdu(module_id_t module_idP, memcpy((void *) mac_pdu_ptr, (void *) dlsch_buffer_ptr, sdu_lengths[i]); dlsch_buffer_ptr += sdu_lengths[i]; mac_pdu_ptr += sdu_lengths[i]; - - mac_stats->lc_bytes_tx[sdu_lcids[i]] += sdu_lengths[i]; } // 4) Compute final offset for padding @@ -412,6 +407,409 @@ void handle_nr_uci(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl, NR_mac_ UL_info->uci_ind.num_ucis = 0; } -/* functionalities of this function have been moved to nr_schedule_uss_dlsch_phytest */ -void nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) { +int getNrOfSymbols(NR_BWP_Downlink_t *bwp, int tda) { + struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = + bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; + AssertFatal(tda < tdaList->list.count, + "time_domain_allocation %d>=%d\n", + tda, + tdaList->list.count); + + const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength; + int startSymbolIndex, nrOfSymbols; + SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols); + return nrOfSymbols; +} + +nfapi_nr_dmrs_type_e getDmrsConfigType(NR_BWP_Downlink_t *bwp) { + return bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1; +} + +uint8_t getN_PRB_DMRS(NR_BWP_Downlink_t *bwp, int numDmrsCdmGrpsNoData) { + const nfapi_nr_dmrs_type_e dmrsConfigType = getDmrsConfigType(bwp); + if (dmrsConfigType == NFAPI_NR_DMRS_TYPE1) { + // if no data in dmrs cdm group is 1 only even REs have no data + // if no data in dmrs cdm group is 2 both odd and even REs have no data + return numDmrsCdmGrpsNoData * 6; + } else { + return numDmrsCdmGrpsNoData * 4; + } +} + +void nr_simple_dlsch_preprocessor(module_id_t module_id, + frame_t frame, + sub_frame_t slot, + int num_slots_per_tdd) { + NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info; + + AssertFatal(UE_info->num_UEs <= 1, + "%s() cannot handle more than one UE, but found %d\n", + __func__, + UE_info->num_UEs); + if (UE_info->num_UEs == 0) + return; + + const int UE_id = 0; + const int CC_id = 0; + + NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + sched_ctrl->rbSize = 0; + + /* Retrieve amount of data to send for this UE */ + sched_ctrl->num_total_bytes = 0; + const int lcid = DL_SCH_LCID_DTCH; + const uint16_t rnti = UE_info->rnti[UE_id]; + sched_ctrl->rlc_status[lcid] = mac_rlc_status_ind(module_id, + rnti, + module_id, + frame, + slot, + ENB_FLAG_YES, + MBMS_FLAG_NO, + lcid, + 0, + 0); + sched_ctrl->num_total_bytes += sched_ctrl->rlc_status[lcid].bytes_in_buffer; + if (sched_ctrl->num_total_bytes == 0 && !get_softmodem_params()->phy_test) + return; + LOG_D(MAC, + "%d.%d, DTCH%d->DLSCH, RLC status %d bytes\n", + frame, + slot, + lcid, + sched_ctrl->rlc_status[lcid].bytes_in_buffer); + + /* Find a free CCE */ + const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; + sched_ctrl->search_space = get_searchspace(sched_ctrl->active_bwp, target_ss); + uint8_t nr_of_candidates; + find_aggregation_candidates(&sched_ctrl->aggregation_level, + &nr_of_candidates, + sched_ctrl->search_space); + sched_ctrl->coreset = get_coreset( + sched_ctrl->active_bwp, sched_ctrl->search_space, 1 /* dedicated */); + sched_ctrl->cce_index = allocate_nr_CCEs(RC.nrmac[module_id], + sched_ctrl->active_bwp, + sched_ctrl->coreset, + sched_ctrl->aggregation_level, + UE_info->rnti[UE_id], + 0); // m + if (sched_ctrl->cce_index < 0) { + LOG_E(MAC, "%s(): could not find CCE for UE %d\n", __func__, UE_id); + return; + } + + /* Find PUCCH occasion */ + nr_update_pucch_scheduling( + module_id, UE_id, frame, slot, num_slots_per_tdd, &sched_ctrl->pucch_sched_idx); + AssertFatal(sched_ctrl->pucch_sched_idx >= 0, "no uplink slot for PUCCH found!\n"); + + uint8_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map; + const int current_harq_pid = sched_ctrl->current_harq_pid; + NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid]; + NR_UE_ret_info_t *retInfo = &sched_ctrl->retInfo[current_harq_pid]; + const uint16_t bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, 275); + int rbStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, 275); + + if (harq->round != 0) { /* retransmission */ + sched_ctrl->time_domain_allocation = retInfo->time_domain_allocation; + + /* ensure that there is a free place for RB allocation */ + int rbSize = 0; + while (rbSize < retInfo->rbSize) { + rbStart += rbSize; /* last iteration rbSize was not enough, skip it */ + rbSize = 0; + while (rbStart < bwpSize && vrb_map[rbStart]) rbStart++; + if (rbStart >= bwpSize) { + LOG_E(MAC, + "cannot allocate retransmission for UE %d/RNTI %04x: no resources\n", + UE_id, + rnti); + return; + } + while (rbStart + rbSize < bwpSize + && !vrb_map[rbStart + rbSize] + && rbSize < retInfo->rbSize) + rbSize++; + } + sched_ctrl->rbSize = retInfo->rbSize; + sched_ctrl->rbStart = rbStart; + + /* MCS etc: just reuse from previous scheduling opportunity */ + sched_ctrl->mcsTableIdx = retInfo->mcsTableIdx; + sched_ctrl->mcs = retInfo->mcs; + sched_ctrl->numDmrsCdmGrpsNoData = retInfo->numDmrsCdmGrpsNoData; + } else { + // Time-domain allocation + sched_ctrl->time_domain_allocation = 2; + + // modulation scheme + sched_ctrl->mcsTableIdx = 0; + sched_ctrl->mcs = 9; + sched_ctrl->numDmrsCdmGrpsNoData = 1; + + // Freq-demain allocation + while (rbStart < bwpSize && vrb_map[rbStart]) rbStart++; + + uint8_t N_PRB_DMRS = + getN_PRB_DMRS(sched_ctrl->active_bwp, sched_ctrl->numDmrsCdmGrpsNoData); + int nrOfSymbols = getNrOfSymbols(sched_ctrl->active_bwp, + sched_ctrl->time_domain_allocation); + + int rbSize = 0; + uint32_t TBS = 0; + do { + rbSize++; + TBS = nr_compute_tbs(nr_get_Qm_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx), + nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx), + rbSize, + nrOfSymbols, + N_PRB_DMRS, // FIXME // This should be multiplied by the + // number of dmrs symbols + 0 /* N_PRB_oh, 0 for initialBWP */, + 0 /* tb_scaling */, + 1 /* nrOfLayers */) + >> 3; + } while (rbStart + rbSize < bwpSize && !vrb_map[rbStart + rbSize] && TBS < sched_ctrl->num_total_bytes); + sched_ctrl->rbSize = rbSize; + sched_ctrl->rbStart = rbStart; + } + + /* mark the corresponding RBs as used */ + for (int rb = 0; rb < sched_ctrl->rbSize; rb++) + vrb_map[rb + sched_ctrl->rbStart] = 1; +} + +void nr_schedule_ue_spec(module_id_t module_id, + frame_t frame, + sub_frame_t slot, + int num_slots_per_tdd) { + /* PREPROCESSOR */ + nr_simple_dlsch_preprocessor(module_id, frame, slot, num_slots_per_tdd); + + gNB_MAC_INST *gNB_mac = RC.nrmac[module_id]; + NR_UE_info_t *UE_info = &gNB_mac->UE_info; + + const int CC_id = 0; + + NR_UE_list_t *UE_list = &UE_info->list; + for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + if (sched_ctrl->rbSize <= 0 && !get_softmodem_params()->phy_test) + continue; + + const rnti_t rnti = UE_info->rnti[UE_id]; + + /* POST processing */ + struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = + sched_ctrl->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; + AssertFatal(sched_ctrl->time_domain_allocation < tdaList->list.count, + "time_domain_allocation %d>=%d\n", + sched_ctrl->time_domain_allocation, + tdaList->list.count); + + const int startSymbolAndLength = + tdaList->list.array[sched_ctrl->time_domain_allocation]->startSymbolAndLength; + int startSymbolIndex, nrOfSymbols; + SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols); + + uint8_t N_PRB_DMRS = + getN_PRB_DMRS(sched_ctrl->active_bwp, sched_ctrl->numDmrsCdmGrpsNoData); + const uint32_t TBS = + nr_compute_tbs(nr_get_Qm_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx), + nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx), + sched_ctrl->rbSize, + nrOfSymbols, + N_PRB_DMRS, // FIXME // This should be multiplied by the + // number of dmrs symbols + 0 /* N_PRB_oh, 0 for initialBWP */, + 0 /* tb_scaling */, + 1 /* nrOfLayers */) + >> 3; + + const int current_harq_pid = sched_ctrl->current_harq_pid; + NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid]; + NR_sched_pucch *pucch = &sched_ctrl->sched_pucch[sched_ctrl->pucch_sched_idx]; + harq->feedback_slot = pucch->ul_slot; + harq->is_waiting = 1; + UE_info->mac_stats[UE_id].dlsch_rounds[harq->round]++; + + nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body; + nr_fill_nfapi_dl_pdu(module_id, + UE_id, + sched_ctrl->active_bwp->bwp_Id, + sched_ctrl->search_space, + sched_ctrl->coreset, + dl_req, + pucch, + 1 /* nrOfLayers */, + sched_ctrl->mcs, + sched_ctrl->rbSize, + sched_ctrl->rbStart, + sched_ctrl->numDmrsCdmGrpsNoData, + getDmrsConfigType(sched_ctrl->active_bwp), + sched_ctrl->mcsTableIdx, + nr_get_code_rate_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx), + nr_get_Qm_dl(sched_ctrl->mcs, sched_ctrl->mcsTableIdx), + TBS, + sched_ctrl->time_domain_allocation, + startSymbolIndex, + nrOfSymbols, + sched_ctrl->aggregation_level, + sched_ctrl->cce_index, + current_harq_pid, + harq->ndi, + harq->round); + + NR_UE_ret_info_t *retInfo = &sched_ctrl->retInfo[current_harq_pid]; + if (harq->round != 0) { /* retransmission */ + if (sched_ctrl->rbSize != retInfo->rbSize) + LOG_W(MAC, + "retransmission uses different rbSize (%d vs. orig %d)\n", + sched_ctrl->rbSize, + retInfo->rbSize); + if (sched_ctrl->time_domain_allocation != retInfo->time_domain_allocation) + LOG_W(MAC, + "retransmission uses different time_domain_allocation (%d vs. orig %d)\n", + sched_ctrl->time_domain_allocation, + retInfo->time_domain_allocation); + if (sched_ctrl->mcs != retInfo->mcs + || sched_ctrl->mcsTableIdx != retInfo->mcsTableIdx + || sched_ctrl->numDmrsCdmGrpsNoData != retInfo->numDmrsCdmGrpsNoData) + LOG_W(MAC, + "retransmission uses different table/MCS/numDmrsCdmGrpsNoData (%d/%d/%d vs. orig %d/%d/%d)\n", + sched_ctrl->mcsTableIdx, + sched_ctrl->mcs, + sched_ctrl->numDmrsCdmGrpsNoData, + retInfo->mcsTableIdx, + retInfo->mcs, + retInfo->numDmrsCdmGrpsNoData); + /* we do not have to do anything, since we do not require to get data + * from RLC, encode MAC CEs, or copy data to FAPI structures */ + LOG_W(MAC, "%d.%2d retransmission UE %d/RNTI %04x\n", frame, slot, UE_id, rnti); + } else { /* initial transmission */ + + /* reserve space for timing advance of UE if necessary, + * nr_generate_dlsch_pdu() checks for ta_apply and add TA CE if necessary */ + const int ta_len = (sched_ctrl->ta_apply) ? 2 : 0; + + /* Get RLC data TODO: remove random data retrieval */ + int header_length_total = 0; + int header_length_last = 0; + int sdu_length_total = 0; + int num_sdus = 0; + uint16_t sdu_lengths[NB_RB_MAX] = {0}; + uint8_t mac_sdus[MAX_NR_DLSCH_PAYLOAD_BYTES]; + unsigned char sdu_lcids[NB_RB_MAX] = {0}; + const int lcid = DL_SCH_LCID_DTCH; + if (sched_ctrl->num_total_bytes > 0) { + LOG_D(MAC, + "[gNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting " + "%d bytes from RLC (lcid %d total hdr len %d), TBS: %d \n \n", + module_id, + frame, + TBS - ta_len - header_length_total - sdu_length_total - 3, + lcid, + header_length_total, + TBS); + + sdu_lengths[num_sdus] = mac_rlc_data_req(module_id, + rnti, + module_id, + frame, + ENB_FLAG_YES, + MBMS_FLAG_NO, + lcid, + TBS - ta_len - header_length_total - sdu_length_total - 3, + (char *)&mac_sdus[sdu_length_total], + 0, + 0); + + LOG_D(MAC, + "[gNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", + module_id, + sdu_lengths[num_sdus], + lcid); + + sdu_lcids[num_sdus] = lcid; + sdu_length_total += sdu_lengths[num_sdus]; + header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128); + header_length_total += header_length_last; + + num_sdus++; + + //ue_sched_ctl->uplane_inactivity_timer = 0; + } + else if (get_softmodem_params()->phy_test) { + LOG_D(MAC, "Configuring DL_TX in %d.%d: random data\n", frame, slot); + // fill dlsch_buffer with random data + for (int i = 0; i < TBS; i++) + mac_sdus[i] = (unsigned char) (lrand48()&0xff); + sdu_lcids[0] = 0x3f; // DRB + sdu_lengths[0] = TBS - ta_len - 3; + header_length_total += 2 + (sdu_lengths[0] >= 128); + sdu_length_total += sdu_lengths[0]; + num_sdus +=1; + } + + UE_info->mac_stats[UE_id].dlsch_total_bytes += TBS; + UE_info->mac_stats[UE_id].lc_bytes_tx[lcid] += sdu_length_total; + + // Check if there is data from RLC or CE + const int post_padding = TBS >= 2 + header_length_total + sdu_length_total + ta_len; + // padding param currently not in use + //padding = TBS - header_length_total - sdu_length_total - ta_len - 1; + + const int ntx_req = gNB_mac->TX_req[CC_id].Number_of_PDUs; + nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[ntx_req]; + /* pointer to directly generate the PDU into the nFAPI structure */ + uint32_t *buf = tx_req->TLVs[0].value.direct; + + const int offset = nr_generate_dlsch_pdu( + module_id, + sched_ctrl, + (unsigned char *)mac_sdus, + (unsigned char *)buf, + num_sdus, // num_sdus + sdu_lengths, + sdu_lcids, + 255, // no drx + NULL, // contention res id + post_padding); + + // Padding: fill remainder of DLSCH with 0 + if (post_padding > 0) { + for (int j = 0; j < TBS - offset; j++) + buf[offset + j] = 0; + } + + /* the buffer has been filled by nr_generate_dlsch_pdu(), below we simply + * fill the remaining information */ + tx_req->PDU_length = TBS; + tx_req->PDU_index = gNB_mac->pdu_index[0]++; + tx_req->num_TLV = 1; + tx_req->TLVs[0].length = TBS + 2; + gNB_mac->TX_req[CC_id].Number_of_PDUs++; + gNB_mac->TX_req[CC_id].SFN = frame; + gNB_mac->TX_req[CC_id].Slot = slot; + + retInfo->rbSize = sched_ctrl->rbSize; + retInfo->time_domain_allocation = sched_ctrl->time_domain_allocation; + retInfo->mcsTableIdx = sched_ctrl->mcsTableIdx; + retInfo->mcs = sched_ctrl->mcs; + retInfo->numDmrsCdmGrpsNoData = sched_ctrl->numDmrsCdmGrpsNoData; + +#if defined(ENABLE_MAC_PAYLOAD_DEBUG) + if (frame%100 == 0) { + LOG_I(MAC, + "%d.%d, first 10 payload bytes, TBS size: %d \n", + frame, + slot, + TBS); + for(int i = 0; i < 10; i++) + LOG_I(MAC, "byte %d: %x\n", i, ((uint8_t *) buf)[i]); + } +#endif + } + } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index f786db8ba9..90cef0f329 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -252,14 +252,12 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, } } - -int configure_fapi_dl_pdu(int Mod_idP, - nfapi_nr_dl_tti_request_body_t *dl_req, - NR_sched_pucch *pucch_sched, - uint8_t *mcsIndex, - uint16_t *rbSize, - uint16_t *rbStart) { - +int configure_fapi_dl_pdu_phytest(int Mod_idP, + nfapi_nr_dl_tti_request_body_t *dl_req, + NR_sched_pucch *pucch_sched, + uint8_t *mcsIndex, + uint16_t *rbSize, + uint16_t *rbStart) { gNB_MAC_INST *nr_mac = RC.nrmac[Mod_idP]; NR_COMMON_channels_t *cc = nr_mac->common_channels; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; @@ -271,9 +269,9 @@ int configure_fapi_dl_pdu(int Mod_idP, int bwp_id=1; int UE_id = 0; - NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list; + NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; - NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id]; + NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id]; AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1, "downlinkBWP_ToAddModList has %d BWP!\n", secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count); @@ -298,7 +296,7 @@ int configure_fapi_dl_pdu(int Mod_idP, pdsch_pdu_rel15->pduBitmap = 0; - pdsch_pdu_rel15->rnti = UE_list->rnti[UE_id]; + pdsch_pdu_rel15->rnti = UE_info->rnti[UE_id]; pdsch_pdu_rel15->pduIndex = 0; // BWP @@ -310,17 +308,17 @@ int configure_fapi_dl_pdu(int Mod_idP, pdsch_pdu_rel15->NrOfCodewords = 1; int mcs = (mcsIndex!=NULL) ? *mcsIndex : 9; - int current_harq_pid = UE_list->UE_sched_ctrl[UE_id].current_harq_pid; + int current_harq_pid = UE_info->UE_sched_ctrl[UE_id].current_harq_pid; pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(mcs,0); pdsch_pdu_rel15->qamModOrder[0] = 2; pdsch_pdu_rel15->mcsIndex[0] = mcs; pdsch_pdu_rel15->mcsTable[0] = 0; - pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[UE_list->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round]; + pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round]; pdsch_pdu_rel15->dataScramblingId = *scc->physCellId; pdsch_pdu_rel15->nrOfLayers = 1; pdsch_pdu_rel15->transmissionScheme = 0; pdsch_pdu_rel15->refPoint = 0; // Point A - UE_list->mac_stats[UE_id].dlsch_rounds[UE_list->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round]++; + UE_info->mac_stats[UE_id].dlsch_rounds[UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round]++; pdsch_pdu_rel15->dmrsConfigType = bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1; pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId; pdsch_pdu_rel15->SCID = 0; @@ -368,18 +366,18 @@ int configure_fapi_dl_pdu(int Mod_idP, dci_pdu_rel15[0].rv = pdsch_pdu_rel15->rvIndex[0]; // harq pid and ndi dci_pdu_rel15[0].harq_pid = current_harq_pid; - dci_pdu_rel15[0].ndi = UE_list->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].ndi; + dci_pdu_rel15[0].ndi = UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].ndi; // DAI dci_pdu_rel15[0].dai[0].val = (pucch_sched->dai_c-1)&3; // TPC for PUCCH - dci_pdu_rel15[0].tpc = UE_list->UE_sched_ctrl[UE_id].tpc1; // table 7.2.1-1 in 38.213 + dci_pdu_rel15[0].tpc = UE_info->UE_sched_ctrl[UE_id].tpc1; // table 7.2.1-1 in 38.213 // PUCCH resource indicator dci_pdu_rel15[0].pucch_resource_indicator = pucch_sched->resource_indicator; // PDSCH to HARQ TI dci_pdu_rel15[0].pdsch_to_harq_feedback_timing_indicator.val = pucch_sched->timing_indicator; - UE_list->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].feedback_slot = pucch_sched->ul_slot; - UE_list->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].is_waiting = 1; + UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].feedback_slot = pucch_sched->ul_slot; + UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].is_waiting = 1; // antenna ports dci_pdu_rel15[0].antenna_ports.val = 0; // nb of cdm groups w/o data 1 and dmrs port 0 // dmrs sequence initialization @@ -416,18 +414,30 @@ int configure_fapi_dl_pdu(int Mod_idP, } AssertFatal(found==1,"Couldn't find an adequate searchspace\n"); - int ret = nr_configure_pdcch(nr_mac, - pdcch_pdu_rel15, - UE_list->rnti[UE_id], - 1, // ue-specific - ss, - scc, - bwp); - if (ret < 0) { - LOG_I(MAC,"CCE list not empty, couldn't schedule PDSCH\n"); - free(dci_pdu_rel15); - return (0); + uint8_t nr_of_candidates, aggregation_level; + find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss); + NR_ControlResourceSet_t *coreset = get_coreset(bwp, ss, 1 /* dedicated */); + int CCEIndex = allocate_nr_CCEs( + nr_mac, + bwp, + coreset, + aggregation_level, + UE_info->rnti[UE_id], + 0); // m + if (CCEIndex < 0) { + LOG_E(MAC, "%s(): CCE list not empty, couldn't schedule PDSCH\n", __func__); + free(dci_pdu_rel15); + return 0; } + nr_configure_pdcch(nr_mac, + pdcch_pdu_rel15, + UE_info->rnti[UE_id], + ss, + coreset, + scc, + bwp, + aggregation_level, + CCEIndex); int dci_formats[2]; int rnti_types[2]; @@ -455,8 +465,8 @@ int configure_fapi_dl_pdu(int Mod_idP, // Hardcode it for now TBS = dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15.TBSize[0]; - if (UE_list->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round==0) - UE_list->mac_stats[UE_id].dlsch_total_bytes += TBS; + if (UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid].round==0) + UE_info->mac_stats[UE_id].dlsch_total_bytes += TBS; LOG_D(MAC, "DLSCH PDU: start PRB %d n_PRB %d startSymbolAndLength %d start symbol %d nb_symbols %d nb_layers %d nb_codewords %d mcs %d TBS: %d\n", pdsch_pdu_rel15->rbStart, @@ -581,7 +591,7 @@ void configure_fapi_dl_Tx(module_id_t Mod_idP, tx_req->num_TLV = 1; tx_req->TLVs[0].length = tbs_bytes +2; - memcpy((void*)&tx_req->TLVs[0].value.direct[0], (void*)&nr_mac->UE_list.DLSCH_pdu[0][0].payload[0], tbs_bytes); + memcpy((void*)&tx_req->TLVs[0].value.direct[0], (void*)&nr_mac->UE_info.DLSCH_pdu[0][0].payload[0], tbs_bytes); nr_mac->TX_req[CC_id].Number_of_PDUs++; nr_mac->TX_req[CC_id].SFN = frameP; @@ -596,7 +606,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, LOG_D(MAC, "In nr_schedule_uss_dlsch_phytest frame %d slot %d\n",frameP,slotP); - int post_padding = 0, ta_len = 0, header_length_total = 0, sdu_length_total = 0, num_sdus = 0; + int post_padding = 0, header_length_total = 0, sdu_length_total = 0, num_sdus = 0; int lcid, offset, i, header_length_last, TBS_bytes = 0; int UE_id = 0, CC_id = 0; @@ -608,26 +618,28 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, mac_rlc_status_resp_t rlc_status; - NR_UE_list_t *UE_list = &gNB_mac->UE_list; + NR_UE_info_t *UE_info = &gNB_mac->UE_info; - if (UE_list->num_UEs ==0) return; + if (UE_info->num_UEs ==0) return; unsigned char sdu_lcids[NB_RB_MAX] = {0}; uint16_t sdu_lengths[NB_RB_MAX] = {0}; - uint16_t rnti = UE_list->rnti[UE_id]; + uint16_t rnti = UE_info->rnti[UE_id]; + NR_UE_sched_ctrl_t *ue_sched_ctl = &UE_info->UE_sched_ctrl[UE_id]; uint8_t mac_sdus[MAX_NR_DLSCH_PAYLOAD_BYTES]; LOG_D(MAC, "Scheduling UE specific search space DCI type 1\n"); - ta_len = gNB_mac->ta_len; + int ta_len = (ue_sched_ctl->ta_apply)?2:0; - TBS_bytes = configure_fapi_dl_pdu(module_idP, - dl_req, - pucch_sched, - dlsch_config!=NULL ? dlsch_config->mcsIndex : NULL, - dlsch_config!=NULL ? &dlsch_config->rbSize : NULL, - dlsch_config!=NULL ? &dlsch_config->rbStart : NULL); + TBS_bytes = configure_fapi_dl_pdu_phytest( + module_idP, + dl_req, + pucch_sched, + dlsch_config != NULL ? dlsch_config->mcsIndex : NULL, + dlsch_config != NULL ? &dlsch_config->rbSize : NULL, + dlsch_config != NULL ? &dlsch_config->rbStart : NULL); if (TBS_bytes == 0) return; @@ -692,7 +704,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, // fill dlsch_buffer with random data for (i = 0; i < TBS_bytes; i++){ mac_sdus[i] = (unsigned char) (lrand48()&0xff); - //((uint8_t *)gNB_mac->UE_list.DLSCH_pdu[0][0].payload[0])[i] = (unsigned char) (lrand48()&0xff); + //((uint8_t *)gNB_mac->UE_info.DLSCH_pdu[0][0].payload[0])[i] = (unsigned char) (lrand48()&0xff); } //Sending SDUs with size 1 //Initialize elements of sdu_lcids and sdu_lengths @@ -706,13 +718,15 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, if (frameP%100 == 0){ LOG_I(MAC, "Printing first 10 payload bytes at the gNB side, Frame: %d, slot: %d, TBS size: %d \n", frameP, slotP, TBS_bytes); for(int i = 0; i < 10; i++) { - LOG_I(MAC, "%x. ", ((uint8_t *)gNB_mac->UE_list.DLSCH_pdu[CC_id][0][0].payload[0])[i]); + LOG_I(MAC, "%x. ", ((uint8_t *)gNB_mac->UE_info.DLSCH_pdu[CC_id][0][0].payload[0])[i]); } } #endif } + UE_info->mac_stats[UE_id].lc_bytes_tx[lcid] += sdu_length_total; + // there is at least one SDU or TA command // if (num_sdus > 0 ){ if (ta_len + sdu_length_total + header_length_total > 0) { @@ -729,8 +743,9 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, } offset = nr_generate_dlsch_pdu(module_idP, + &UE_info->UE_sched_ctrl[UE_id], (unsigned char *) mac_sdus, - (unsigned char *) gNB_mac->UE_list.DLSCH_pdu[0][0].payload[0], + (unsigned char *) gNB_mac->UE_info.DLSCH_pdu[0][0].payload[0], num_sdus, //num_sdus sdu_lengths, sdu_lcids, @@ -741,7 +756,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, // Padding: fill remainder of DLSCH with 0 if (post_padding > 0){ for (int j = 0; j < (TBS_bytes - offset); j++) - gNB_mac->UE_list.DLSCH_pdu[0][0].payload[0][offset + j] = 0; // mac_pdu[offset + j] = 0; + gNB_mac->UE_info.DLSCH_pdu[0][0].payload[0][offset + j] = 0; // mac_pdu[offset + j] = 0; } configure_fapi_dl_Tx(module_idP, frameP, slotP, dl_req, tx_req, TBS_bytes, gNB_mac->pdu_index[CC_id]); @@ -758,7 +773,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, if (frameP%100 == 0){ LOG_I(MAC, "Printing first 10 payload bytes at the gNB side, Frame: %d, slot: %d, TBS size: %d \n", frameP, slotP, TBS_bytes); for(int i = 0; i < 10; i++) { - LOG_I(MAC, "byte %d : %x\n", i,((uint8_t *)gNB_mac->UE_list.DLSCH_pdu[0][0].payload[0])[i]); //LOG_I(MAC, "%x. ", mac_payload[i]); + LOG_I(MAC, "byte %d : %x\n", i,((uint8_t *)gNB_mac->UE_info.DLSCH_pdu[0][0].payload[0])[i]); //LOG_I(MAC, "%x. ", mac_payload[i]); } } #endif @@ -799,12 +814,26 @@ int8_t select_ul_harq_pid(NR_UE_sched_ctrl_t *sched_ctrl) { return -1; } +long get_K2(NR_BWP_Uplink_t *ubwp, int time_domain_assignment, int mu) { + DevAssert(ubwp); + const NR_PUSCH_TimeDomainResourceAllocation_t *tda_list = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]; + if (tda_list->k2) + return *tda_list->k2; + else if (mu < 2) + return 1; + else if (mu == 2) + return 2; + else + return 3; +} + void schedule_fapi_ul_pdu(int Mod_idP, frame_t frameP, sub_frame_t slotP, int num_slots_per_tdd, int ul_slots, - int time_domain_assignment) { + int time_domain_assignment, + uint64_t ulsch_in_slot_bitmap) { gNB_MAC_INST *nr_mac = RC.nrmac[Mod_idP]; NR_COMMON_channels_t *cc = nr_mac->common_channels; @@ -813,10 +842,10 @@ void schedule_fapi_ul_pdu(int Mod_idP, int bwp_id=1; int mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing; int UE_id = 0; - NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list; - AssertFatal(UE_list->active[UE_id] >=0,"Cannot find UE_id %d is not active\n",UE_id); + NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; + AssertFatal(UE_info->active[UE_id],"Cannot find UE_id %d is not active\n",UE_id); - NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id]; + NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id]; AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1, "downlinkBWP_ToAddModList has %d BWP!\n", secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count); @@ -828,18 +857,14 @@ void schedule_fapi_ul_pdu(int Mod_idP, AssertFatal(time_domain_assignmentbwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.count, "time_domain_assignment %d>=%d\n",time_domain_assignment,ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.count); - int K2; - if (ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]->k2 != NULL) - K2 = *ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]->k2; - else { - if (mu<2) K2=1; - else if(mu==2) K2=2; - else K2=3; - } - - if (is_xlsch_in_slot(UE_list->UE_sched_ctrl[UE_id].ulsch_in_slot_bitmap,(slotP+K2)%num_slots_per_tdd)) { - - //nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[Mod_idP]->UL_tti_req[0]; + int K2 = get_K2(ubwp, time_domain_assignment,mu); + /* check if slot is UL, and for phy test verify that it is in first TDD + * period, slot 8 (for K2=2, this is at slot 6 in the gNB; because of UE + * limitations). Note that if K2 or the TDD configuration is changed, below + * conditions might exclude each other and never be true */ + const int slot_idx = (slotP + K2) % num_slots_per_tdd; + if (is_xlsch_in_slot(ulsch_in_slot_bitmap, slot_idx) + && (!get_softmodem_params()->phy_test || slotP == 6)) { nfapi_nr_ul_dci_request_t *UL_dci_req = &RC.nrmac[Mod_idP]->UL_dci_req[0]; UL_dci_req->SFN = frameP; UL_dci_req->Slot = slotP; @@ -849,10 +874,10 @@ void schedule_fapi_ul_pdu(int Mod_idP, AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0, "searchPsacesToAddModList is empty\n"); - uint16_t rnti = UE_list->rnti[UE_id]; + uint16_t rnti = UE_info->rnti[UE_id]; int first_ul_slot = num_slots_per_tdd - ul_slots; - NR_sched_pusch *pusch_sched = &UE_list->UE_sched_ctrl[UE_id].sched_pusch[slotP+K2-first_ul_slot]; + NR_sched_pusch *pusch_sched = &UE_info->UE_sched_ctrl[UE_id].sched_pusch[slotP+K2-first_ul_slot]; pusch_sched->frame = frameP; pusch_sched->slot = slotP + K2; pusch_sched->active = true; @@ -862,6 +887,36 @@ void schedule_fapi_ul_pdu(int Mod_idP, LOG_D(MAC, "Scheduling UE specific PUSCH\n"); //UL_tti_req = &nr_mac->UL_tti_req[CC_id]; + int dci_formats[2]; + int rnti_types[2]; + + NR_SearchSpace_t *ss; + int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; + + AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n"); + AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0, + "searchPsacesToAddModList is empty\n"); + + int found=0; + + for (int i=0;ibwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count;i++) { + ss=bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i]; + AssertFatal(ss->controlResourceSetId != NULL,"ss->controlResourceSetId is null\n"); + AssertFatal(ss->searchSpaceType != NULL,"ss->searchSpaceType is null\n"); + if (ss->searchSpaceType->present == target_ss) { + found=1; + break; + } + } + AssertFatal(found==1,"Couldn't find an adequate searchspace\n"); + + if (ss->searchSpaceType->choice.ue_Specific->dci_Formats) + dci_formats[0] = NR_UL_DCI_FORMAT_0_1; + else + dci_formats[0] = NR_UL_DCI_FORMAT_0_0; + + rnti_types[0] = NR_RNTI_C; + //Resource Allocation in time domain int startSymbolAndLength=0; int StartSymbolIndex,NrOfSymbols,mapping_type; @@ -881,12 +936,7 @@ void schedule_fapi_ul_pdu(int Mod_idP, pusch_pdu->bwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275); pusch_pdu->subcarrier_spacing = ubwp->bwp_Common->genericParameters.subcarrierSpacing; pusch_pdu->cyclic_prefix = 0; - //pusch information always include - //this informantion seems to be redundant. with hthe mcs_index and the modulation table, the mod_order and target_code_rate can be determined. - pusch_pdu->mcs_index = 9; - pusch_pdu->mcs_table = 0; //0: notqam256 [TS38.214, table 5.1.3.1-1] - corresponds to nr_target_code_rate_table1 in PHY - pusch_pdu->target_code_rate = nr_get_code_rate_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table) ; - pusch_pdu->qam_mod_order = nr_get_Qm_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table) ; + if (pusch_Config->transformPrecoder == NULL) { if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL) pusch_pdu->transform_precoding = 1; @@ -900,6 +950,23 @@ void schedule_fapi_ul_pdu(int Mod_idP, else pusch_pdu->data_scrambling_id = *scc->physCellId; + pusch_pdu->mcs_index = 9; + if (pusch_pdu->transform_precoding) + pusch_pdu->mcs_table = get_pusch_mcs_table(pusch_Config->mcs_Table, 0, + dci_formats[0], rnti_types[0], target_ss, false); + else + pusch_pdu->mcs_table = get_pusch_mcs_table(pusch_Config->mcs_TableTransformPrecoder, 1, + dci_formats[0], rnti_types[0], target_ss, false); + + pusch_pdu->target_code_rate = nr_get_code_rate_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table); + pusch_pdu->qam_mod_order = nr_get_Qm_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table); + if (pusch_Config->tp_pi2BPSK!=NULL) { + if(((pusch_pdu->mcs_table==3)&&(pusch_pdu->mcs_index<2)) || + ((pusch_pdu->mcs_table==4)&&(pusch_pdu->mcs_index<6))) { + pusch_pdu->target_code_rate = pusch_pdu->target_code_rate>>1; + pusch_pdu->qam_mod_order = pusch_pdu->qam_mod_order<<1; + } + } pusch_pdu->nrOfLayers = 1; //Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2] @@ -1002,9 +1069,9 @@ void schedule_fapi_ul_pdu(int Mod_idP, //Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2] //Optional Data only included if indicated in pduBitmap - int8_t harq_id = select_ul_harq_pid(&UE_list->UE_sched_ctrl[UE_id]); + int8_t harq_id = select_ul_harq_pid(&UE_info->UE_sched_ctrl[UE_id]); if (harq_id < 0) return; - NR_UE_ul_harq_t *cur_harq = &UE_list->UE_sched_ctrl[UE_id].ul_harq_processes[harq_id]; + NR_UE_ul_harq_t *cur_harq = &UE_info->UE_sched_ctrl[UE_id].ul_harq_processes[harq_id]; pusch_pdu->pusch_data.harq_process_id = harq_id; pusch_pdu->pusch_data.new_data_indicator = cur_harq->ndi; pusch_pdu->pusch_data.rv_index = nr_rv_round_map[cur_harq->round]; @@ -1034,8 +1101,8 @@ void schedule_fapi_ul_pdu(int Mod_idP, 0, pusch_pdu->nrOfLayers)>>3; - UE_list->mac_stats[UE_id].ulsch_rounds[cur_harq->round]++; - if (cur_harq->round == 0) UE_list->mac_stats[UE_id].ulsch_total_bytes_scheduled+=pusch_pdu->pusch_data.tb_size; + UE_info->mac_stats[UE_id].ulsch_rounds[cur_harq->round]++; + if (cur_harq->round == 0) UE_info->mac_stats[UE_id].ulsch_total_bytes_scheduled+=pusch_pdu->pusch_data.tb_size; pusch_pdu->pusch_data.num_cb = 0; //CBG not supported //pusch_pdu->pusch_data.cb_present_and_position; @@ -1053,53 +1120,37 @@ void schedule_fapi_ul_pdu(int Mod_idP, nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15; UL_dci_req->numPdus+=1; - int dci_formats[2]; - int rnti_types[2]; - NR_SearchSpace_t *ss; - int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; - - AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n"); - AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0, - "searchPsacesToAddModList is empty\n"); - - int found=0; - - for (int i=0;ibwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count;i++) { - ss=bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i]; - AssertFatal(ss->controlResourceSetId != NULL,"ss->controlResourceSetId is null\n"); - AssertFatal(ss->searchSpaceType != NULL,"ss->searchSpaceType is null\n"); - if (ss->searchSpaceType->present == target_ss) { - found=1; - break; - } - } - AssertFatal(found==1,"Couldn't find an adequate searchspace\n"); - - if (ss->searchSpaceType->choice.ue_Specific->dci_Formats) - dci_formats[0] = NR_UL_DCI_FORMAT_0_1; - else - dci_formats[0] = NR_UL_DCI_FORMAT_0_0; - - rnti_types[0] = NR_RNTI_C; LOG_D(MAC,"Configuring ULDCI/PDCCH in %d.%d\n", frameP,slotP); - int ret = nr_configure_pdcch(nr_mac, - pdcch_pdu_rel15, - UE_list->rnti[UE_id], - 1, // ue-specific, - ss, - scc, - bwp); - - if (ret < 0) { - LOG_I(MAC,"CCE list not empty, couldn't schedule PUSCH\n"); + uint8_t nr_of_candidates, aggregation_level; + find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss); + NR_ControlResourceSet_t *coreset = get_coreset(bwp, ss, 1 /* dedicated */); + int CCEIndex = allocate_nr_CCEs( + nr_mac, + bwp, + coreset, + aggregation_level, + UE_info->rnti[UE_id], + 0); // m + if (CCEIndex < 0) { + LOG_E(MAC, "%s(): CCE list not empty, couldn't schedule PUSCH\n", __func__); pusch_sched->active = false; return; } else { + nr_configure_pdcch(nr_mac, + pdcch_pdu_rel15, + UE_info->rnti[UE_id], + ss, + coreset, + scc, + bwp, + aggregation_level, + CCEIndex); + dci_pdu_rel15_t *dci_pdu_rel15 = calloc(MAX_DCI_CORESET,sizeof(dci_pdu_rel15_t)); - config_uldci(ubwp,pusch_pdu,pdcch_pdu_rel15,&dci_pdu_rel15[0],dci_formats,rnti_types,time_domain_assignment,UE_list->UE_sched_ctrl[UE_id].tpc0,n_ubwp,bwp_id); + config_uldci(ubwp,pusch_pdu,pdcch_pdu_rel15,&dci_pdu_rel15[0],dci_formats,rnti_types,time_domain_assignment,UE_info->UE_sched_ctrl[UE_id].tpc0,n_ubwp,bwp_id); fill_dci_pdu_rel15(scc,secondaryCellGroup,pdcch_pdu_rel15,dci_pdu_rel15,dci_formats,rnti_types,pusch_pdu->bwp_size,bwp_id); free(dci_pdu_rel15); } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index f4ec142da1..d2f9582517 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -63,7 +63,6 @@ #define ENABLE_MAC_PAYLOAD_DEBUG #define DEBUG_gNB_SCHEDULER 1 - #include "common/ran_context.h" extern RAN_CONTEXT_t RC; @@ -127,37 +126,60 @@ static inline uint8_t get_max_cces(uint8_t scs) { return (nr_max_number_of_cces_per_slot[scs]); } +NR_ControlResourceSet_t *get_coreset(NR_BWP_Downlink_t *bwp, + NR_SearchSpace_t *ss, + int ss_type) { + NR_ControlResourceSetId_t coreset_id = *ss->controlResourceSetId; + if (ss_type == 0) { // common search space + AssertFatal(coreset_id != 0, "coreset0 currently not supported\n"); + NR_ControlResourceSet_t *coreset = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet; + AssertFatal(coreset_id == coreset->controlResourceSetId, + "ID of common ss coreset does not correspond to id set in the " + "search space\n"); + return coreset; + } else { + const int n = bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.count; + for (int i = 0; i < n; i++) { + NR_ControlResourceSet_t *coreset = + bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[i]; + if (coreset_id == coreset->controlResourceSetId) { + return coreset; + } + } + AssertFatal(0, "Couldn't find coreset with id %ld\n", coreset_id); + } +} + +NR_SearchSpace_t *get_searchspace( + NR_BWP_Downlink_t *bwp, + NR_SearchSpace__searchSpaceType_PR target_ss) { + DevAssert(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList); + DevAssert(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count > 0); + + const int n = bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count; + for (int i=0;ibwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i]; + AssertFatal(ss->controlResourceSetId != NULL, "ss->controlResourceSetId is null\n"); + AssertFatal(ss->searchSpaceType != NULL, "ss->searchSpaceType is null\n"); + if (ss->searchSpaceType->present == target_ss) { + return ss; + } + } + AssertFatal(0, "Couldn't find an adequate searchspace\n"); +} + int allocate_nr_CCEs(gNB_MAC_INST *nr_mac, - int bwp_id, - int list_id, - int aggregation, - int search_space, // 0 common, 1 ue-specific - int UE_id, - int m) { + NR_BWP_Downlink_t *bwp, + NR_ControlResourceSet_t *coreset, + int aggregation, + uint16_t n_RNTI, + int m) { // uncomment these when we allocate for common search space // NR_COMMON_channels_t *cc = nr_mac->common_channels; // NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - NR_UE_list_t *UE_list = &nr_mac->UE_list; - - NR_BWP_Downlink_t *bwp; - NR_CellGroupConfig_t *secondaryCellGroup; - - NR_ControlResourceSet_t *coreset; - - AssertFatal(UE_list->active[UE_id] >=0,"UE_id %d is not active\n",UE_id); - secondaryCellGroup = UE_list->secondaryCellGroup[UE_id]; - bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]; - - if (search_space == 1) { - coreset = bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[list_id]; - } - else { - coreset = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet; - } - int coreset_id = coreset->controlResourceSetId; - int *cce_list = nr_mac->cce_list[bwp_id][coreset_id]; + int *cce_list = nr_mac->cce_list[bwp->bwp_Id][coreset_id]; int n_rb=0; for (int i=0;i<6;i++) @@ -167,17 +189,14 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac, n_rb*=6; uint16_t N_reg = n_rb * coreset->duration; - uint16_t Y=0, N_cce, M_s_max, n_CI=0; - uint16_t n_RNTI = search_space == 1 ? UE_list->rnti[UE_id]:0; - uint32_t A[3]={39827,39829,39839}; + uint16_t n_CI=0; + const uint32_t A[3]={39827,39829,39839}; + /* if n_RNTI is zero, this results in zero, too! */ + uint16_t Y = (A[0]*n_RNTI)%65537; // Candidate 0, antenna port 0 - N_cce = N_reg / NR_NB_REG_PER_CCE; + uint16_t N_cce = N_reg / NR_NB_REG_PER_CCE; - M_s_max = (aggregation==4)?4:(aggregation==8)?2:1; - - if (search_space == 1) { - Y = (A[0]*n_RNTI)%65537; // Candidate 0, antenna port 0 - } + uint16_t M_s_max = (aggregation==4)?4:(aggregation==8)?2:1; int first_cce = aggregation * (( Y + (m*N_cce)/(aggregation*M_s_max) + n_CI ) % CEILIDIV(N_cce,aggregation)); for (int i=0;icommon_channels; + NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - int CCEIndex = -1; - int cid = 0; - NR_ControlResourceSet_t *coreset = NULL; + NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; + NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id]; + AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1, + "downlinkBWP_ToAddModList has %d BWP!\n", + secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count); + NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]; + + AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n"); + AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0, + "searchPsacesToAddModList is empty\n"); + + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; + memset((void*)dl_tti_pdcch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t)); + dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE; + dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu)); + + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->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)); + + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15; + + + pdsch_pdu_rel15->pduBitmap = 0; + pdsch_pdu_rel15->rnti = UE_info->rnti[UE_id]; + pdsch_pdu_rel15->pduIndex = nr_mac->pdu_index[0]++; + + // BWP + pdsch_pdu_rel15->BWPSize = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275); + pdsch_pdu_rel15->BWPStart = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth,275); + pdsch_pdu_rel15->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing; + if (bwp->bwp_Common->genericParameters.cyclicPrefix) + pdsch_pdu_rel15->CyclicPrefix = *bwp->bwp_Common->genericParameters.cyclicPrefix; + else + pdsch_pdu_rel15->CyclicPrefix = 0; + + pdsch_pdu_rel15->NrOfCodewords = 1; + pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(mcs,0); + pdsch_pdu_rel15->qamModOrder[0] = 2; + pdsch_pdu_rel15->mcsIndex[0] = mcs; + pdsch_pdu_rel15->mcsTable[0] = 0; + pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[round]; + pdsch_pdu_rel15->dataScramblingId = *scc->physCellId; + pdsch_pdu_rel15->nrOfLayers = nrOfLayers; + pdsch_pdu_rel15->transmissionScheme = 0; + pdsch_pdu_rel15->refPoint = 0; // Point A + pdsch_pdu_rel15->dmrsConfigType = dmrsConfigType; + pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId; + pdsch_pdu_rel15->SCID = 0; + pdsch_pdu_rel15->numDmrsCdmGrpsNoData = numDmrsCdmGrpsNoData; + pdsch_pdu_rel15->dmrsPorts = 1; + pdsch_pdu_rel15->resourceAlloc = 1; + pdsch_pdu_rel15->rbStart = rbStart; + pdsch_pdu_rel15->rbSize = rbSize; + pdsch_pdu_rel15->VRBtoPRBMapping = 1; // non-interleaved, check if this is ok for initialBWP + pdsch_pdu_rel15->targetCodeRate[0] = R; + pdsch_pdu_rel15->qamModOrder[0] = Qm; + pdsch_pdu_rel15->TBSize[0] = TBS; + pdsch_pdu_rel15->mcsTable[0] = table_idx; + pdsch_pdu_rel15->StartSymbolIndex = StartSymbolIndex; + pdsch_pdu_rel15->NrOfSymbols = NrOfSymbols; + + // k0 = *bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->k0; + pdsch_pdu_rel15->dlDmrsSymbPos = + fill_dmrs_mask(bwp->bwp_Dedicated->pdsch_Config->choice.setup, + scc->dmrs_TypeA_Position, + pdsch_pdu_rel15->NrOfSymbols); + + dci_pdu_rel15_t dci_pdu_rel15[MAX_DCI_CORESET]; + memset(dci_pdu_rel15, 0, sizeof(dci_pdu_rel15_t) * MAX_DCI_CORESET); + + // bwp indicator + int n_dl_bwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count; + if (n_dl_bwp < 4) + dci_pdu_rel15[0].bwp_indicator.val = bwp_id; + else + dci_pdu_rel15[0].bwp_indicator.val = bwp_id - 1; // as per table 7.3.1.1.2-1 in 38.212 + // frequency domain assignment + if (bwp->bwp_Dedicated->pdsch_Config->choice.setup->resourceAllocation==NR_PDSCH_Config__resourceAllocation_resourceAllocationType1) + dci_pdu_rel15[0].frequency_domain_assignment.val = + PRBalloc_to_locationandbandwidth0( + pdsch_pdu_rel15->rbSize, + pdsch_pdu_rel15->rbStart, + NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth, + 275)); + else + AssertFatal(1==0,"Only frequency resource allocation type 1 is currently supported\n"); + // time domain assignment + dci_pdu_rel15[0].time_domain_assignment.val = time_domain_assignment; // row index used here instead of SLIV; + // mcs and rv + dci_pdu_rel15[0].mcs = mcs; + dci_pdu_rel15[0].rv = pdsch_pdu_rel15->rvIndex[0]; + // harq pid and ndi + dci_pdu_rel15[0].harq_pid = harq_pid; + dci_pdu_rel15[0].ndi = ndi; + // DAI + dci_pdu_rel15[0].dai[0].val = (pucch_sched->dai_c-1)&3; + + // TPC for PUCCH + dci_pdu_rel15[0].tpc = UE_info->UE_sched_ctrl[UE_id].tpc1; // table 7.2.1-1 in 38.213 + // PUCCH resource indicator + dci_pdu_rel15[0].pucch_resource_indicator = pucch_sched->resource_indicator; + // PDSCH to HARQ TI + dci_pdu_rel15[0].pdsch_to_harq_feedback_timing_indicator.val = pucch_sched->timing_indicator; + // antenna ports + dci_pdu_rel15[0].antenna_ports.val = 0; // nb of cdm groups w/o data 1 and dmrs port 0 + // dmrs sequence initialization + dci_pdu_rel15[0].dmrs_sequence_initialization.val = pdsch_pdu_rel15->SCID; + LOG_D(MAC, + "[gNB scheduler phytest] DCI type 1 payload: freq_alloc %d (%d,%d,%d), " + "time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d\n", + dci_pdu_rel15[0].frequency_domain_assignment.val, + pdsch_pdu_rel15->rbStart, + pdsch_pdu_rel15->rbSize, + NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth, 275), + dci_pdu_rel15[0].time_domain_assignment.val, + dci_pdu_rel15[0].vrb_to_prb_mapping.val, + dci_pdu_rel15[0].mcs, + dci_pdu_rel15[0].tb_scaling, + dci_pdu_rel15[0].ndi, + dci_pdu_rel15[0].rv); + + nr_configure_pdcch(nr_mac, + pdcch_pdu_rel15, + UE_info->rnti[UE_id], + ss, + coreset, + scc, + bwp, + aggregation_level, + CCEIndex); + + int dci_formats[2]; + int rnti_types[2]; + + if (ss->searchSpaceType->choice.ue_Specific->dci_Formats) + dci_formats[0] = NR_DL_DCI_FORMAT_1_1; + else + dci_formats[0] = NR_DL_DCI_FORMAT_1_0; + + rnti_types[0] = NR_RNTI_C; + + fill_dci_pdu_rel15(scc,secondaryCellGroup,pdcch_pdu_rel15,dci_pdu_rel15,dci_formats,rnti_types,pdsch_pdu_rel15->BWPSize,bwp_id); + + LOG_D(MAC, + "DCI params: rnti %x, rnti_type %d, dci_format %d\n", + pdcch_pdu_rel15->dci_pdu.RNTI[0], + rnti_types[0], + dci_formats[0]); + LOG_D(MAC, + "coreset params: FreqDomainResource %llx, start_symbol %d n_symb %d\n", + (unsigned long long)pdcch_pdu_rel15->FreqDomainResource, + pdcch_pdu_rel15->StartSymbolIndex, + pdcch_pdu_rel15->DurationSymbols); + + // I don't know why the following is not needed, but in this case we don't + // need additional calculations: + //const uint16_t N_RE_prime = NR_NB_SC_PER_RB * N_sh_symb - N_PRB_DMRS - N_PRB_oh; + //LOG_D(MAC, + // "N_RE_prime %d for %d symbols %d DMRS per PRB and %d overhead\n", + // N_RE_prime, + // N_sh_symb, + // N_PRB_DMRS, + // N_PRB_oh); + //pdsch_pdu_rel15->nb_mod_symbols = N_RE_prime*pdsch_pdu_rel15->n_prb*pdsch_pdu_rel15->nb_codewords; + + LOG_D(MAC, + "DLSCH PDU: start PRB %d n_PRB %d start symbol %d nb_symbols %d " + "nb_layers %d nb_codewords %d mcs %d TBS: %d\n", + pdsch_pdu_rel15->rbStart, + pdsch_pdu_rel15->rbSize, + pdsch_pdu_rel15->StartSymbolIndex, + pdsch_pdu_rel15->NrOfSymbols, + pdsch_pdu_rel15->nrOfLayers, + pdsch_pdu_rel15->NrOfCodewords, + pdsch_pdu_rel15->mcsIndex[0], + TBS); + + dl_req->nPDUs += 2; +} + +void nr_configure_pdcch(gNB_MAC_INST *nr_mac, + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, + uint16_t rnti, + NR_SearchSpace_t *ss, + NR_ControlResourceSet_t *coreset, + NR_ServingCellConfigCommon_t *scc, + NR_BWP_Downlink_t *bwp, + uint8_t aggregation_level, + int CCEIndex) { if (bwp) { // This is not the InitialBWP - NR_ControlResourceSet_t *temp_coreset; - NR_ControlResourceSetId_t coresetid = *ss->controlResourceSetId; - if (ss_type == 0) { // common search space - if (coresetid == 0){ - AssertFatal(1==0,"coreset0 currently not supported\n"); - } - else { - coreset = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet; - AssertFatal(coresetid==coreset->controlResourceSetId,"ID of common ss coreset does not correspond to id set in the search space\n"); - } - } - else { - int n_list = bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.count; - for (int i=0; ibwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[i]; - if (coresetid==temp_coreset->controlResourceSetId) { - coreset = temp_coreset; - cid = i; - break; - } - } - if(coreset==NULL) - AssertFatal(1==0,"Couldn't find coreset with id %ld\n",coresetid); - } - pdcch_pdu->BWPSize = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275); pdcch_pdu->BWPStart = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth,275); pdcch_pdu->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing; @@ -507,22 +711,6 @@ int nr_configure_pdcch(gNB_MAC_INST *nr_mac, pdcch_pdu->dci_pdu.ScramblingRNTI[pdcch_pdu->numDlDci]=0; } - uint8_t nr_of_candidates,aggregation_level; - find_aggregation_candidates(&aggregation_level, - &nr_of_candidates, - ss); - - CCEIndex = allocate_nr_CCEs(nr_mac, - 1, // bwp_id - cid, - aggregation_level, - ss->searchSpaceType->present-1, // search_space, 0 common, 1 ue-specific - 0, // UE-id - 0); // m - - if (CCEIndex<0) - return (CCEIndex); - pdcch_pdu->dci_pdu.AggregationLevel[pdcch_pdu->numDlDci] = aggregation_level; pdcch_pdu->dci_pdu.CceIndex[pdcch_pdu->numDlDci] = CCEIndex; @@ -531,7 +719,6 @@ int nr_configure_pdcch(gNB_MAC_INST *nr_mac, pdcch_pdu->dci_pdu.powerControlOffsetSS[pdcch_pdu->numDlDci]=1; pdcch_pdu->numDlDci++; - return (0); } else { // this is for InitialBWP AssertFatal(1==0,"Fill in InitialBWP PDCCH configuration\n"); @@ -1396,39 +1583,34 @@ int extract_length(int startSymbolAndLength) { } /* - * Dump the UL or DL UE_list into LOG_T(MAC) + * Dump the UL or DL UE_info into LOG_T(MAC) */ -void -dump_nr_ue_list(NR_UE_list_t *listP, - int ul_flag) -//------------------------------------------------------------------------------ -{ - if (ul_flag == 0) { - for (int j = listP->head; j >= 0; j = listP->next[j]) { - LOG_T(MAC, "DL list node %d => %d\n", - j, - listP->next[j]); - } - } else { - for (int j = listP->head_ul; j >= 0; j = listP->next_ul[j]) { - LOG_T(MAC, "UL list node %d => %d\n", - j, - listP->next_ul[j]); - } - } +void dump_nr_ue_list(NR_UE_list_t *listP) { + for (int j = listP->head; j >= 0; j = listP->next[j]) + LOG_T(MAC, "DL list node %d => %d\n", j, listP->next[j]); +} - return; +/* + * Add a UE to NR_UE_list listP + */ +inline void add_nr_ue_list(NR_UE_list_t *listP, int UE_id) { + int *cur = &listP->head; + while (*cur >= 0) { + AssertFatal(*cur != UE_id, "UE_id %d already in NR_UE_list!\n", UE_id); + cur = &listP->next[*cur]; + } + *cur = UE_id; } int find_nr_UE_id(module_id_t mod_idP, rnti_t rntiP) //------------------------------------------------------------------------------ { int UE_id; - NR_UE_list_t *UE_list = &RC.nrmac[mod_idP]->UE_list; + NR_UE_info_t *UE_info = &RC.nrmac[mod_idP]->UE_info; for (UE_id = 0; UE_id < MAX_MOBILES_PER_GNB; UE_id++) { - if (UE_list->active[UE_id] == TRUE) { - if (UE_list->rnti[UE_id] == rntiP) { + if (UE_info->active[UE_id]) { + if (UE_info->rnti[UE_id] == rntiP) { return UE_id; } } @@ -1439,40 +1621,40 @@ int find_nr_UE_id(module_id_t mod_idP, rnti_t rntiP) int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){ - int UE_id; - int i; - NR_UE_list_t *UE_list = &RC.nrmac[mod_idP]->UE_list; + NR_UE_info_t *UE_info = &RC.nrmac[mod_idP]->UE_info; NR_COMMON_channels_t *cc = RC.nrmac[mod_idP]->common_channels; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; int num_slots_ul = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots; if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols>0) num_slots_ul++; - LOG_I(MAC, "[gNB %d] Adding UE with rnti %x (next avail %d, num_UEs %d)\n", + LOG_W(MAC, "[gNB %d] Adding UE with rnti %x (num_UEs %d)\n", mod_idP, rntiP, - UE_list->avail, - UE_list->num_UEs); - dump_nr_ue_list(UE_list, 0); + UE_info->num_UEs); + dump_nr_ue_list(&UE_info->list); - for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { - if (UE_list->active[i] == TRUE) + for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) { + if (UE_info->active[i]) continue; - UE_id = i; - UE_list->num_UEs++; - UE_list->active[UE_id] = TRUE; - UE_list->rnti[UE_id] = rntiP; - memset((void *) &UE_list->UE_sched_ctrl[UE_id], + int UE_id = i; + UE_info->num_UEs++; + UE_info->active[UE_id] = true; + UE_info->rnti[UE_id] = rntiP; + add_nr_ue_list(&UE_info->list, UE_id); + memset((void *) &UE_info->UE_sched_ctrl[UE_id], 0, sizeof(NR_UE_sched_ctrl_t)); - UE_list->UE_sched_ctrl[UE_id].ul_rssi = 0; - UE_list->UE_sched_ctrl[UE_id].sched_pucch = (NR_sched_pucch *)malloc(num_slots_ul*sizeof(NR_sched_pucch)); - UE_list->UE_sched_ctrl[UE_id].sched_pusch = (NR_sched_pusch *)malloc(num_slots_ul*sizeof(NR_sched_pusch)); + UE_info->UE_sched_ctrl[UE_id].ta_timer = 100; + UE_info->UE_sched_ctrl[UE_id].ta_update = 31; + UE_info->UE_sched_ctrl[UE_id].ul_rssi = 0; + UE_info->UE_sched_ctrl[UE_id].sched_pucch = (NR_sched_pucch *)malloc(num_slots_ul*sizeof(NR_sched_pucch)); + UE_info->UE_sched_ctrl[UE_id].sched_pusch = (NR_sched_pusch *)malloc(num_slots_ul*sizeof(NR_sched_pusch)); for (int k=0; kUE_sched_ctrl[UE_id].sched_pucch[k], + memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k], 0, sizeof(NR_sched_pucch)); - memset((void *) &UE_list->UE_sched_ctrl[UE_id].sched_pusch[k], + memset((void *) &UE_info->UE_sched_ctrl[UE_id].sched_pusch[k], 0, sizeof(NR_sched_pusch)); } @@ -1480,18 +1662,57 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){ mod_idP, UE_id, rntiP); - dump_nr_ue_list(UE_list, - 0); + dump_nr_ue_list(&UE_info->list); return (UE_id); } // printf("MAC: cannot add new UE for rnti %x\n", rntiP); - LOG_E(MAC, "error in add_new_ue(), could not find space in UE_list, Dumping UE list\n"); - dump_nr_ue_list(UE_list, - 0); + LOG_E(MAC, "error in add_new_ue(), could not find space in UE_info, Dumping UE list\n"); + dump_nr_ue_list(&UE_info->list); return -1; } +/* hack data to remove UE in the phy */ +int rnti_to_remove[10]; +volatile int rnti_to_remove_count; +pthread_mutex_t rnti_to_remove_mutex = PTHREAD_MUTEX_INITIALIZER; + +void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti) +{ + int UE_id; + int i; + NR_UE_info_t *UE_info = &RC.nrmac[mod_id]->UE_info; + + for (i = 0; i < MAX_MOBILES_PER_GNB; i++) { + if (!UE_info->active[i]) + continue; + if (UE_info->rnti[i] != rnti) + continue; + + /* UE found, remove it */ + UE_id = i; + UE_info->num_UEs--; + UE_info->active[UE_id] = FALSE; + UE_info->rnti[UE_id] = 0; + free(UE_info->UE_sched_ctrl[UE_id].sched_pucch); + free(UE_info->UE_sched_ctrl[UE_id].sched_pusch); + memset((void *) &UE_info->UE_sched_ctrl[UE_id], + 0, + sizeof(NR_UE_sched_ctrl_t)); + LOG_I(MAC, "[gNB %d] Remove NR UE_id %d : rnti %x\n", + mod_id, + UE_id, + rnti); + + /* hack to remove UE in the phy */ + if (pthread_mutex_lock(&rnti_to_remove_mutex)) exit(1); + if (rnti_to_remove_count == 10) exit(1); + rnti_to_remove[rnti_to_remove_count] = rnti; + LOG_W(MAC, "to remove in mac rnti_to_remove[%d]=%d\n", rnti_to_remove_count, rnti); + rnti_to_remove_count++; + if (pthread_mutex_unlock(&rnti_to_remove_mutex)) exit(1); + } +} uint8_t nr_get_tpc(int target, uint8_t cqi, int incr) { // al values passed to this function are x10 @@ -1510,8 +1731,8 @@ void get_pdsch_to_harq_feedback(int Mod_idP, uint8_t *pdsch_to_harq_feedback) { int bwp_id=1; - NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list; - NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id]; + NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; + NR_CellGroupConfig_t *secondaryCellGroup = UE_info->secondaryCellGroup[UE_id]; NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]; NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1]; @@ -1563,7 +1784,7 @@ void nr_update_pucch_scheduling(int Mod_idP, int *pucch_id) { NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon; - NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list; + NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info; NR_sched_pucch *curr_pucch; int first_ul_slot_tdd,k,i; uint8_t pdsch_to_harq_feedback[8]; @@ -1578,7 +1799,7 @@ void nr_update_pucch_scheduling(int Mod_idP, // for each possible ul or mixed slot for (k=0; kUE_sched_ctrl[UE_id].sched_pucch[k]; + curr_pucch = &UE_info->UE_sched_ctrl[UE_id].sched_pucch[k]; // if there is free room in current pucch structure if (curr_pucch->dai_cframe = frameP; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index bb0dad7064..a3dc3872c4 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -212,7 +212,7 @@ void nr_process_mac_pdu( LOG_D(MAC, "[UE %d] Frame %d : ULSCH -> UL-DTCH %d (gNB %d, %d bytes)\n", module_idP, frameP, rx_lcid, module_idP, mac_sdu_len); int UE_id = find_nr_UE_id(module_idP, rnti); - RC.nrmac[module_idP]->UE_list.mac_stats[UE_id].lc_bytes_rx[rx_lcid] += mac_sdu_len; + RC.nrmac[module_idP]->UE_info.mac_stats[UE_id].lc_bytes_rx[rx_lcid] += mac_sdu_len; #if defined(ENABLE_MAC_PAYLOAD_DEBUG) LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP); @@ -313,19 +313,19 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, const uint16_t rssi){ int current_rnti = 0, UE_id = -1, harq_pid = 0; gNB_MAC_INST *gNB_mac = NULL; - NR_UE_list_t *UE_list = NULL; + NR_UE_info_t *UE_info = NULL; NR_UE_sched_ctrl_t *UE_scheduling_control = NULL; current_rnti = rntiP; UE_id = find_nr_UE_id(gnb_mod_idP, current_rnti); gNB_mac = RC.nrmac[gnb_mod_idP]; - UE_list = &gNB_mac->UE_list; + UE_info = &gNB_mac->UE_info; int target_snrx10 = gNB_mac->pusch_target_snrx10; if (UE_id != -1) { - UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]); + UE_scheduling_control = &(UE_info->UE_sched_ctrl[UE_id]); - UE_list->mac_stats[UE_id].ulsch_total_bytes_rx += 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", gnb_mod_idP, harq_pid, @@ -339,7 +339,8 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, // if not missed detection (10dB threshold for now) if (UE_scheduling_control->ul_rssi < (100+rssi)) { UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10,ul_cqi,30); - UE_scheduling_control->ta_update = timing_advance; + 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); } @@ -365,20 +366,44 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, } } - else { + else if (sduP != NULL) { // if the CRC passed // random access pusch with TC-RNTI - if (sduP != NULL) { // if the CRC passed - for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { - if (UE_list->active[i] == TRUE) { - if (UE_list->tc_rnti[i] == current_rnti) { - // for now the only thing we are doing is set the UE as 5G connected - UE_list->fiveG_connected[i] = true; - LOG_I(MAC, "[gNB %d][RAPROC] PUSCH with TC_RNTI %x received correctly and UE_id %d is now 5G connected\n", - gnb_mod_idP, current_rnti, i); - } - } - } + NR_RA_t *ra = &gNB_mac->common_channels[CC_idP].ra[0]; + if (ra->state != WAIT_Msg3) { + LOG_E(MAC, + "expected RA state WAIT_Msg3/%d (but is %d) for RA-RNTI %04x\n", + WAIT_Msg3, + ra->state, + ra->rnti); + return; } + if (ra->rnti != current_rnti) { + LOG_E(MAC, + "expected RA-RNTI %04x (C-RNTI %04x) to match current RNTI %04x\n", + ra->rnti, + ra->crnti, + current_rnti); + return; + } + free(ra->preambles.preamble_list); + ra->state = RA_IDLE; + LOG_I(MAC, "reset RA state information for RA-RNTI %04x\n", ra->rnti); + const int UE_id = add_new_nr_ue(gnb_mod_idP, ra->crnti); + UE_info->secondaryCellGroup[UE_id] = ra->secondaryCellGroup; + struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = + ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList; + AssertFatal(bwpList->list.count == 1, + "downlinkBWP_ToAddModList has %d BWP!\n", + bwpList->list.count); + const int bwp_id = 1; + UE_info->UE_sched_ctrl[UE_id].active_bwp = bwpList->list.array[bwp_id - 1]; + LOG_W(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->crnti); } } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 7caf1baed5..726615b6e3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -67,6 +67,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frame_rxP, sub_frame_t slot_rxP); int nr_generate_dlsch_pdu(module_id_t Mod_idP, + NR_UE_sched_ctrl_t *ue_sched_ctl, unsigned char *sdus_payload, unsigned char *mac_pdu, unsigned char num_sdus, @@ -76,7 +77,10 @@ int nr_generate_dlsch_pdu(module_id_t Mod_idP, unsigned char *ue_cont_res_id, unsigned short post_padding); -void nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slotP); +void nr_schedule_ue_spec(module_id_t module_id, + frame_t frame, + sub_frame_t slot, + int num_slots_per_tdd); void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP); @@ -126,12 +130,38 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP); -int configure_fapi_dl_pdu(int Mod_id, - nfapi_nr_dl_tti_request_body_t *dl_req, - NR_sched_pucch *pucch_sched, - uint8_t *mcsIndex, - uint16_t *rbSize, - uint16_t *rbStart); +void nr_fill_nfapi_dl_pdu(int Mod_id, + int UE_id, + int bwp_id, + NR_SearchSpace_t *ss, + NR_ControlResourceSet_t *coreset, + nfapi_nr_dl_tti_request_body_t *dl_req, + NR_sched_pucch *pucch_sched, + int nrOfLayers, + uint8_t mcs, + uint16_t rbSize, + uint16_t rbStart, + uint8_t numDmrsCdmGrpsNoData, + nfapi_nr_dmrs_type_e dmrsConfigType, + uint8_t table_idx, + uint16_t R, + uint8_t Qm, + uint32_t tbs, + int time_domain_assignment, + int StartSymbolIndex, + int NrOfSymbols, + uint8_t aggregation_level, + int CCEIndex, + int harq_pid, + int ndi, + int round); + +int configure_fapi_dl_pdu_phytest(int Mod_id, + nfapi_nr_dl_tti_request_body_t *dl_req, + NR_sched_pucch *pucch_sched, + uint8_t *mcsIndex, + uint16_t *rbSize, + uint16_t *rbStart); void config_uldci(NR_BWP_Uplink_t *ubwp, nfapi_nr_pusch_pdu_t *pusch_pdu, @@ -211,13 +241,15 @@ void find_search_space(int ss_type, NR_BWP_Downlink_t *bwp, NR_SearchSpace_t *ss); -int nr_configure_pdcch(gNB_MAC_INST *nr_mac, - nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu, - uint16_t rnti, - int ss_type, - NR_SearchSpace_t *ss, - NR_ServingCellConfigCommon_t *scc, - NR_BWP_Downlink_t *bwp); +void nr_configure_pdcch(gNB_MAC_INST *nr_mac, + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, + uint16_t rnti, + NR_SearchSpace_t *ss, + NR_ControlResourceSet_t *coreset, + NR_ServingCellConfigCommon_t *scc, + NR_BWP_Downlink_t *bwp, + uint8_t aggregation_level, + int CCEIndex); void fill_dci_pdu_rel15(NR_ServingCellConfigCommon_t *scc, NR_CellGroupConfig_t *secondaryCellGroup, @@ -233,6 +265,16 @@ void prepare_dci(NR_CellGroupConfig_t *secondaryCellGroup, nr_dci_format_t format, int bwp_id); +/* find coreset within the search space */ +NR_ControlResourceSet_t *get_coreset(NR_BWP_Downlink_t *bwp, + NR_SearchSpace_t *ss, + int ss_type); + +/* find a search space within a BWP */ +NR_SearchSpace_t *get_searchspace( + NR_BWP_Downlink_t *bwp, + NR_SearchSpace__searchSpaceType_PR target_ss); + void find_aggregation_candidates(uint8_t *aggregation_level, uint8_t *nr_of_candidates, NR_SearchSpace_t *ss); @@ -259,20 +301,21 @@ int NRRIV2BW(int locationAndBandwidth,int N_RB); int NRRIV2PRBOFFSET(int locationAndBandwidth,int N_RB); -void dump_nr_ue_list(NR_UE_list_t *listP, int ul_flag); +void dump_nr_ue_list(NR_UE_list_t *listP); +void add_nr_ue_list(NR_UE_list_t *listP, int UE_id); int find_nr_UE_id(module_id_t mod_idP, rnti_t rntiP); int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP); +void mac_remove_nr_ue(module_id_t mod_id, rnti_t rnti); + int allocate_nr_CCEs(gNB_MAC_INST *nr_mac, - int bwp_id, - int coreset_id, + NR_BWP_Downlink_t *bwp, + NR_ControlResourceSet_t *coreset, int aggregation, - int search_space, // 0 common, 1 ue-specific - int UE_id, - int m - ); + uint16_t n_RNTI, + int m); int get_dlscs(nfapi_nr_config_request_t *cfg); @@ -305,7 +348,8 @@ void schedule_fapi_ul_pdu(int Mod_idP, sub_frame_t slotP, int num_slots_per_tdd, int ul_slots, - int time_domain_assignment); + int time_domain_assignment, + uint64_t ulsch_in_slot_bitmap); 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 bd0be8c409..7df00f15f1 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -50,7 +50,7 @@ void mac_top_init_gNB(void) { module_id_t i; int list_el; - NR_UE_list_t *UE_list; + NR_UE_info_t *UE_info; gNB_MAC_INST *nrmac; LOG_I(MAC, "[MAIN] Init function start:nb_nr_macrlc_inst=%d\n",RC.nb_nr_macrlc_inst); @@ -104,29 +104,21 @@ void mac_top_init_gNB(void) nrmac = RC.nrmac[i]; nrmac->if_inst = NR_IF_Module_init(i); - UE_list = &nrmac->UE_list; - UE_list->num_UEs = 0; - UE_list->head = -1; - UE_list->head_ul = -1; - UE_list->avail = 0; - - for (list_el = 0; list_el < MAX_MOBILES_PER_GNB - 1; list_el++) { - UE_list->next[list_el] = list_el + 1; - UE_list->next_ul[list_el] = list_el + 1; - UE_list->active[list_el] = FALSE; + UE_info = &nrmac->UE_info; + UE_info->num_UEs = 0; + UE_info->list.head = -1; + for (list_el = 0; list_el < MAX_MOBILES_PER_GNB; list_el++) { + UE_info->list.next[list_el] = -1; + UE_info->active[list_el] = false; for (int list_harq = 0; list_harq < NR_MAX_NB_HARQ_PROCESSES; list_harq++) { - UE_list->UE_sched_ctrl[list_el].harq_processes[list_harq].round = 0; - UE_list->UE_sched_ctrl[list_el].harq_processes[list_harq].ndi = 0; - UE_list->UE_sched_ctrl[list_el].harq_processes[list_harq].is_waiting = 0; - UE_list->UE_sched_ctrl[list_el].ul_harq_processes[list_harq].round = 0; - UE_list->UE_sched_ctrl[list_el].ul_harq_processes[list_harq].ndi = 0; - UE_list->UE_sched_ctrl[list_el].ul_harq_processes[list_harq].state = 0; + UE_info->UE_sched_ctrl[list_el].harq_processes[list_harq].round = 0; + UE_info->UE_sched_ctrl[list_el].harq_processes[list_harq].ndi = 0; + UE_info->UE_sched_ctrl[list_el].harq_processes[list_harq].is_waiting = 0; + UE_info->UE_sched_ctrl[list_el].ul_harq_processes[list_harq].round = 0; + UE_info->UE_sched_ctrl[list_el].ul_harq_processes[list_harq].ndi = 0; + UE_info->UE_sched_ctrl[list_el].ul_harq_processes[list_harq].state = 0; } } - - UE_list->next[list_el] = -1; - UE_list->next_ul[list_el] = -1; - UE_list->active[list_el] = FALSE; } srand48(0); diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index bd8f0208c6..0ed64a9621 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -83,6 +83,11 @@ typedef enum { WAIT_Msg4_ACK = 4 } RA_gNB_state_t; +typedef struct NR_preamble_ue { + uint8_t num_preambles; + uint8_t *preamble_list; +} NR_preamble_ue_t; + /*! \brief gNB template for the Random access information */ typedef struct { /// Flag to indicate this process is active @@ -141,6 +146,12 @@ typedef struct { int msg4_mcs; /// RA search space NR_SearchSpace_t *ra_ss; + /// secondaryCellGroup for UE in NSA that is to come + NR_CellGroupConfig_t *secondaryCellGroup; + /// Preambles for contention-free access + NR_preamble_ue_t preambles; + /// NSA: the UEs C-RNTI to use + rnti_t crnti; } NR_RA_t; /*! \brief gNB common channels */ @@ -172,9 +183,9 @@ typedef struct { /// Template for RA computations NR_RA_t ra[NR_NB_RA_PROC_MAX]; /// VRB map for common channels - uint8_t vrb_map[100]; + uint8_t vrb_map[275]; /// VRB map for common channels and retransmissions by PHICH - uint8_t vrb_map_UL[100]; + uint8_t vrb_map_UL[275]; /// number of subframe allocation pattern available for MBSFN sync area uint8_t num_sf_allocation_pattern; } NR_COMMON_channels_t; @@ -268,6 +279,14 @@ typedef struct NR_UE_harq { uint16_t feedback_slot; } NR_UE_harq_t; +typedef struct NR_UE_old_sched { + uint16_t rbSize; + int time_domain_allocation; + uint8_t mcsTableIdx; + uint8_t mcs; + uint8_t numDmrsCdmGrpsNoData; +} NR_UE_ret_info_t; + typedef enum { INACTIVE = 0, ACTIVE_NOT_SCHED, @@ -283,12 +302,42 @@ typedef struct NR_UE_ul_harq { /*! \brief scheduling control information set through an API */ typedef struct { - uint64_t dlsch_in_slot_bitmap; // static bitmap signaling which slot in a tdd period contains dlsch - uint64_t ulsch_in_slot_bitmap; // static bitmap signaling which slot in a tdd period contains ulsch + /// total amount of data awaiting for this UE + uint32_t num_total_bytes; + /// per-LC status data + mac_rlc_status_resp_t rlc_status[MAX_NUM_LCID]; + + /// the currently active BWP in DL + NR_BWP_Downlink_t *active_bwp; NR_sched_pucch *sched_pucch; + /// selected PUCCH index, if scheduled + int pucch_sched_idx; NR_sched_pusch *sched_pusch; + + /// CCE index and aggregation, should be coherent with cce_list + NR_SearchSpace_t *search_space; + NR_ControlResourceSet_t *coreset; + int cce_index; + uint8_t aggregation_level; + + /// RB allocation within active BWP + uint16_t rbSize; + uint16_t rbStart; + + // time-domain allocation for scheduled RBs + int time_domain_allocation; + + /// MCS-related infos + uint8_t mcsTableIdx; + uint8_t mcs; + uint8_t numDmrsCdmGrpsNoData; + + /// Retransmission-related information + NR_UE_ret_info_t retInfo[NR_MAX_NB_HARQ_PROCESSES]; + uint16_t ta_timer; int16_t ta_update; + bool ta_apply; uint8_t tpc0; uint8_t tpc1; uint16_t ul_rssi; @@ -299,11 +348,6 @@ typedef struct { NR_UE_mac_ce_ctrl_t UE_mac_ce_ctrl;// MAC CE related information } NR_UE_sched_ctrl_t; -typedef struct NR_preamble_ue { - uint8_t num_preambles; - uint8_t *preamble_list; -} NR_preamble_ue; - typedef struct { int lc_bytes_tx[64]; @@ -317,25 +361,26 @@ typedef struct { int ulsch_total_bytes_rx; } NR_mac_stats_t; + +/*! \brief UNR_E_list_t is a "list" of users within UE_info_t. Especial useful in + * the scheduler and to keep "classes" of users. */ +typedef struct { + int head; + int next[MAX_MOBILES_PER_GNB]; +} NR_UE_list_t; + /*! \brief UE list used by gNB to order UEs/CC for scheduling*/ typedef struct { DLSCH_PDU DLSCH_pdu[4][MAX_MOBILES_PER_GNB]; /// scheduling control info NR_UE_sched_ctrl_t UE_sched_ctrl[MAX_MOBILES_PER_GNB]; NR_mac_stats_t mac_stats[MAX_MOBILES_PER_GNB]; - int next[MAX_MOBILES_PER_GNB]; - int head; - int next_ul[MAX_MOBILES_PER_GNB]; - int head_ul; - int avail; + NR_UE_list_t list; int num_UEs; - boolean_t active[MAX_MOBILES_PER_GNB]; - boolean_t fiveG_connected[MAX_MOBILES_PER_GNB]; + bool active[MAX_MOBILES_PER_GNB]; rnti_t rnti[MAX_MOBILES_PER_GNB]; - rnti_t tc_rnti[MAX_MOBILES_PER_GNB]; - NR_preamble_ue preambles[MAX_MOBILES_PER_GNB]; NR_CellGroupConfig_t *secondaryCellGroup[MAX_MOBILES_PER_GNB]; -} NR_UE_list_t; +} NR_UE_info_t; /*! \brief top level eNB MAC structure */ typedef struct gNB_MAC_INST_s { @@ -353,10 +398,6 @@ typedef struct gNB_MAC_INST_s { int pusch_target_snrx10; /// Pucch target SNR int pucch_target_snrx10; - /// TA command - int ta_command; - /// MAC CE flag indicating TA length - int ta_len; /// Common cell resources NR_COMMON_channels_t common_channels[NFAPI_CC_MAX]; /// current PDU index (BCH,DLSCH) @@ -373,7 +414,7 @@ typedef struct gNB_MAC_INST_s { /// NFAPI DL PDU structure nfapi_nr_tx_data_request_t TX_req[NFAPI_CC_MAX]; - NR_UE_list_t UE_list; + NR_UE_info_t UE_info; /// UL handle uint32_t ul_handle; diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index c8b385bbfc..0d98840f5b 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -431,9 +431,9 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity, GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).offset = GTPU_HEADER_OVERHEAD_MAX; GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rnti = ue->rnti; GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rab_id = rb_id + 4; - printf("!!!!!!! deliver_sdu_drb (drb %d) sending message to gtp size %d: ", rb_id, size); - //for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)buf[i]); - printf("\n"); + LOG_D(PDCP, "%s() (drb %d) sending message to gtp size %d\n", __func__, rb_id, size); + //for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)buf[i]); + //printf("\n"); itti_send_msg_to_task(TASK_GTPV1_U, INSTANCE_DEFAULT, message_p); } @@ -474,9 +474,9 @@ rb_found: memblock = get_free_mem_block(size, __FUNCTION__); memcpy(memblock->data, buf, size); -printf("!!!!!!! deliver_pdu_drb (srb %d) calling rlc_data_req size %d: ", rb_id, size); -//for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)memblock->data[i]); -printf("\n"); + LOG_D(PDCP, "%s(): (srb %d) calling rlc_data_req size %d\n", __func__, rb_id, size); + //for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)memblock->data[i]); + //printf("\n"); enqueue_rlc_data_req(&ctxt, 0, MBMS_FLAG_NO, rb_id, sdu_id, 0, size, memblock, NULL, NULL); } @@ -854,7 +854,12 @@ uint64_t get_pdcp_optmask(void) boolean_t pdcp_remove_UE( const protocol_ctxt_t *const ctxt_pP) { - TODO; + int rnti = ctxt_pP->rnti; + + nr_pdcp_manager_lock(nr_pdcp_ue_manager); + nr_pdcp_manager_remove_ue(nr_pdcp_ue_manager, rnti); + nr_pdcp_manager_unlock(nr_pdcp_ue_manager); + return 1; } @@ -872,7 +877,7 @@ static boolean_t pdcp_data_req_drb( const sdu_size_t sdu_buffer_size, unsigned char *const sdu_buffer) { -printf("pdcp_data_req called size %d\n", sdu_buffer_size); + LOG_D(PDCP, "%s() called, size %d\n", __func__, sdu_buffer_size); nr_pdcp_ue_t *ue; nr_pdcp_entity_t *rb; int rnti = ctxt_pP->rnti; @@ -897,9 +902,9 @@ printf("pdcp_data_req called size %d\n", sdu_buffer_size); rb = ue->drb[rb_id - 1]; if (rb == NULL) { - LOG_E(PDCP, "%s:%d:%s: fatal: no DRB found (rnti %d, rb_id %ld)\n", + LOG_E(PDCP, "%s:%d:%s: no DRB found (rnti %d, rb_id %ld)\n", __FILE__, __LINE__, __FUNCTION__, rnti, rb_id); - exit(1); + return 0; } rb->recv_sdu(rb, (char *)sdu_buffer, sdu_buffer_size, muiP); diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 919cf1a46a..5048dd245e 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -158,14 +158,6 @@ mac_rlc_status_resp_t mac_rlc_status_ind( mac_rlc_status_resp_t ret; nr_rlc_entity_t *rb; - /* TODO: handle time a bit more properly */ - if (nr_rlc_current_time_last_frame != frameP || - nr_rlc_current_time_last_subframe != subframeP) { - nr_rlc_current_time++; - nr_rlc_current_time_last_frame = frameP; - nr_rlc_current_time_last_subframe = subframeP; - } - nr_rlc_manager_lock(nr_rlc_ue_manager); ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rntiP); @@ -921,3 +913,10 @@ rlc_op_status_t rrc_rlc_remove_ue (const protocol_ctxt_t* const x) return RLC_OP_STATUS_OK; } + +void nr_rlc_tick(int frame, int subframe) +{ + if (frame != nr_rlc_current_time_last_frame || + subframe != nr_rlc_current_time_last_subframe) + nr_rlc_current_time++; +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.c b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.c index 09f1e4f599..d4db8d8484 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.c @@ -117,7 +117,7 @@ void nr_rlc_manager_remove_ue(nr_rlc_ue_manager_t *_m, int rnti) break; if (i == m->ue_count) { - LOG_D(RLC, "%s:%d:%s: warning: ue %d not found\n", + LOG_W(RLC, "%s:%d:%s: warning: ue %d not found\n", __FILE__, __LINE__, __FUNCTION__, rnti); return; diff --git a/openair2/LAYER2/nr_rlc/tests/LOG/log.h b/openair2/LAYER2/nr_rlc/tests/LOG/log.h index 5c9fcd643c..8ebc7e1909 100644 --- a/openair2/LAYER2/nr_rlc/tests/LOG/log.h +++ b/openair2/LAYER2/nr_rlc/tests/LOG/log.h @@ -1,5 +1,5 @@ -#ifndef _LOG_H_ -#define _LOG_H_ +#ifndef _NR_RLC_TESTS_LOG_H_ +#define _NR_RLC_TESTS_LOG_H_ #include @@ -7,4 +7,4 @@ #define LOG_D(x, ...) printf(__VA_ARGS__) #define LOG_W(x, ...) printf(__VA_ARGS__) -#endif /* _LOG_H_ */ +#endif /* _NR_RLC_TESTS_LOG_H_ */ diff --git a/openair2/LAYER2/rlc_v2/tests/LOG/log.h b/openair2/LAYER2/rlc_v2/tests/LOG/log.h index 5c9fcd643c..89d85090b1 100644 --- a/openair2/LAYER2/rlc_v2/tests/LOG/log.h +++ b/openair2/LAYER2/rlc_v2/tests/LOG/log.h @@ -1,5 +1,5 @@ -#ifndef _LOG_H_ -#define _LOG_H_ +#ifndef _RLC_V2_TESTS_LOG_H_ +#define _RLC_V2_TESTS_LOG_H_ #include @@ -7,4 +7,4 @@ #define LOG_D(x, ...) printf(__VA_ARGS__) #define LOG_W(x, ...) printf(__VA_ARGS__) -#endif /* _LOG_H_ */ +#endif /* _RLC_V2_TESTS_LOG_H_ */ diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index c5b90cf028..22c48d11eb 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -181,10 +181,10 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) { clear_nr_nfapi_information(mac,CC_id,UL_info->frame,UL_info->slot); handle_nr_rach(UL_info); - handle_nr_uci(UL_info,&mac->UE_list.UE_sched_ctrl[0],&mac->UE_list.mac_stats[0],mac->pucch_target_snrx10); + handle_nr_uci(UL_info,&mac->UE_info.UE_sched_ctrl[0],&mac->UE_info.mac_stats[0],mac->pucch_target_snrx10); // clear HI prior to handling ULSCH mac->UL_dci_req[CC_id].numPdus = 0; - handle_nr_ulsch(UL_info, &mac->UE_list.UE_sched_ctrl[0],&mac->UE_list.mac_stats[0]); + handle_nr_ulsch(UL_info, &mac->UE_info.UE_sched_ctrl[0],&mac->UE_info.mac_stats[0]); if (nfapi_mode != 1) { if (ifi->CC_mask == ((1<present = NR_FreqBandInformation_PR_bandInformationEUTRA; + nsa_band->choice.bandInformationEUTRA = (NR_FreqBandInformationEUTRA_t *) calloc(1, sizeof(NR_FreqBandInformationEUTRA_t)); + nsa_band->choice.bandInformationEUTRA->bandEUTRA = eutra_band; + ASN_SEQUENCE_ADD(&nsa_band_list->list, nsa_band); + + nsa_band = (NR_FreqBandInformation_t *) calloc(1,sizeof(NR_FreqBandInformation_t)); + nsa_band->present = NR_FreqBandInformation_PR_bandInformationNR; + nsa_band->choice.bandInformationNR = (NR_FreqBandInformationNR_t *) calloc(1, sizeof(NR_FreqBandInformationNR_t)); + if(nr_band > 0) + nsa_band->choice.bandInformationNR->bandNR = nr_band; + else + nsa_band->choice.bandInformationNR->bandNR = 78; + ASN_SEQUENCE_ADD(&nsa_band_list->list, nsa_band); + OCTET_STRING_t req_freq; - unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x02, 0x68 }; // bands 7 & nr78 + //unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x02, 0x68 }; // bands 7 & nr78 + unsigned char req_freq_buf[1024]; + enc_rval = uper_encode_to_buffer(&asn_DEF_NR_FreqBandList, + NULL, + (void *)nsa_band_list, + req_freq_buf, + 1024); + + xer_fprint(stdout, &asn_DEF_NR_FreqBandList, (void *)nsa_band_list); + + + //unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x08, 0x18 }; // bands 7 & nr260 //unsigned char req_freq_buf[13] = { 0x00, 0xc0, 0x18, 0x01, 0x01, 0x30, 0x4b, 0x04, 0x0e, 0x08, 0x24, 0x04, 0xd0 }; @@ -3248,7 +3281,7 @@ uint8_t do_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, // }; req_freq.buf = req_freq_buf; - req_freq.size = 5; + req_freq.size = (enc_rval.encoded+7)/8; // req_freq.size = 21; r15_10.requestedFreqBandsNR_MRDC_r15 = &req_freq; @@ -3287,9 +3320,13 @@ uint8_t do_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, //------------------------------------------------------------------------------ uint8_t do_NR_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, uint8_t *const buffer, - const uint8_t Transaction_id) + const uint8_t Transaction_id, + int16_t eutra_band, + uint32_t nr_band) //------------------------------------------------------------------------------ { + NR_FreqBandList_t *nsa_band_list; + NR_FreqBandInformation_t *nsa_band; LTE_DL_DCCH_Message_t dl_dcch_msg; LTE_RAT_Type_t rat_nr=LTE_RAT_Type_nr; LTE_RAT_Type_t rat_eutra_nr=LTE_RAT_Type_eutra_nr; @@ -3329,8 +3366,32 @@ uint8_t do_NR_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, /* TODO: no hardcoded values here */ + nsa_band_list = (NR_FreqBandList_t *)calloc(1, sizeof(NR_FreqBandList_t)); + + nsa_band = (NR_FreqBandInformation_t *) calloc(1,sizeof(NR_FreqBandInformation_t)); + nsa_band->present = NR_FreqBandInformation_PR_bandInformationEUTRA; + nsa_band->choice.bandInformationEUTRA = (NR_FreqBandInformationEUTRA_t *) calloc(1, sizeof(NR_FreqBandInformationEUTRA_t)); + nsa_band->choice.bandInformationEUTRA->bandEUTRA = eutra_band; + ASN_SEQUENCE_ADD(&nsa_band_list->list, nsa_band); + + nsa_band = (NR_FreqBandInformation_t *) calloc(1,sizeof(NR_FreqBandInformation_t)); + nsa_band->present = NR_FreqBandInformation_PR_bandInformationNR; + nsa_band->choice.bandInformationNR = (NR_FreqBandInformationNR_t *) calloc(1, sizeof(NR_FreqBandInformationNR_t)); + if(nr_band > 0) + nsa_band->choice.bandInformationNR->bandNR = nr_band; + else + nsa_band->choice.bandInformationNR->bandNR = 78; + ASN_SEQUENCE_ADD(&nsa_band_list->list, nsa_band); + OCTET_STRING_t req_freq; - unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x02, 0x68 }; // bands 7 & nr78 + //unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x02, 0x68 }; // bands 7 & nr78 + unsigned char req_freq_buf[100]; + enc_rval = uper_encode_to_buffer(&asn_DEF_NR_FreqBandList, + NULL, + (void *)nsa_band_list, + req_freq_buf, + 1024); + //unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x08, 0x18 }; // bands 7 & nr260 //unsigned char req_freq_buf[13] = { 0x00, 0xc0, 0x18, 0x01, 0x01, 0x30, 0x4b, 0x04, 0x0e, 0x08, 0x24, 0x04, 0xd0 }; @@ -3339,7 +3400,7 @@ uint8_t do_NR_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, // }; req_freq.buf = req_freq_buf; - req_freq.size = 5; + req_freq.size = (enc_rval.encoded+7)/8; // req_freq.size = 21; r15_10.requestedFreqBandsNR_MRDC_r15 = &req_freq; diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.h b/openair2/RRC/LTE/MESSAGES/asn1_msg.h index 640d18a61f..0d9fe65aeb 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.h +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.h @@ -359,15 +359,17 @@ uint8_t do_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, uint8_t *const buffer, - const uint8_t Transaction_id -); + const uint8_t Transaction_id, + int16_t eutra_band, + uint32_t nr_band); uint8_t do_NR_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, uint8_t *const buffer, - const uint8_t Transaction_id -); + const uint8_t Transaction_id, + int16_t eutra_band, + uint32_t nr_band); uint8_t do_SecurityModeCommand( const protocol_ctxt_t *const ctxt_pP, diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index c498e3c6fe..7829360939 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -271,7 +271,8 @@ typedef enum UE_STATE_e { RRC_RECONFIGURED, RRC_HO_EXECUTION, RRC_NR_NSA, - RRC_NR_NSA_RECONFIGURED + RRC_NR_NSA_RECONFIGURED, + RRC_NR_NSA_DELETED } UE_STATE_t; typedef enum HO_STATE_e { @@ -591,6 +592,8 @@ typedef struct eNB_RRC_UE_s { uint8_t Status; // RRC status, type enum UE_STATE_t rnti_t rnti; + int gnb_rnti; //RNTI of the UE at the gNB if in ENDC connection + int gnb_x2_assoc_id; uint64_t random_ue_identity; @@ -791,6 +794,10 @@ typedef struct eNB_RRC_INST_s { int num_neigh_cells_cc[MAX_NUM_CCs]; uint32_t neigh_cells_id[MAX_NUM_NEIGH_CELLs][MAX_NUM_CCs]; + // Nr scc freq band and SSB absolute frequency + uint32_t nr_neigh_freq_band[MAX_NUM_NEIGH_CELLs][MAX_NUM_CCs]; + int nr_scg_ssb_freq; + // other RAN parameters int srb1_timer_poll_retransmit; int srb1_poll_pdu; diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 31a26d322d..4454980e33 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -155,7 +155,6 @@ init_SI( LOG_D(RRC,"%s()\n\n\n\n",__FUNCTION__); if(configuration->radioresourceconfig[CC_id].mbms_dedicated_serving_cell == TRUE) { - LOG_I(RRC, "Configuring MIB FeMBMS (N_RB_DL %d)\n", (int)configuration->N_RB_DL[CC_id]); RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MIB_FeMBMS = (uint8_t *) malloc16(4); @@ -500,13 +499,17 @@ init_SI( RC.rrc[ctxt_pP->module_id]->carrier[CC_id].FeMBMS_flag, (carrier->sib1_MBMS==NULL?(LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL:(LTE_BCCH_DL_SCH_Message_MBMS_t *)carrier->sib1_MBMS),//(LTE_BCCH_DL_SCH_Message_MBMS_t *) NULL, (LTE_SchedulingInfo_MBMS_r14_t *) NULL, - (carrier->sib1_MBMS==NULL?(struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL:(struct LTE_NonMBSFN_SubframeConfig_r14 *)carrier->sib1_MBMS->nonMBSFN_SubframeConfig_r14),//(struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, - (carrier->sib1_MBMS==NULL?(LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL:(LTE_SystemInformationBlockType1_MBMS_r14_t *)carrier->sib1_MBMS->systemInformationBlockType13_r14),//(LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, - (carrier->sib1_MBMS==NULL?(LTE_MBSFN_AreaInfoList_r9_t *) NULL:(LTE_MBSFN_AreaInfoList_r9_t *)&carrier->sib1_MBMS->systemInformationBlockType13_r14->mbsfn_AreaInfoList_r9)//(LTE_MBSFN_AreaInfoList_r9_t *) NULL - - ,(LTE_MBSFNAreaConfiguration_r9_t*) NULL - - ); + (carrier->sib1_MBMS==NULL + ? (struct LTE_NonMBSFN_SubframeConfig_r14 *)NULL + : (struct LTE_NonMBSFN_SubframeConfig_r14 *)carrier->sib1_MBMS->nonMBSFN_SubframeConfig_r14),//(struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, + (carrier->sib1_MBMS==NULL + ? (LTE_SystemInformationBlockType1_MBMS_r14_t *)NULL + : (LTE_SystemInformationBlockType1_MBMS_r14_t *)carrier->sib1_MBMS->systemInformationBlockType13_r14),//(LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, + (carrier->sib1_MBMS==NULL + ? (LTE_MBSFN_AreaInfoList_r9_t *)NULL + : (LTE_MBSFN_AreaInfoList_r9_t *)&carrier->sib1_MBMS->systemInformationBlockType13_r14->mbsfn_AreaInfoList_r9),//(LTE_MBSFN_AreaInfoList_r9_t *) NULL, + (LTE_MBSFNAreaConfiguration_r9_t *)NULL + ); } /* set flag to indicate that cell information is configured. This is required @@ -590,7 +593,7 @@ init_MCCH( (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, - (LTE_MBSFNAreaConfiguration_r9_t*) NULL + (LTE_MBSFNAreaConfiguration_r9_t *) NULL ); } @@ -1040,59 +1043,59 @@ void release_UE_in_freeList(module_id_t mod_id) { for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { eNB_PHY = RC.eNB[mod_id][CC_id]; + int id; + // clean ULSCH entries for rnti + id = find_ulsch(rnti,eNB_PHY,SEARCH_EXIST); - int id; - - // clean ULSCH entries for rnti - id = find_ulsch(rnti,eNB_PHY,SEARCH_EXIST); if (id>=0) clean_eNb_ulsch(eNB_PHY->ulsch[id]); - // clean DLSCH entries for rnti - id = find_dlsch(rnti,eNB_PHY,SEARCH_EXIST); + // clean DLSCH entries for rnti + id = find_dlsch(rnti,eNB_PHY,SEARCH_EXIST); + if (id>=0) clean_eNb_dlsch(eNB_PHY->dlsch[id][0]); - // clean UCI entries for rnti + // clean UCI entries for rnti for (i=0; iuci_vars[i].rnti == rnti) { LOG_I(MAC, "clean eNb uci_vars[%d] UE %x \n",i, rnti); memset(&eNB_PHY->uci_vars[i],0,sizeof(LTE_eNB_UCI)); } } - - /* - for (i=0; iulsch[i]; - if((ulsch != NULL) && (ulsch->rnti == rnti)) { - void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch); - LOG_I(RRC, "clean_eNb_ulsch ulsch[%d] UE %x\n", i, rnti); - clean_eNb_ulsch(ulsch); - } + /* + for (i=0; iulsch[i]; - dlsch = eNB_PHY->dlsch[i][0]; + if((ulsch != NULL) && (ulsch->rnti == rnti)) { + void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch); + LOG_I(RRC, "clean_eNb_ulsch ulsch[%d] UE %x\n", i, rnti); + clean_eNb_ulsch(ulsch); + } - if((dlsch != NULL) && (dlsch->rnti == rnti)) { - void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch); - LOG_I(RRC, "clean_eNb_dlsch dlsch[%d] UE %x \n", i, rnti); - clean_eNb_dlsch(dlsch); - } - } + dlsch = eNB_PHY->dlsch[i][0]; - ulsch = eNB_PHY->ulsch[i]; + if((dlsch != NULL) && (dlsch->rnti == rnti)) { + void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch); + LOG_I(RRC, "clean_eNb_dlsch dlsch[%d] UE %x \n", i, rnti); + clean_eNb_dlsch(dlsch); + } + } - if((ulsch != NULL) && (ulsch->rnti == rnti)) { - void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch); - LOG_I(RRC, "clean_eNb_ulsch ulsch[%d] UE %x\n", i, rnti); - clean_eNb_ulsch(ulsch); - } + ulsch = eNB_PHY->ulsch[i]; - for (i=0; iuci_vars[i].rnti == rnti) { - LOG_I(MAC, "clean eNb uci_vars[%d] UE %x \n",i, rnti); - memset(&eNB_PHY->uci_vars[i],0,sizeof(LTE_eNB_UCI)); - } - } - */ + if((ulsch != NULL) && (ulsch->rnti == rnti)) { + void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch); + LOG_I(RRC, "clean_eNb_ulsch ulsch[%d] UE %x\n", i, rnti); + clean_eNb_ulsch(ulsch); + } + + for (i=0; iuci_vars[i].rnti == rnti) { + LOG_I(MAC, "clean eNb uci_vars[%d] UE %x \n",i, rnti); + memset(&eNB_PHY->uci_vars[i],0,sizeof(LTE_eNB_UCI)); + } + } + */ if (flexran_agent_get_rrc_xface(mod_id)) { flexran_agent_get_rrc_xface(mod_id)->flexran_agent_notify_ue_state_change( @@ -1279,10 +1282,14 @@ rrc_eNB_generate_UECapabilityEnquiry( uint8_t size; T(T_ENB_RRC_UE_CAPABILITY_ENQUIRY, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + int16_t eutra_band = RC.rrc[ctxt_pP->module_id]->configuration.eutra_band[0]; + uint32_t nr_band = RC.rrc[ctxt_pP->module_id]->nr_neigh_freq_band[0][0]; size = do_UECapabilityEnquiry( ctxt_pP, buffer, - rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id)); + rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id), + eutra_band, + nr_band); LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate UECapabilityEnquiry (bytes %d)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), @@ -1325,10 +1332,14 @@ rrc_eNB_generate_NR_UECapabilityEnquiry( uint8_t size; T(T_ENB_RRC_UE_CAPABILITY_ENQUIRY, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + int16_t eutra_band = RC.rrc[ctxt_pP->module_id]->configuration.eutra_band[0]; + uint32_t nr_band = RC.rrc[ctxt_pP->module_id]->nr_neigh_freq_band[0][0]; size = do_NR_UECapabilityEnquiry( ctxt_pP, buffer, - rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id)); + rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id), + eutra_band, + nr_band); LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate NR UECapabilityEnquiry (bytes %d)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), @@ -1488,7 +1499,7 @@ rrc_eNB_generate_RRCConnectionReestablishment( (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, - (LTE_MBSFNAreaConfiguration_r9_t*) NULL + (LTE_MBSFNAreaConfiguration_r9_t *) NULL ); break; } @@ -2190,7 +2201,6 @@ rrc_eNB_generate_RRCConnectionRelease( uint8_t buffer[RRC_BUF_SIZE]; uint16_t size = 0; int release_num; - memset(buffer, 0, RRC_BUF_SIZE); T(T_ENB_RRC_CONNECTION_RELEASE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); @@ -3281,7 +3291,7 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t MeasObj2->measObjectId = 2; MeasObj2->measObject.present = LTE_MeasObjectToAddMod__measObject_PR_measObjectNR_r15; - MeasObj2->measObject.choice.measObjectNR_r15.carrierFreq_r15 =641272; //634000; //(634000 = 3.51GHz) (640000 = 3.6GHz) (641272 = 3619.08MHz = 3600 + 30/1000*106*12/2) (642256 is for 3.6GHz and absoluteFrequencySSB = 642016) + MeasObj2->measObject.choice.measObjectNR_r15.carrierFreq_r15 = rrc_inst->nr_scg_ssb_freq; //641272; //634000; //(634000 = 3.51GHz) (640000 = 3.6GHz) (641272 = 3619.08MHz = 3600 + 30/1000*106*12/2) (642256 is for 3.6GHz and absoluteFrequencySSB = 642016) MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.measTimingConfig_r15.periodicityAndOffset_r15.present = LTE_MTC_SSB_NR_r15__periodicityAndOffset_r15_PR_sf20_r15; MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.measTimingConfig_r15.periodicityAndOffset_r15.choice.sf20_r15 = 0; MeasObj2->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.measTimingConfig_r15.ssb_Duration_r15 = LTE_MTC_SSB_NR_r15__ssb_Duration_r15_sf4; @@ -3593,20 +3603,19 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t size, buffer, PDCP_TRANSMISSION_MODE_CONTROL); - /* Refresh SRBs/DRBs */ rrc_pdcp_config_asn1_req(ctxt_pP, - *SRB_configList2, // NULL, - *DRB_configList, - NULL, - 0xff, // already configured during the securitymodecommand - NULL, - NULL, - NULL + *SRB_configList2, // NULL, + *DRB_configList, + NULL, + 0xff, // already configured during the securitymodecommand + NULL, + NULL, + NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , (LTE_PMCH_InfoList_r9_t *) NULL + , (LTE_PMCH_InfoList_r9_t *) NULL #endif - , NULL); + , NULL); /* Refresh SRBs/DRBs */ if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { @@ -3619,7 +3628,7 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t 0, 0 #endif - ); + ); } free(Sparams); @@ -4646,6 +4655,8 @@ rrc_eNB_process_MeasurementReport( if ((ue_context_pP->ue_context.Status != RRC_NR_NSA) && (ue_context_pP->ue_context.Status != RRC_NR_NSA_RECONFIGURED)) { MessageDef *msg; ue_context_pP->ue_context.Status = RRC_NR_NSA; + ue_context_pP->ue_context.gnb_rnti = -1; // set when receiving X2AP_ENDC_SGNB_ADDITION_REQ_ACK + ue_context_pP->ue_context.gnb_x2_assoc_id = -1; // set when receiving X2AP_ENDC_SGNB_ADDITION_REQ_ACK if(is_en_dc_supported(ue_context_pP->ue_context.UE_Capability)) { /** to add gNB as Secondary node CG-ConfigInfo to be added as per 36.423 r15 **/ @@ -4666,7 +4677,7 @@ rrc_eNB_process_MeasurementReport( for (int e_rab=0; e_rab < X2AP_ENDC_SGNB_ADDITION_REQ(msg).nb_e_rabs_tobeadded; e_rab++) { X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[e_rab].e_rab_id = ue_context_pP->ue_context.e_rab[e_rab].param.e_rab_id; X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[e_rab].gtp_teid = ue_context_pP->ue_context.e_rab[e_rab].param.gtp_teid; - X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[e_rab].drb_ID = ue_context_pP->ue_context.DRB_configList->list.array[e_rab]->drb_Identity; + X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[e_rab].drb_ID = ue_context_pP->ue_context.DRB_configList->list.array[e_rab]->drb_Identity; memcpy(&X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[e_rab].sgw_addr, &ue_context_pP->ue_context.e_rab[e_rab].param.sgw_addr, sizeof(transport_layer_addr_t)); @@ -5004,6 +5015,7 @@ void rrc_eNB_handover_ue_context_release( msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ); memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p))); GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti; + GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).from_gnb = 0; for (e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) { GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] = @@ -5789,7 +5801,7 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, - (LTE_MBSFNAreaConfiguration_r9_t*) NULL + (LTE_MBSFNAreaConfiguration_r9_t *) NULL ); // Configure target eNB SRB2 /// SRB2 @@ -6341,20 +6353,19 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct ue_context_pP->ue_context.rnti, rrc_eNB_mui, size); - /* Refresh SRBs/DRBs */ rrc_pdcp_config_asn1_req(ctxt_pP, - *SRB_configList2, // NULL, - *DRB_configList, - NULL, - 0xff, // already configured during the securitymodecommand - NULL, - NULL, - NULL + *SRB_configList2, // NULL, + *DRB_configList, + NULL, + 0xff, // already configured during the securitymodecommand + NULL, + NULL, + NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , (LTE_PMCH_InfoList_r9_t *) NULL + , (LTE_PMCH_InfoList_r9_t *) NULL #endif - , NULL); + , NULL); /* Refresh SRBs/DRBs */ if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { @@ -6367,7 +6378,7 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct 0, 0 #endif - ); + ); } free(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ); @@ -6413,6 +6424,7 @@ rrc_eNB_configure_rbs_handover(struct rrc_eNB_ue_context_s *ue_context_p, protoc NULL, NULL, (LTE_PMCH_InfoList_r9_t *) NULL, NULL); + if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { rrc_rlc_config_asn1_req(ctxt_pP, ue_context_p->ue_context.SRB_configList, @@ -6470,7 +6482,7 @@ rrc_eNB_configure_rbs_handover(struct rrc_eNB_ue_context_s *ue_context_p, protoc (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, - (LTE_MBSFNAreaConfiguration_r9_t*) NULL + (LTE_MBSFNAreaConfiguration_r9_t *) NULL ); } @@ -6553,6 +6565,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( kUPenc, (LTE_PMCH_InfoList_r9_t *) NULL, NULL); + /* Refresh SRBs/DRBs */ if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { rrc_rlc_config_asn1_req(ctxt_pP, @@ -6562,7 +6575,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( (LTE_PMCH_InfoList_r9_t *) NULL, 0, 0 - ); + ); } /* Set the SRB active in UE context */ @@ -6687,7 +6700,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, - (LTE_MBSFNAreaConfiguration_r9_t*) NULL + (LTE_MBSFNAreaConfiguration_r9_t *) NULL ); } } else { // remove LCHAN from MAC/PHY @@ -6747,7 +6760,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, - (LTE_MBSFNAreaConfiguration_r9_t*) NULL + (LTE_MBSFNAreaConfiguration_r9_t *) NULL ); } } // end else of if (ue_context_pP->ue_context.DRB_active[drb_id] == 0) @@ -6910,7 +6923,7 @@ rrc_eNB_generate_RRCConnectionSetup( (struct LTE_NonMBSFN_SubframeConfig_r14 *) NULL, (LTE_SystemInformationBlockType1_MBMS_r14_t *) NULL, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, - (LTE_MBSFNAreaConfiguration_r9_t*) NULL + (LTE_MBSFNAreaConfiguration_r9_t *) NULL ); break; } @@ -6945,6 +6958,32 @@ rrc_eNB_generate_RRCConnectionSetup( } } +//----------------------------------------------------------------------------- +void rrc_eNB_process_reconfiguration_complete_endc(const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_p) +//----------------------------------------------------------------------------- +{ + MessageDef *msg_p; + + msg_p = itti_alloc_new_message (TASK_RRC_ENB, X2AP_ENDC_SGNB_RECONF_COMPLETE); + + /* MeNB_ue_x2_id is unknown, set to 0. + * This is not correct but X2 id in the eNB is only 12 bits, + * so unfortunately we can't use rnti. + * To be corrected if needed. + * As of today, when stopping t_dc_prep we remove the UE + * from X2. To keep the id until the 'reconfiguration complete' message is received + * needs a rethink/rewrite of this logic. For simplicity, let's + * keep it as is. The only problem we can get is if/when we + * interoperate with a non-OAI gNB. The OAI gNB does not + * care about MeNB_ue_x2_id. + */ + X2AP_ENDC_SGNB_RECONF_COMPLETE(msg_p).MeNB_ue_x2_id = 0; + X2AP_ENDC_SGNB_RECONF_COMPLETE(msg_p).SgNB_ue_x2_id = ue_context_p->ue_context.gnb_rnti; + X2AP_ENDC_SGNB_RECONF_COMPLETE(msg_p).gnb_x2_assoc_id = ue_context_p->ue_context.gnb_x2_assoc_id; + itti_send_msg_to_task (TASK_X2AP, ctxt_pP->instance, msg_p); +} + void setup_ngran_CU(eNB_RRC_INST *rrc) { } @@ -7026,6 +7065,8 @@ char openair_rrc_eNB_configuration( openair_rrc_top_init_eNB(RC.rrc[ctxt.module_id]->carrier[CC_id].MBMS_flag,0); } + RC.rrc[ctxt.module_id]->nr_scg_ssb_freq = configuration->nr_scg_ssb_freq; + openair_rrc_on(&ctxt); /* @@ -7044,6 +7085,16 @@ char openair_rrc_eNB_configuration( return 0; } +static +void rrc_eNB_generate_RRCConnectionReestablishmentReject_unknown_UE(protocol_ctxt_t *const ctxt_pP, + const int CC_id) { + struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_next_free_ue_context(ctxt_pP, ctxt_pP->rnti); + rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, + ue_context_p, + CC_id); + ue_context_p->ue_context.ul_failure_timer = 500; // 500 milliseconds to send the message and remove temporary entry +} + /*------------------------------------------------------------------------------*/ int rrc_eNB_decode_ccch( @@ -7122,12 +7173,14 @@ rrc_eNB_decode_ccch( uint16_t c_rnti = 0; if (rrcConnectionReestablishmentRequest->ue_Identity.physCellId != RC.rrc[ctxt_pP->module_id]->carrier[CC_id].physCellId) { + /* UE was moving from previous cell so quickly that RRCConnectionReestablishment for previous cell was recieved in this cell */ LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentRequest ue_Identity.physCellId(%ld) is not equal to current physCellId(%d), let's reject the UE\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), rrcConnectionReestablishmentRequest->ue_Identity.physCellId, RC.rrc[ctxt_pP->module_id]->carrier[CC_id].physCellId); - rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id); + rrc_eNB_generate_RRCConnectionReestablishmentReject_unknown_UE(ctxt_pP, + CC_id); break; } @@ -7140,10 +7193,12 @@ rrc_eNB_decode_ccch( if (rrcConnectionReestablishmentRequest->ue_Identity.c_RNTI.size == 0 || rrcConnectionReestablishmentRequest->ue_Identity.c_RNTI.size > 2) { + /* c_RNTI range error should not happen */ LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentRequest c_RNTI range error, let's reject the UE\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); - rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id); + rrc_eNB_generate_RRCConnectionReestablishmentReject_unknown_UE(ctxt_pP, + CC_id); break; } @@ -7155,7 +7210,8 @@ rrc_eNB_decode_ccch( LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentRequest without UE context, let's reject the UE\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); - rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id); + rrc_eNB_generate_RRCConnectionReestablishmentReject_unknown_UE(ctxt_pP, + CC_id); break; } @@ -7222,8 +7278,10 @@ rrc_eNB_decode_ccch( if(ue_context_p->ue_context.ue_reestablishment_timer > 0) { LOG_E(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" RRRCConnectionReconfigurationComplete(Previous) don't receive, delete the Previous UE\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); + PROTOCOL_RRC_CTXT_UE_FMT" RRRCConnectionReconfigurationComplete(Previous) don't receive, delete the Previous UE,\nprevious Status %d, new Status RRC_RECONFIGURED\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + ue_context_p->ue_context.Status + ); ue_context_p->ue_context.Status = RRC_RECONFIGURED; protocol_ctxt_t ctxt_old_p; PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt_old_p, @@ -7808,8 +7866,7 @@ rrc_eNB_decode_dcch( LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_HO_EXECUTION (xid %ld)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); - } - else if(ue_context_p->ue_context.Status == RRC_NR_NSA){ + } else if(ue_context_p->ue_context.Status == RRC_NR_NSA) { //Looking for a condition to trigger S1AP E-RAB-Modification-indication, based on the reception of RRCConnectionReconfigurationComplete //including NR specific elements. if(ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8. @@ -7830,6 +7887,8 @@ rrc_eNB_decode_dcch( ue_context_p->ue_context.Status = RRC_NR_NSA_RECONFIGURED; /*Trigger E-RAB Modification Indication */ rrc_eNB_send_E_RAB_Modification_Indication(ctxt_pP, ue_context_p); + /* send reconfiguration complete to gNB */ + rrc_eNB_process_reconfiguration_complete_endc(ctxt_pP, ue_context_p); } } } @@ -7837,8 +7896,7 @@ rrc_eNB_decode_dcch( } } } - } - else { + } else { dedicated_DRB = 0; ue_context_p->ue_context.Status = RRC_RECONFIGURED; LOG_I(RRC, @@ -7847,7 +7905,6 @@ rrc_eNB_decode_dcch( } ue_context_p->ue_context.reestablishment_xid = -1; - } else { dedicated_DRB = 1; ue_context_p->ue_context.Status = RRC_RECONFIGURED; @@ -7892,6 +7949,7 @@ rrc_eNB_decode_dcch( msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ); memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p))); GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti; + GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).from_gnb = 0; for(i = 0; i < NB_RB_MAX; i++) { if(xid == ue_context_p->ue_context.e_rab[i].xid) { @@ -8383,8 +8441,7 @@ rrc_eNB_decode_dcch( case LTE_UL_DCCH_MessageType__c1_PR_mbmsCountingResponse_r10: T(T_ENB_RRC_MBMS_COUNTING_RESPONSE_R10, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - LOG_E(RRC, "THINH [LTE_UL_DCCH_MessageType__c1_PR_mbmsCountingResponse_r10]\n"); - + LOG_E(RRC, "THINH [LTE_UL_DCCH_MessageType__c1_PR_mbmsCountingResponse_r10]\n"); break; case LTE_UL_DCCH_MessageType__c1_PR_interFreqRSTDMeasurementIndication_r10: @@ -8412,46 +8469,57 @@ rrc_eNB_decode_dcch( case LTE_UL_DCCH_MessageType__messageClassExtension_PR_c2: //SidelinkUEInformation if(ul_dcch_msg->message.choice.messageClassExtension.choice.c2.present == - LTE_UL_DCCH_MessageType__messageClassExtension__c2_PR_scgFailureInformationNR_r15){ + LTE_UL_DCCH_MessageType__messageClassExtension__c2_PR_scgFailureInformationNR_r15) { if (ul_dcch_msg->message.choice.messageClassExtension.choice.c2.choice.scgFailureInformationNR_r15. - criticalExtensions.present == LTE_SCGFailureInformationNR_r15__criticalExtensions_PR_c1){ + criticalExtensions.present == LTE_SCGFailureInformationNR_r15__criticalExtensions_PR_c1) { if (ul_dcch_msg->message.choice.messageClassExtension.choice.c2.choice.scgFailureInformationNR_r15.criticalExtensions. - choice.c1.present == LTE_SCGFailureInformationNR_r15__criticalExtensions__c1_PR_scgFailureInformationNR_r15){ + choice.c1.present == LTE_SCGFailureInformationNR_r15__criticalExtensions__c1_PR_scgFailureInformationNR_r15) { if (ul_dcch_msg->message.choice.messageClassExtension.choice.c2.choice.scgFailureInformationNR_r15.criticalExtensions. - choice.c1.choice.scgFailureInformationNR_r15.failureReportSCG_NR_r15!=NULL) { + choice.c1.choice.scgFailureInformationNR_r15.failureReportSCG_NR_r15!=NULL) { LOG_E(RRC, "Received NR scgFailureInformation from UE, failure type: %ld \n", - ul_dcch_msg->message.choice.messageClassExtension.choice.c2.choice.scgFailureInformationNR_r15.criticalExtensions. - choice.c1.choice.scgFailureInformationNR_r15.failureReportSCG_NR_r15->failureType_r15); + ul_dcch_msg->message.choice.messageClassExtension.choice.c2.choice.scgFailureInformationNR_r15.criticalExtensions. + choice.c1.choice.scgFailureInformationNR_r15.failureReportSCG_NR_r15->failureType_r15); xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)ul_dcch_msg); + + /* TODO: scg failure indication, what to do? Let's remove the UE for now. + * We could re-establish DRB? + * Also, the way to remove is to start ue_release_timer_rrc and + * send RRCConnectionRelease to the UE, maybe it's not good/correct. + */ + if (ue_context_p != NULL) { + ue_context_p->ue_context.ue_release_timer_thres_rrc = 100; + ue_context_p->ue_context.ue_release_timer_rrc = 1; + rrc_eNB_generate_RRCConnectionRelease(ctxt_pP, ue_context_p); + } } } } - } - else if(ul_dcch_msg->message.choice.messageClassExtension.choice.c2.present == LTE_UL_DCCH_MessageType__messageClassExtension__c2_PR_sidelinkUEInformation_r12){ + } else if(ul_dcch_msg->message.choice.messageClassExtension.choice.c2.present == LTE_UL_DCCH_MessageType__messageClassExtension__c2_PR_sidelinkUEInformation_r12) { //case UL_DCCH_MessageType__messageClassExtension__c2_PR_sidelinkUEInformation_r12: //SidelinkUEInformation LOG_I(RRC,"THINH [LTE_UL_DCCH_MessageType__messageClassExtension_PR_c2]\n"); LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, - "[MSG] RRC SidelinkUEInformation \n"); + "[MSG] RRC SidelinkUEInformation \n"); MSC_LOG_RX_MESSAGE( - MSC_RRC_ENB, - MSC_RRC_UE, - Rx_sdu, - sdu_sizeP, - MSC_AS_TIME_FMT" SidelinkUEInformation UE %x size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_p->ue_context.rnti, - sdu_sizeP); - LOG_I(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " - "(SidelinkUEInformation) ---> RRC_eNB\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - DCCH, + MSC_RRC_ENB, + MSC_RRC_UE, + Rx_sdu, + sdu_sizeP, + MSC_AS_TIME_FMT" SidelinkUEInformation UE %x size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->ue_context.rnti, sdu_sizeP); + LOG_I(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " + "(SidelinkUEInformation) ---> RRC_eNB\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + DCCH, + sdu_sizeP); rrc_eNB_process_SidelinkUEInformation( ctxt_pP, ue_context_p, &ul_dcch_msg->message.choice.messageClassExtension.choice.c2.choice.sidelinkUEInformation_r12); - } + } + break; default: @@ -8618,17 +8686,14 @@ void rrc_enb_init(void) { //----------------------------------------------------------------------------- void process_successful_rlc_sdu_indication(int instance, - int rnti, - int message_id) -{ + int rnti, + int message_id) { int release_num; int release_total; RRC_release_ctrl_t *release_ctrl; - /* Check if the message sent was RRC Connection Release. * If yes then continue the release process. */ - pthread_mutex_lock(&rrc_release_freelist); if (rrc_release_info.num_UEs > 0) { @@ -8670,14 +8735,11 @@ void process_successful_rlc_sdu_indication(int instance, } //----------------------------------------------------------------------------- -void process_unsuccessful_rlc_sdu_indication(int instance, int rnti) -{ +void process_unsuccessful_rlc_sdu_indication(int instance, int rnti) { int release_num; int release_total; RRC_release_ctrl_t *release_ctrl; - /* radio link failure detected by RLC layer, remove UE properly */ - pthread_mutex_lock(&rrc_release_freelist); /* first, check if the rnti is in the list rrc_release_info.RRC_release_ctrl */ @@ -8745,8 +8807,7 @@ void process_rlc_sdu_indication(int instance, int rnti, int is_successful, int srb_id, - int message_id) -{ + int message_id) { if (is_successful) process_successful_rlc_sdu_indication(instance, rnti, message_id); else @@ -8980,6 +9041,19 @@ void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) { ue_to_be_removed[cur_ue]->ue_context.ue_reestablishment_timer = 0; } + /* remove UE from gNB if UE is in NSA mode */ + if (ue_to_be_removed[cur_ue]->ue_context.Status == RRC_NR_NSA || + ue_to_be_removed[cur_ue]->ue_context.Status == RRC_NR_NSA_RECONFIGURED) { + MessageDef *message_p; + message_p = itti_alloc_new_message(TASK_RRC_ENB, X2AP_ENDC_SGNB_RELEASE_REQUEST); + X2AP_ENDC_SGNB_RELEASE_REQUEST(message_p).rnti = ue_to_be_removed[cur_ue]->ue_context.gnb_rnti; + X2AP_ENDC_SGNB_RELEASE_REQUEST(message_p).assoc_id = ue_to_be_removed[cur_ue]->ue_context.gnb_x2_assoc_id; + X2AP_ENDC_SGNB_RELEASE_REQUEST(message_p).cause = X2AP_CAUSE_RADIO_CONNECTION_WITH_UE_LOST; + itti_send_msg_to_task(TASK_X2AP, ctxt_pP->module_id, message_p); + /* set state to RRC_NR_NSA_DELETED to avoid sending X2AP_ENDC_SGNB_RELEASE_REQUEST again later */ + ue_to_be_removed[cur_ue]->ue_context.Status = RRC_NR_NSA_DELETED; + } + rrc_eNB_free_UE(ctxt_pP->module_id, ue_to_be_removed[cur_ue]); if (ue_to_be_removed[cur_ue]->ue_context.ul_failure_timer >= 20000) { @@ -9023,6 +9097,27 @@ void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX, VCD_FUNCTION_OUT); } +void rrc_eNB_process_ENDC_x2_setup_request(int mod_id, x2ap_ENDC_setup_req_t *m) { + if (RC.rrc[mod_id]->num_neigh_cells > MAX_NUM_NEIGH_CELLs) { + LOG_E(RRC, "Error: number of neighbouring cells is exceeded \n"); + return; + } + + if (m->num_cc > MAX_NUM_CCs) { + LOG_E(RRC, "Error: number of neighbouring cells carriers is exceeded \n"); + return; + } + + RC.rrc[mod_id]->num_neigh_cells++; + RC.rrc[mod_id]->num_neigh_cells_cc[RC.rrc[mod_id]->num_neigh_cells-1] = m->num_cc; + + for (int i=0; inum_cc; i++) { + RC.rrc[mod_id]->neigh_cells_id[RC.rrc[mod_id]->num_neigh_cells-1][i] = m->Nid_cell[i]; + RC.rrc[mod_id]->nr_neigh_freq_band[RC.rrc[mod_id]->num_neigh_cells-1][i] = m->servedNrCell_band[i]; + } + +} + void rrc_eNB_process_AdditionResponseInformation(const module_id_t enb_mod_idP, x2ap_ENDC_sgnb_addition_req_ACK_t *m) { NR_CG_Config_t *CG_Config = NULL; { @@ -9089,51 +9184,101 @@ void rrc_eNB_process_AdditionResponseInformation(const module_id_t enb_mod_idP, return; } - protocol_ctxt_t ctxt; - rrc_eNB_ue_context_t *ue_context; - unsigned char buffer[8192]; - int size; + protocol_ctxt_t ctxt; + rrc_eNB_ue_context_t *ue_context; + unsigned char buffer[8192]; + int size; + ue_context = rrc_eNB_get_ue_context(RC.rrc[enb_mod_idP], m->rnti); - ue_context = rrc_eNB_get_ue_context(RC.rrc[enb_mod_idP], m->rnti); - if (ue_context) { - ue_context->ue_context.nb_of_modify_endc_e_rabs = m->nb_e_rabs_admitted_tobeadded; + if (ue_context) { + ue_context->ue_context.nb_of_modify_endc_e_rabs = m->nb_e_rabs_admitted_tobeadded; - int j=0; - while(j < m->nb_e_rabs_admitted_tobeadded){ - for (int e_rab_idx=0; e_rab_idxue_context.setup_e_rabs; e_rab_idx++){ - //Update ue_context information with gNB's address and new GTP tunnel ID - if( ue_context->ue_context.e_rab[e_rab_idx].param.e_rab_id == m->e_rabs_admitted_tobeadded[j].e_rab_id){ - memcpy(ue_context->ue_context.gnb_gtp_endc_addrs[e_rab_idx].buffer, - m->e_rabs_admitted_tobeadded[j].gnb_addr.buffer, - m->e_rabs_admitted_tobeadded[j].gnb_addr.length); - ue_context->ue_context.gnb_gtp_endc_addrs[e_rab_idx].length = m->e_rabs_admitted_tobeadded[j].gnb_addr.length; - ue_context->ue_context.gnb_gtp_endc_teid[e_rab_idx] = m->e_rabs_admitted_tobeadded[j].gtp_teid; - ue_context->ue_context.e_rab[e_rab_idx].status = E_RAB_STATUS_TOMODIFY; - break; - } - } - j++; + ue_context->ue_context.gnb_rnti = m->SgNB_ue_x2_id; + ue_context->ue_context.gnb_x2_assoc_id = m->gnb_x2_assoc_id; + + int j=0; + + while(j < m->nb_e_rabs_admitted_tobeadded) { + for (int e_rab_idx=0; e_rab_idxue_context.setup_e_rabs; e_rab_idx++) { + //Update ue_context information with gNB's address and new GTP tunnel ID + if( ue_context->ue_context.e_rab[e_rab_idx].param.e_rab_id == m->e_rabs_admitted_tobeadded[j].e_rab_id) { + memcpy(ue_context->ue_context.gnb_gtp_endc_addrs[e_rab_idx].buffer, + m->e_rabs_admitted_tobeadded[j].gnb_addr.buffer, + m->e_rabs_admitted_tobeadded[j].gnb_addr.length); + ue_context->ue_context.gnb_gtp_endc_addrs[e_rab_idx].length = m->e_rabs_admitted_tobeadded[j].gnb_addr.length; + ue_context->ue_context.gnb_gtp_endc_teid[e_rab_idx] = m->e_rabs_admitted_tobeadded[j].gtp_teid; + ue_context->ue_context.e_rab[e_rab_idx].status = E_RAB_STATUS_TOMODIFY; + break; + } } - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, - 0, - ENB_FLAG_YES, - m->rnti, - 0, 0); - - size = rrc_eNB_generate_RRCConnectionReconfiguration_endc(&ctxt, ue_context, buffer, 8192, scg_CellGroupConfig, nr1_conf); - - rrc_data_req(&ctxt, - DCCH, - rrc_eNB_mui++, - SDU_CONFIRM_NO, - size, - buffer, - PDCP_TRANSMISSION_MODE_CONTROL); - } else { - LOG_E(F1AP, "no ue_context for RNTI %x, acknowledging release\n", m->rnti); + j++; } + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, + 0, + ENB_FLAG_YES, + m->rnti, + 0, 0); + size = rrc_eNB_generate_RRCConnectionReconfiguration_endc(&ctxt, ue_context, buffer, 8192, scg_CellGroupConfig, nr1_conf); + rrc_data_req(&ctxt, + DCCH, + rrc_eNB_mui++, + SDU_CONFIRM_NO, + size, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); + } else { + LOG_E(F1AP, "no ue_context for RNTI %x, acknowledging release\n", m->rnti); + } +} + +void rrc_eNB_process_ENDC_DC_prep_timeout(module_id_t module_id, x2ap_ENDC_dc_prep_timeout_t *m) +{ + rrc_eNB_ue_context_t *ue_context; + + ue_context = rrc_eNB_get_ue_context(RC.rrc[module_id], m->rnti); + if (ue_context == NULL) { + LOG_E(RRC, "receiving DC prep timeout for unknown UE rnti %d\n", m->rnti); + return; + } + + if (ue_context->ue_context.Status != RRC_NR_NSA) { + LOG_E(RRC, "receiving DC prep timeout for UE rnti %d not in state RRC_NR_NSA\n", m->rnti); + return; + } + + LOG_I(RRC, "DC prep timeout for UE rnti %d, put back to RRC_RECONFIGURED mode\n", m->rnti); + ue_context->ue_context.Status = RRC_RECONFIGURED; +} + +void rrc_eNB_process_ENDC_sgNB_release_required(module_id_t module_id, x2ap_ENDC_sgnb_release_required_t *m) +{ + rrc_eNB_ue_context_t *ue_context; + protocol_ctxt_t ctxt; + + ue_context = rrc_eNB_find_ue_context_from_gnb_rnti(RC.rrc[module_id], m->gnb_rnti); + if (ue_context == NULL) { + LOG_E(RRC, "receiving ENDC SgNB Release Required for unknown UE (with gNB's rnti %d)\n", m->gnb_rnti); + return; + } + + /* TODO: what to do? release the UE? if yes, how? Or re-establish bearers in LTE? + * Or something else? + * The following removes the UE, maybe it's not correct at all. + */ + ue_context->ue_context.ue_release_timer_thres_rrc = 100; + ue_context->ue_context.ue_release_timer_rrc = 1; + + ue_context->ue_context.Status = RRC_NR_NSA_DELETED; + + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, + module_id, /* TODO: should be 'instance' */ + ENB_FLAG_YES, + ue_context->ue_context.rnti, + 0, 0); + + rrc_eNB_generate_RRCConnectionRelease(&ctxt, ue_context); } //----------------------------------------------------------------------------- @@ -9414,11 +9559,25 @@ void *rrc_enb_process_itti_msg(void *notUsed) { break; } + case X2AP_ENDC_SETUP_REQ: + rrc_eNB_process_ENDC_x2_setup_request(instance, &X2AP_ENDC_SETUP_REQ(msg_p)); + break; + case X2AP_ENDC_SGNB_ADDITION_REQ_ACK: { rrc_eNB_process_AdditionResponseInformation(ENB_INSTANCE_TO_MODULE_ID(instance), &X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg_p)); break; } + case X2AP_ENDC_DC_PREP_TIMEOUT: { + rrc_eNB_process_ENDC_DC_prep_timeout(ENB_INSTANCE_TO_MODULE_ID(instance), &X2AP_ENDC_DC_PREP_TIMEOUT(msg_p)); + break; + } + + case X2AP_ENDC_SGNB_RELEASE_REQUIRED: { + rrc_eNB_process_ENDC_sgNB_release_required(ENB_INSTANCE_TO_MODULE_ID(instance), &X2AP_ENDC_SGNB_RELEASE_REQUIRED(msg_p)); + break; + } + /* Messages from eNB app */ case RRC_CONFIGURATION_REQ: LOG_I(RRC, "[eNB %d] Received %s : %p\n", instance, msg_name_p, &RRC_CONFIGURATION_REQ(msg_p)); @@ -9470,8 +9629,8 @@ void *rrc_enb_process_itti_msg(void *notUsed) { break; case M2AP_MCE_CONFIGURATION_UPDATE: - rrc_eNB_process_M2AP_MCE_CONFIGURATION_UPDATE(&ctxt,&M2AP_MCE_CONFIGURATION_UPDATE(msg_p)); - break; + rrc_eNB_process_M2AP_MCE_CONFIGURATION_UPDATE(&ctxt,&M2AP_MCE_CONFIGURATION_UPDATE(msg_p)); + break; case RLC_SDU_INDICATION: process_rlc_sdu_indication(instance, @@ -9515,7 +9674,7 @@ rrc_enb_task( //if (go_nr) rrc_go_nr(); } } - } +} /*------------------------------------------------------------------------------*/ void diff --git a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c index 1025d46f62..5c25d2dbcf 100644 --- a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c +++ b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c @@ -189,6 +189,7 @@ void rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ( MessageDef *msg = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ); memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg))); GTPV1U_ENB_DELETE_TUNNEL_REQ(msg).rnti = ue_context_pP->ue_context.rnti; + GTPV1U_ENB_DELETE_TUNNEL_REQ(msg).from_gnb = 0; GTPV1U_ENB_DELETE_TUNNEL_REQ(msg).num_erab = ue_context_pP->ue_context.nb_of_e_rabs; for (int e_rab = 0; e_rab < ue_context_pP->ue_context.nb_of_e_rabs; e_rab++) { const rb_id_t gtp_ebi = ue_context_pP->ue_context.enb_gtp_ebi[e_rab]; diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index 9f92be366b..4be9a50b32 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -1751,6 +1751,7 @@ int rrc_eNB_process_S1AP_E_RAB_RELEASE_COMMAND(MessageDef *msg_p, const char *ms msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ); memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p))); GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti; + GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).from_gnb = 0; for(i = 0; i < NB_RB_MAX; i++) { if(xid == ue_context_p->ue_context.e_rab[i].xid) { diff --git a/openair2/RRC/LTE/rrc_eNB_UE_context.c b/openair2/RRC/LTE/rrc_eNB_UE_context.c index 197aedae51..2cc89adf15 100644 --- a/openair2/RRC/LTE/rrc_eNB_UE_context.c +++ b/openair2/RRC/LTE/rrc_eNB_UE_context.c @@ -173,6 +173,23 @@ rrc_eNB_get_ue_context( } +//------------------------------------------------------------------------------ +struct rrc_eNB_ue_context_s * +rrc_eNB_find_ue_context_from_gnb_rnti( + eNB_RRC_INST *rrc_instance_pP, + int gnb_rnti) +//------------------------------------------------------------------------------ +{ + struct rrc_eNB_ue_context_s *ue_context_p = NULL; + RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(rrc_instance_pP->rrc_ue_head)) { + if (ue_context_p->ue_context.gnb_rnti == gnb_rnti) { + return ue_context_p; + } + } + return NULL; +} + + //------------------------------------------------------------------------------ void rrc_eNB_remove_ue_context( const protocol_ctxt_t *const ctxt_pP, diff --git a/openair2/RRC/LTE/rrc_eNB_UE_context.h b/openair2/RRC/LTE/rrc_eNB_UE_context.h index e22f517d50..c6420ca936 100644 --- a/openair2/RRC/LTE/rrc_eNB_UE_context.h +++ b/openair2/RRC/LTE/rrc_eNB_UE_context.h @@ -73,6 +73,11 @@ rrc_eNB_get_ue_context( rnti_t rntiP ); +struct rrc_eNB_ue_context_s * +rrc_eNB_find_ue_context_from_gnb_rnti( + eNB_RRC_INST *rrc_instance_pP, + int gnb_rnti); + void rrc_eNB_remove_ue_context( const protocol_ctxt_t* const ctxt_pP, eNB_RRC_INST* rrc_instance_pP, diff --git a/openair2/RRC/LTE/rrc_proto.h b/openair2/RRC/LTE/rrc_proto.h index 8f6baabcbf..c50ddf3189 100644 --- a/openair2/RRC/LTE/rrc_proto.h +++ b/openair2/RRC/LTE/rrc_proto.h @@ -360,6 +360,8 @@ void rrc_eNB_process_x2_setup_response(int mod_id, x2ap_setup_resp_t *m); void rrc_eNB_process_handoverPreparationInformation(int mod_id, x2ap_handover_req_t *m); +void rrc_eNB_process_ENDC_x2_setup_request(int mod_id, x2ap_ENDC_setup_req_t *m); + /**\brief Generate/decode the handover RRCConnectionReconfiguration at eNB \param module_idP Instance ID for eNB/CH \param frame Frame index diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index 317282c814..3a6bbfd5a3 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -69,6 +69,8 @@ void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc,LTE_UE_CapabilityRAT_ContainerL void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_p, x2ap_ENDC_sgnb_addition_req_t *m); +void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti); + void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellconfigcommon, NR_CellGroupConfig_t *secondaryCellGroup, int scg_id, @@ -97,3 +99,5 @@ int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo, x2 \param void *args_p Pointer on arguments to start the task. */ void *rrc_gnb_task(void *args_p); +/* Trigger RRC periodic processing. To be called once per ms. */ +void nr_rrc_trigger(protocol_ctxt_t *ctxt, int CC_id, int frame, int subframe); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 5721d05aee..757724765e 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -301,6 +301,26 @@ void rrc_gNB_process_AdditionRequestInformation(const module_id_t gnb_mod_idP, x parse_CG_ConfigInfo(rrc,cg_configinfo,m); } +void rrc_gNB_process_release_request(const module_id_t gnb_mod_idP, x2ap_ENDC_sgnb_release_request_t *m) +{ + gNB_RRC_INST *rrc = RC.nrrrc[gnb_mod_idP]; + rrc_remove_nsa_user(rrc, m->rnti); +} + +void rrc_gNB_process_dc_overall_timeout(const module_id_t gnb_mod_idP, x2ap_ENDC_dc_overall_timeout_t *m) +{ + gNB_RRC_INST *rrc = RC.nrrrc[gnb_mod_idP]; + rrc_remove_nsa_user(rrc, m->rnti); +} + +void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) { + MessageDef *msg; + + /* send a tick to x2ap */ + msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_SUBFRAME_PROCESS); + itti_send_msg_to_task(TASK_X2AP, ctxt_pP->module_id, msg); +} + ///---------------------------------------------------------------------------------------------------------------/// ///---------------------------------------------------------------------------------------------------------------/// void *rrc_gnb_task(void *args_p) { @@ -319,7 +339,10 @@ void *rrc_gnb_task(void *args_p) { itti_receive_msg(TASK_RRC_GNB, &msg_p); msg_name_p = ITTI_MSG_NAME(msg_p); instance = ITTI_MSG_INSTANCE(msg_p); - LOG_I(NR_RRC,"Received message %s\n",msg_name_p); + + /* RRC_SUBFRAME_PROCESS is sent every subframe, do not log it */ + if (ITTI_MSG_ID(msg_p) != RRC_SUBFRAME_PROCESS) + LOG_I(NR_RRC,"Received message %s\n",msg_name_p); switch (ITTI_MSG_ID(msg_p)) { case TERMINATE_MESSAGE: @@ -333,6 +356,10 @@ void *rrc_gnb_task(void *args_p) { /* Messages from MAC */ + case RRC_SUBFRAME_PROCESS: + nr_rrc_subframe_process(&RRC_SUBFRAME_PROCESS(msg_p).ctxt, RRC_SUBFRAME_PROCESS(msg_p).CC_id); + break; + /* Messages from PDCP */ /* @@ -406,6 +433,20 @@ void *rrc_gnb_task(void *args_p) { LOG_I(NR_RRC, "Handling of reconfiguration complete message at RRC gNB is pending \n"); break; + case X2AP_ENDC_SGNB_RELEASE_REQUEST: + LOG_I(NR_RRC, "Received ENDC sgNB release request from X2AP \n"); + rrc_gNB_process_release_request(GNB_INSTANCE_TO_MODULE_ID(instance), &X2AP_ENDC_SGNB_RELEASE_REQUEST(msg_p)); + break; + + case X2AP_ENDC_DC_OVERALL_TIMEOUT: + rrc_gNB_process_dc_overall_timeout(GNB_INSTANCE_TO_MODULE_ID(instance), &X2AP_ENDC_DC_OVERALL_TIMEOUT(msg_p)); + break; + + /* Messages from GTP */ + case GTPV1U_ENB_DELETE_TUNNEL_RESP: + /* nothing to do? */ + break; + default: LOG_E(NR_RRC, "[gNB %d] Received unexpected message %s\n", instance, msg_name_p); break; @@ -417,3 +458,11 @@ void *rrc_gnb_task(void *args_p) { } } +void nr_rrc_trigger(protocol_ctxt_t *ctxt, int CC_id, int frame, int subframe) +{ + MessageDef *message_p; + message_p = itti_alloc_new_message(TASK_RRC_GNB, RRC_SUBFRAME_PROCESS); + RRC_SUBFRAME_PROCESS(message_p).ctxt = *ctxt; + RRC_SUBFRAME_PROCESS(message_p).CC_id = CC_id; + itti_send_msg_to_task(TASK_RRC_GNB, ctxt->module_id, message_p); +} diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 78f39c16d7..7b7647a746 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -27,8 +27,6 @@ * \company Eurecom * \email: raymond.knopp@eurecom.fr */ -#ifndef RRC_GNB_NSA_C -#define RRC_GNB_NSA_C #include "nr_rrc_defs.h" #include "NR_RRCReconfiguration.h" @@ -247,15 +245,21 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ LOG_W(RRC, "No E-RAB to be added received from SgNB Addition Request message \n"); } - //X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer_size = CG_Config_size; //Need to verify correct value for the buffer_size - // Send to X2 entity to transport to MeNB - asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CG_Config, - NULL, - (void *)CG_Config, - X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer, - 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 + if (m != NULL) { + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).MeNB_ue_x2_id = m->ue_x2_id; + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).SgNB_ue_x2_id = ue_context_p->ue_context.secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity; + + //X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer_size = CG_Config_size; //Need to verify correct value for the buffer_size + // Send to X2 entity to transport to MeNB + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CG_Config, + NULL, + (void *)CG_Config, + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer, + 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 + } + rrc->Nb_ue++; // configure MAC and RLC rrc_mac_config_req_gNB(rrc->module_id, @@ -290,5 +294,45 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ } +void rrc_remove_nsa_user(gNB_RRC_INST *rrc, int rnti) { + protocol_ctxt_t ctxt; + rrc_gNB_ue_context_t *ue_context; + MessageDef *msg_delete_tunnels_p; + int e_rab; -#endif + LOG_D(RRC, "calling rrc_remove_nsa_user rnti %d\n", rnti); + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, rnti, 0, 0, rrc->module_id); + + ue_context = rrc_gNB_get_ue_context(rrc, rnti); + if (ue_context == NULL) { + LOG_W(RRC, "rrc_remove_nsa_user: rnti %d not found\n", rnti); + return; + } + + pdcp_remove_UE(&ctxt); + + rrc_rlc_remove_ue(&ctxt); + + mac_remove_nr_ue(rrc->module_id, rnti); + + /* delete gtp tunnel */ + msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_GNB, GTPV1U_ENB_DELETE_TUNNEL_REQ); + memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p))); + GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = rnti; + GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).from_gnb = 1; + + LOG_D(RRC, "ue_context->ue_context.nb_of_e_rabs %d\n", ue_context->ue_context.nb_of_e_rabs); + for (e_rab = 0; e_rab < ue_context->ue_context.nb_of_e_rabs; e_rab++) { + GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] = + ue_context->ue_context.gnb_gtp_ebi[e_rab]; + // erase data + ue_context->ue_context.gnb_gtp_teid[e_rab] = 0; + memset(&ue_context->ue_context.gnb_gtp_addrs[e_rab], 0, sizeof(ue_context->ue_context.gnb_gtp_addrs[e_rab])); + ue_context->ue_context.gnb_gtp_ebi[e_rab] = 0; + } + + itti_send_msg_to_task(TASK_GTPV1_U, rrc->module_id, msg_delete_tunnels_p); + + /* remove context */ + rrc_gNB_remove_ue_context(&ctxt, rrc, ue_context); +} diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 44215df218..1e182eff8b 100755 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -399,9 +399,9 @@ int8_t nr_rrc_ue_decode_NR_BCCH_BCH_Message( } - for(i=0; iid_manager); x2ap_timers_init(&new_instance->timers, x2ap_register_eNB->t_reloc_prep, - x2ap_register_eNB->tx2_reloc_overall); + x2ap_register_eNB->tx2_reloc_overall, + x2ap_register_eNB->t_dc_prep, + x2ap_register_eNB->t_dc_overall); for (int i = 0; i< x2ap_register_eNB->num_cc; i++) { new_instance->eutra_band[i] = x2ap_register_eNB->eutra_band[i]; @@ -476,7 +478,10 @@ void x2ap_eNB_handle_sgNB_add_req(instance_t instance, } /* id_source is ue_id, id_target is unknown yet */ x2ap_set_ids(id_manager, ue_id, x2ap_ENDC_sgnb_addition_req->rnti, ue_id, -1); - x2ap_id_set_state(id_manager, ue_id, X2ID_STATE_NSA_PREPARE); + x2ap_id_set_state(id_manager, ue_id, X2ID_STATE_NSA_ENB_PREPARE); + x2ap_set_dc_prep_timer(id_manager, ue_id, + x2ap_timer_get_tti(&instance_p->timers)); + x2ap_id_set_target(id_manager, ue_id, x2ap_eNB_data); x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(instance_p, x2ap_ENDC_sgnb_addition_req, x2ap_eNB_data, ue_id); @@ -498,9 +503,6 @@ void x2ap_gNB_trigger_sgNB_add_req_ack(instance_t instance, x2ap_eNB_instance_t *instance_p; x2ap_eNB_data_t *target; int ue_id; - /*int source_assoc_id = x2ap_ENDC_sgnb_addition_req_ACK->source_assoc_id; - int id_source; - int id_target;*/ instance_p = x2ap_eNB_get_instance(instance); DevAssert(instance_p != NULL); @@ -514,22 +516,15 @@ void x2ap_gNB_trigger_sgNB_add_req_ack(instance_t instance, X2AP_ERROR("could not allocate a new X2AP UE ID\n"); exit(1); } - /* id_source is ue_id, id_target is unknown yet */ - x2ap_set_ids(id_manager, ue_id, x2ap_ENDC_sgnb_addition_req_ACK->rnti, ue_id, - x2ap_ENDC_sgnb_addition_req_ACK->MeNB_ue_x2_id); - x2ap_id_set_state(id_manager, ue_id, X2ID_STATE_SOURCE_OVERALL); - - - /*target = x2ap_get_eNB(NULL, source_assoc_id, 0); - DevAssert(target != NULL);*/ - - // rnti is a new information, save it - - /*ue_id = x2ap_handover_req_ack->x2_id_target; - id_source = x2ap_id_get_id_source(&instance_p->id_manager, ue_id); - id_target = ue_id; - x2ap_set_ids(&instance_p->id_manager, ue_id, x2ap_handover_req_ack->rnti, id_source, id_target);*/ - + /* id_Source is MeNB_ue_x2_id, id_target is rnti (rnti is SgNB_ue_x2_id) */ + x2ap_set_ids(id_manager, ue_id, + x2ap_ENDC_sgnb_addition_req_ACK->SgNB_ue_x2_id, + x2ap_ENDC_sgnb_addition_req_ACK->MeNB_ue_x2_id, + x2ap_ENDC_sgnb_addition_req_ACK->SgNB_ue_x2_id); + x2ap_id_set_state(id_manager, ue_id, X2ID_STATE_NSA_GNB_OVERALL); + x2ap_set_dc_overall_timer(id_manager, ue_id, + x2ap_timer_get_tti(&instance_p->timers)); + x2ap_id_set_target(id_manager, ue_id, target); x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK(instance_p, target, x2ap_ENDC_sgnb_addition_req_ACK, ue_id); @@ -540,27 +535,24 @@ void x2ap_gNB_trigger_sgNB_add_req_ack(instance_t instance, * @param : IN instance, IN x2ap_reconf_complete **/ static -void x2ap_eNB_trigger_sgnb_reconfiguration_complete(instance_t instance, - x2ap_ENDC_reconf_complete_t *x2ap_reconf_complete) +void x2ap_eNB_trigger_sgnb_reconfiguration_complete(instance_t instance, + x2ap_ENDC_reconf_complete_t *x2ap_reconf_complete) { - x2ap_eNB_instance_t *instance_p = NULL; - x2ap_eNB_data_t *target = NULL; - int id_source = -1; - int id_target = -1; - LTE_PhysCellId_t target_pci; - + x2ap_eNB_instance_t *instance_p; + x2ap_eNB_data_t *target; + int id_source; + int id_target; + instance_p = x2ap_eNB_get_instance(instance); DevAssert(instance_p != NULL); DevAssert(x2ap_reconf_complete != NULL); - - target_pci = x2ap_reconf_complete->target_physCellId; - target = x2ap_is_eNB_pci_in_list(target_pci); + + target = x2ap_get_eNB(NULL,x2ap_reconf_complete->gnb_x2_assoc_id, 0); DevAssert(target != NULL); - + id_source = x2ap_reconf_complete->MeNB_ue_x2_id; id_target = x2ap_reconf_complete->SgNB_ue_x2_id; x2ap_eNB_generate_ENDC_x2_SgNB_reconfiguration_complete(instance_p, target, id_source, id_target); - } @@ -589,6 +581,34 @@ void x2ap_eNB_ue_context_release(instance_t instance, x2ap_release_id(&instance_p->id_manager, ue_id); } +static +void x2ap_eNB_handle_sgNB_release_request(instance_t instance, + x2ap_ENDC_sgnb_release_request_t *x2ap_release_req) +{ + x2ap_eNB_instance_t *instance_p; + x2ap_eNB_data_t *target; + + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + DevAssert(x2ap_release_req != NULL); + + if (x2ap_release_req->rnti == -1 || + x2ap_release_req->assoc_id == -1) { + X2AP_WARN("x2ap_eNB_handle_sgNB_release_request: bad rnti or assoc_id, do not send release request to gNB\n"); + return; + } + + target = x2ap_get_eNB(NULL, x2ap_release_req->assoc_id, 0); + DevAssert(target != NULL); + + /* id_source is not used by oai's gNB so it's not big deal. For + * interoperability with other gNBs things may need to be refined. + */ + x2ap_eNB_generate_ENDC_x2_SgNB_release_request(instance_p, target, + 0, x2ap_release_req->rnti, + x2ap_release_req->cause); +} + void *x2ap_task(void *arg) { MessageDef *received_msg = NULL; int result; @@ -640,10 +660,16 @@ void *x2ap_task(void *arg) { LOG_I(X2AP, "Received elements for X2AP_ENDC_SGNB_ADDITION_REQ_ACK \n"); break; - case X2AP_ENDC_SGNB_RECONF_COMPLETE: - x2ap_eNB_trigger_sgnb_reconfiguration_complete(ITTI_MESSAGE_GET_INSTANCE(received_msg), - &X2AP_ENDC_SGNB_RECONF_COMPLETE(received_msg)); - break; + case X2AP_ENDC_SGNB_RECONF_COMPLETE: + x2ap_eNB_trigger_sgnb_reconfiguration_complete(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &X2AP_ENDC_SGNB_RECONF_COMPLETE(received_msg)); + break; + + case X2AP_ENDC_SGNB_RELEASE_REQUEST: + x2ap_eNB_handle_sgNB_release_request(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &X2AP_ENDC_SGNB_RELEASE_REQUEST(received_msg)); + break; + case SCTP_INIT_MSG_MULTI_CNF: x2ap_eNB_handle_sctp_init_msg_multi_cnf(ITTI_MESSAGE_GET_INSTANCE(received_msg), &received_msg->ittiMsg.sctp_init_msg_multi_cnf); diff --git a/openair2/X2AP/x2ap_eNB_decoder.c b/openair2/X2AP/x2ap_eNB_decoder.c index 3762bc06dc..6d7897bf14 100644 --- a/openair2/X2AP/x2ap_eNB_decoder.c +++ b/openair2/X2AP/x2ap_eNB_decoder.c @@ -69,6 +69,14 @@ static int x2ap_eNB_decode_initiating_message(X2AP_X2AP_PDU_t *pdu) X2AP_INFO("X2AP_ProcedureCode_id_sgNBReconfigurationCompletion message!\n"); break; + case X2AP_ProcedureCode_id_meNBinitiatedSgNBRelease: + X2AP_INFO("X2AP_ProcedureCode_id_meNBinitiatedSgNBRelease message!\n"); + break; + + case X2AP_ProcedureCode_id_sgNBinitiatedSgNBRelease: + X2AP_INFO("X2AP_ProcedureCode_id_sgNBinitiatedSgNBRelease message!\n"); + break; + default: X2AP_ERROR("Unknown procedure ID (%d) for initiating message\n", (int)pdu->choice.initiatingMessage.procedureCode); @@ -103,6 +111,10 @@ static int x2ap_eNB_decode_successful_outcome(X2AP_X2AP_PDU_t *pdu) X2AP_INFO("x2ap_eNB_decode_successfuloutcome_message!\n"); break; + case X2AP_ProcedureCode_id_meNBinitiatedSgNBRelease: + X2AP_INFO("meNBinitiatedSgNBRelease successful outcome!\n"); + break; + default: X2AP_ERROR("Unknown procedure ID (%d) for successfull outcome message\n", (int)pdu->choice.successfulOutcome.procedureCode); diff --git a/openair2/X2AP/x2ap_eNB_defs.h b/openair2/X2AP/x2ap_eNB_defs.h index 6ab62ebf98..3d8efd8cd4 100644 --- a/openair2/X2AP/x2ap_eNB_defs.h +++ b/openair2/X2AP/x2ap_eNB_defs.h @@ -119,6 +119,8 @@ typedef struct x2ap_eNB_data_s { /* Nid cells */ uint32_t Nid_cell[MAX_NUM_CCs]; int num_cc; + /*Frequency band of NR neighbor cell supporting ENDC NSA */ + uint32_t servedNrCell_band[MAX_NUM_CCs]; /* Only meaningfull in virtual mode */ struct x2ap_eNB_instance_s *x2ap_eNB_instance; diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c index a96fa14f48..1e549d8cbe 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.c +++ b/openair2/X2AP/x2ap_eNB_generate_messages.c @@ -1317,7 +1317,7 @@ MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length freq_band = calloc(1, sizeof(X2AP_FreqBandNrItem_t)); if (freq_band == NULL) exit(1); - freq_band->freqBandIndicatorNr = 1; /* TODO: put correct value */ + freq_band->freqBandIndicatorNr = instance_p->eutra_band[0]; SULFreqBandItem = calloc(1, sizeof(X2AP_SupportedSULFreqBandItem_t)); SULFreqBandItem->freqBandIndicatorNr=80; /* TODO: put correct value */ @@ -1668,8 +1668,6 @@ int x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *in uint32_t len; int ret = 0; - int MeNB_UE_X2AP_id = x2ap_sgnb_addition_req_ACK->MeNB_ue_x2_id; - int SgNB_UE_X2AP_id = ue_id; int e_rabs_admitted_tobeadded = x2ap_sgnb_addition_req_ACK->nb_e_rabs_admitted_tobeadded; long int pDCPatSgNB = X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present; long int mCGresources = X2AP_EN_DC_ResourceConfiguration__mCGresources_not_present; @@ -1694,7 +1692,7 @@ int x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *in ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID; ie->criticality= X2AP_Criticality_reject; ie->value.present = X2AP_SgNBAdditionRequestAcknowledge_IEs__value_PR_UE_X2AP_ID; - ie->value.choice.UE_X2AP_ID = MeNB_UE_X2AP_id; //x2ap_id_get_id_source(&instance_p->id_manager, ue_id); + ie->value.choice.UE_X2AP_ID = x2ap_id_get_id_source(&instance_p->id_manager, ue_id); ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); // SgNB_UE_X2AP_id @@ -1702,7 +1700,7 @@ int x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *in ie->id = X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID; ie->criticality= X2AP_Criticality_reject; ie->value.present = X2AP_SgNBAdditionRequestAcknowledge_IEs__value_PR_SgNB_UE_X2AP_ID; - ie->value.choice.UE_X2AP_ID = SgNB_UE_X2AP_id; //x2ap_id_get_id_source(&instance_p->id_manager, ue_id); + ie->value.choice.UE_X2AP_ID = x2ap_id_get_id_target(&instance_p->id_manager, ue_id); ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); ie = (X2AP_SgNBAdditionRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SgNBAdditionRequestAcknowledge_IEs_t)); @@ -1792,7 +1790,7 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_reconfiguration_complete( ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID; ie->criticality= X2AP_Criticality_reject; ie->value.present = X2AP_SgNBReconfigurationComplete_IEs__value_PR_UE_X2AP_ID; - ie->value.choice.UE_X2AP_ID = ue_id; //x2ap_id_get_id_source(&instance_p->id_manager, ue_id); + ie->value.choice.UE_X2AP_ID = x2ap_id_get_id_source(&instance_p->id_manager, ue_id); ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); ie = (X2AP_SgNBReconfigurationComplete_IEs_t *)calloc(1, sizeof(X2AP_SgNBReconfigurationComplete_IEs_t)); @@ -1821,3 +1819,226 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_reconfiguration_complete( return ret; } + +int x2ap_eNB_generate_ENDC_x2_SgNB_release_request( + x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, + int x2_id_source, int x2_id_target, x2ap_cause_t cause) +{ + X2AP_X2AP_PDU_t pdu; + X2AP_SgNBReleaseRequest_t *out; + X2AP_SgNBReleaseRequest_IEs_t *ie; + + uint8_t *buffer; + uint32_t len; + int ret = 0; + + DevAssert(instance_p != NULL); + DevAssert(x2ap_eNB_data_p != NULL); + + memset(&pdu, 0, sizeof(pdu)); + pdu.present = X2AP_X2AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage.procedureCode = X2AP_ProcedureCode_id_meNBinitiatedSgNBRelease; + pdu.choice.initiatingMessage.criticality = X2AP_Criticality_ignore; + pdu.choice.initiatingMessage.value.present = X2AP_InitiatingMessage__value_PR_SgNBReleaseRequest; + out = &pdu.choice.initiatingMessage.value.choice.SgNBReleaseRequest; + + ie = (X2AP_SgNBReleaseRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseRequest_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID; + ie->criticality= X2AP_Criticality_reject; + ie->value.present = X2AP_SgNBReleaseRequest_IEs__value_PR_UE_X2AP_ID; + ie->value.choice.UE_X2AP_ID = x2_id_source; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (x2_id_target != -1) { + ie = (X2AP_SgNBReleaseRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseRequest_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID; + ie->criticality= X2AP_Criticality_reject; + ie->value.present = X2AP_SgNBReleaseRequest_IEs__value_PR_SgNB_UE_X2AP_ID; + ie->value.choice.SgNB_UE_X2AP_ID = x2_id_target; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + } + + ie = (X2AP_SgNBReleaseRequest_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseRequest_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_Cause; + ie->criticality= X2AP_Criticality_ignore; + ie->value.present = X2AP_SgNBReleaseRequest_IEs__value_PR_Cause; + switch (cause) { + case X2AP_CAUSE_T_DC_PREP_TIMEOUT: + ie->value.choice.Cause.present = X2AP_Cause_PR_radioNetwork; + ie->value.choice.Cause.choice.radioNetwork = X2AP_CauseRadioNetwork_tDCprep_expiry; + break; + case X2AP_CAUSE_RADIO_CONNECTION_WITH_UE_LOST: + ie->value.choice.Cause.present = X2AP_Cause_PR_radioNetwork; + ie->value.choice.Cause.choice.radioNetwork = X2AP_CauseRadioNetwork_radio_connection_with_UE_lost; + break; + default: + X2AP_ERROR("%s: unhandled cause %d\n", __FUNCTION__, cause); + exit(1); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { + X2AP_ERROR("Failed to encode ENDC X2 SgNB_release_request message\n"); + return -1; + } + + x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 0); + + return ret; +} + +int x2ap_gNB_generate_ENDC_x2_SgNB_release_request_acknowledge( + x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, + int menb_ue_x2ap_id, int sgnb_ue_x2ap_id) +{ + X2AP_X2AP_PDU_t pdu; + X2AP_SgNBReleaseRequestAcknowledge_t *out; + X2AP_SgNBReleaseRequestAcknowledge_IEs_t *ie; + + uint8_t *buffer; + uint32_t len; + int ret = 0; + + DevAssert(instance_p != NULL); + DevAssert(x2ap_eNB_data_p != NULL); + + x2ap_eNB_data_p->state = X2AP_ENB_STATE_WAITING; + + memset(&pdu, 0, sizeof(pdu)); + pdu.present = X2AP_X2AP_PDU_PR_successfulOutcome; + pdu.choice.successfulOutcome.procedureCode = X2AP_ProcedureCode_id_meNBinitiatedSgNBRelease; + pdu.choice.successfulOutcome.criticality = X2AP_Criticality_ignore; + pdu.choice.successfulOutcome.value.present = X2AP_SuccessfulOutcome__value_PR_SgNBReleaseRequestAcknowledge; + out = &pdu.choice.successfulOutcome.value.choice.SgNBReleaseRequestAcknowledge; + + ie = (X2AP_SgNBReleaseRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseRequestAcknowledge_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID; + ie->criticality= X2AP_Criticality_ignore; + ie->value.present = X2AP_SgNBReleaseRequestAcknowledge_IEs__value_PR_UE_X2AP_ID; + ie->value.choice.UE_X2AP_ID = menb_ue_x2ap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + ie = (X2AP_SgNBReleaseRequestAcknowledge_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseRequestAcknowledge_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID; + ie->criticality= X2AP_Criticality_ignore; + ie->value.present = X2AP_SgNBReleaseRequestAcknowledge_IEs__value_PR_SgNB_UE_X2AP_ID; + ie->value.choice.SgNB_UE_X2AP_ID = sgnb_ue_x2ap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { + X2AP_ERROR("Failed to encode ENDC X2 SgNB Release Request Acknowledge\n"); + return -1; + } + + x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 0); + + return ret; +} + +int x2ap_eNB_generate_ENDC_x2_SgNB_release_required( + x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, + int x2_id_source, int x2_id_target, x2ap_cause_t cause) +{ + X2AP_X2AP_PDU_t pdu; + X2AP_SgNBReleaseRequired_t *out; + X2AP_SgNBReleaseRequired_IEs_t *ie; + + uint8_t *buffer; + uint32_t len; + int ret = 0; + + DevAssert(instance_p != NULL); + DevAssert(x2ap_eNB_data_p != NULL); + + /* Prepare the X2AP message to encode */ + memset(&pdu, 0, sizeof(pdu)); + pdu.present = X2AP_X2AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage.procedureCode = X2AP_ProcedureCode_id_sgNBinitiatedSgNBRelease; + pdu.choice.initiatingMessage.criticality = X2AP_Criticality_reject; + pdu.choice.initiatingMessage.value.present = X2AP_InitiatingMessage__value_PR_SgNBReleaseRequired; + out = &pdu.choice.initiatingMessage.value.choice.SgNBReleaseRequired; + + ie = (X2AP_SgNBReleaseRequired_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseRequired_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID; + ie->criticality= X2AP_Criticality_reject; + ie->value.present = X2AP_SgNBReleaseRequired_IEs__value_PR_UE_X2AP_ID; + ie->value.choice.UE_X2AP_ID = x2_id_source; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + ie = (X2AP_SgNBReleaseRequired_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseRequired_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID; + ie->criticality= X2AP_Criticality_reject; + ie->value.present = X2AP_SgNBReleaseRequired_IEs__value_PR_SgNB_UE_X2AP_ID; + ie->value.choice.SgNB_UE_X2AP_ID = x2_id_target; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + ie = (X2AP_SgNBReleaseRequired_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseRequired_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_Cause; + ie->criticality= X2AP_Criticality_ignore; + ie->value.present = X2AP_SgNBReleaseRequired_IEs__value_PR_Cause; + switch (cause) { + case X2AP_CAUSE_T_DC_OVERALL_TIMEOUT: + ie->value.choice.Cause.present = X2AP_Cause_PR_radioNetwork; + ie->value.choice.Cause.choice.radioNetwork = X2AP_CauseRadioNetwork_tDCoverall_expiry; + break; + default: + X2AP_ERROR("%s: unhandled cause %d\n", __FUNCTION__, cause); + exit(1); + } + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { + X2AP_ERROR("Failed to encode ENDC X2 SgNB_release_request message\n"); + return -1; + } + + x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 0); + + return ret; +} + +int x2ap_gNB_generate_ENDC_x2_SgNB_release_confirm( + x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, + int menb_ue_x2ap_id, int sgnb_ue_x2ap_id) +{ + X2AP_X2AP_PDU_t pdu; + X2AP_SgNBReleaseConfirm_t *out; + X2AP_SgNBReleaseConfirm_IEs_t *ie; + + uint8_t *buffer; + uint32_t len; + int ret = 0; + + DevAssert(instance_p != NULL); + DevAssert(x2ap_eNB_data_p != NULL); + + memset(&pdu, 0, sizeof(pdu)); + pdu.present = X2AP_X2AP_PDU_PR_successfulOutcome; + pdu.choice.successfulOutcome.procedureCode = X2AP_ProcedureCode_id_sgNBinitiatedSgNBRelease; + pdu.choice.successfulOutcome.criticality = X2AP_Criticality_reject; + pdu.choice.successfulOutcome.value.present = X2AP_SuccessfulOutcome__value_PR_SgNBReleaseConfirm; + out = &pdu.choice.successfulOutcome.value.choice.SgNBReleaseConfirm; + + ie = (X2AP_SgNBReleaseConfirm_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseConfirm_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID; + ie->criticality= X2AP_Criticality_ignore; + ie->value.present = X2AP_SgNBReleaseConfirm_IEs__value_PR_UE_X2AP_ID; + ie->value.choice.UE_X2AP_ID = menb_ue_x2ap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + ie = (X2AP_SgNBReleaseConfirm_IEs_t *)calloc(1, sizeof(X2AP_SgNBReleaseConfirm_IEs_t)); + ie->id = X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID; + ie->criticality= X2AP_Criticality_ignore; + ie->value.present = X2AP_SgNBReleaseConfirm_IEs__value_PR_SgNB_UE_X2AP_ID; + ie->value.choice.SgNB_UE_X2AP_ID = sgnb_ue_x2ap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + if (x2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { + X2AP_ERROR("Failed to encode ENDC X2 SgNB Release Request Acknowledge\n"); + return -1; + } + + x2ap_eNB_itti_send_sctp_data_req(instance_p->instance, x2ap_eNB_data_p->assoc_id, buffer, len, 0); + + return ret; +} diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.h b/openair2/X2AP/x2ap_eNB_generate_messages.h index 3dfccc0e52..a920020b81 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.h +++ b/openair2/X2AP/x2ap_eNB_generate_messages.h @@ -77,4 +77,16 @@ int x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *in int x2ap_eNB_generate_ENDC_x2_SgNB_reconfiguration_complete( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id, int SgNB_ue_id); +int x2ap_eNB_generate_ENDC_x2_SgNB_release_request(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, + int x2_id_source, int x2_id_target, x2ap_cause_t cause); + +int x2ap_gNB_generate_ENDC_x2_SgNB_release_request_acknowledge(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, + int menb_ue_x2ap_id, int sgnb_ue_x2ap_id); + +int x2ap_eNB_generate_ENDC_x2_SgNB_release_required(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, + int x2_id_source, int x2_id_target, x2ap_cause_t cause); + +int x2ap_gNB_generate_ENDC_x2_SgNB_release_confirm(x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, + int menb_ue_x2ap_id, int sgnb_ue_x2ap_id); + #endif /* X2AP_ENB_GENERATE_MESSAGES_H_ */ diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c index 1c6c98cd81..bbdeaf0ac8 100644 --- a/openair2/X2AP/x2ap_eNB_handler.c +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -44,6 +44,7 @@ #include "msc.h" #include "assertions.h" #include "conversions.h" +#include "X2AP_FreqBandNrItem.h" static int x2ap_eNB_handle_x2_setup_request (instance_t instance, @@ -132,6 +133,29 @@ int x2ap_gNB_handle_ENDC_sGNB_reconfiguration_complete (instance_t instance, uint32_t stream, X2AP_X2AP_PDU_t *pdu); +static +int x2ap_gNB_handle_ENDC_sGNB_release_request(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu); + +static +int x2ap_gNB_handle_ENDC_sGNB_release_request_acknowledge(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu); + +static +int x2ap_gNB_handle_ENDC_sGNB_release_required(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu); + +static +int x2ap_gNB_handle_ENDC_sGNB_release_confirm(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu); /* Handlers matrix. Only eNB related procedure present here. Placement of callback functions according to X2AP_ProcedureCode.h */ x2ap_message_decoded_callback x2ap_messages_callback[][3] = { @@ -166,8 +190,9 @@ x2ap_message_decoded_callback x2ap_messages_callback[][3] = { { x2ap_gNB_handle_ENDC_sGNB_reconfiguration_complete, 0, 0 }, /*X2AP_ProcedureCode_id_sgNBReconfigurationCompletion*/ { 0, 0, 0 }, { 0, 0, 0 }, - { 0, 0, 0 }, - { 0, 0, 0 }, + { x2ap_gNB_handle_ENDC_sGNB_release_request, x2ap_gNB_handle_ENDC_sGNB_release_request_acknowledge, 0 }, /* meNBinitiatedSgNBRelease */ + { x2ap_gNB_handle_ENDC_sGNB_release_required, x2ap_gNB_handle_ENDC_sGNB_release_confirm, 0 }, /* sgNBinitiatedSgNBRelease */ + { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, @@ -1354,13 +1379,13 @@ x2ap_eNB_handle_ENDC_x2_setup_request(instance_t instance, ServedNRcellsENDCX2ManagementList__Member *servedCellMember; x2ap_eNB_instance_t *instance_p; + MessageDef *msg; x2ap_eNB_data_t *x2ap_eNB_data; uint32_t gNB_id = 0; x2ap_eNB_data = NULL; DevAssert (pdu != NULL); x2_ENDC_SetupRequest = &pdu->choice.initiatingMessage.value.choice.ENDCX2SetupRequest; - /* * We received a new valid X2 Setup Request on a stream != 0. * * * * This should not happen -> reject eNB x2 setup request. @@ -1385,103 +1410,110 @@ x2ap_eNB_handle_ENDC_x2_setup_request(instance_t instance, X2AP_ProtocolIE_ID_id_InitiatingNodeType_EndcX2Setup, true); + msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_SETUP_REQ); if (ie == NULL ) { X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); return -1; } else { if (ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_en_gNB.list.count > 0) { + for (int i=0; ivalue.choice.InitiatingNodeType_EndcX2Setup.choice.init_en_gNB.list.count;i++) { + ie_GNB_ENDC = (X2AP_En_gNB_ENDCX2SetupReqIEs_t*) ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_eNB.list.array[i]; + if (ie_GNB_ENDC == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } - for (int i=0; ivalue.choice.InitiatingNodeType_EndcX2Setup.choice.init_en_gNB.list.count;i++) { + else if (ie_GNB_ENDC->id == X2AP_ProtocolIE_ID_id_Globalen_gNB_ID) { + if (ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID.size!= 28) { + //TODO: handle case were size != 28 -> notify ? reject ? + } + OCTET_STRING_TO_INT32(&ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID,gNB_id); + X2AP_DEBUG("gNB id: %07x\n", gNB_id); - ie_GNB_ENDC = (X2AP_En_gNB_ENDCX2SetupReqIEs_t*) ie->value.choice.InitiatingNodeType_EndcX2Setup.choice.init_eNB.list.array[i]; - if (ie_GNB_ENDC == NULL ) { - X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); - return -1; - } + X2AP_DEBUG("Adding gNB to the list of associated gNBs\n"); + if ((x2ap_eNB_data = x2ap_is_eNB_id_in_list (gNB_id)) == NULL) { + /* + * eNB has not been found in list of associated eNB, + * * * * Add it to the tail of list and initialize data + */ + if ((x2ap_eNB_data = x2ap_is_eNB_assoc_id_in_list (assoc_id)) == NULL) { + /* + * ?? + */ + return -1; + } else { + x2ap_eNB_data->state = X2AP_ENB_STATE_RESETTING; + x2ap_eNB_data->eNB_id = gNB_id; + } + } else { + x2ap_eNB_data->state = X2AP_ENB_STATE_RESETTING; + /* + * eNB has been found in list, consider the x2 setup request as a reset connection, + * * * * reseting any previous UE state if sctp association is != than the previous one + */ + if (x2ap_eNB_data->assoc_id != assoc_id) { + /* + * ??: Send an overload cause... + */ + X2AP_ERROR("Rejecting x2 setup request as eNB id %d is already associated to an active sctp association" "Previous known: %d, new one: %d\n", gNB_id, x2ap_eNB_data->assoc_id, assoc_id); - else if (ie_GNB_ENDC->id == X2AP_ProtocolIE_ID_id_Globalen_gNB_ID) { - if (ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID.size!= 28) { - //TODO: handle case were size != 28 -> notify ? reject ? - } - OCTET_STRING_TO_INT32(&ie_GNB_ENDC->value.choice.GlobalGNB_ID.gNB_ID.choice.gNB_ID,gNB_id); - X2AP_DEBUG("gNB id: %07x\n", gNB_id); + // Here we should be calling an ENDC specific setup_failure function instead + x2ap_eNB_generate_x2_setup_failure (instance, + assoc_id, + X2AP_Cause_PR_protocol, + X2AP_CauseProtocol_unspecified, + -1); + return -1; + } + /* + * * TODO: call the reset procedure + */ + } + } + else if (ie_GNB_ENDC->id == X2AP_ProtocolIE_ID_id_ServedNRcellsENDCX2ManagementList){ + if (ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list.count > 0) { + x2ap_eNB_data->num_cc = ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list.count; + X2AP_ENDC_SETUP_REQ(msg).num_cc = x2ap_eNB_data->num_cc; + for (int i=0; ivalue.choice.ServedNRcellsENDCX2ManagementList.list.count;i++) { + servedCellMember = (ServedNRcellsENDCX2ManagementList__Member *)ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list.array[i]; + x2ap_eNB_data->Nid_cell[i] = servedCellMember->servedNRCellInfo.nrpCI; + X2AP_ENDC_SETUP_REQ(msg).Nid_cell[i] = x2ap_eNB_data->Nid_cell[i]; + //servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity.buf[0] + if (servedCellMember->servedNRCellInfo.fiveGS_TAC != NULL) { + X2AP_INFO("TAC: %02x%02x%02x\n", + servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[0], + servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[1], + servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[2]); + } else { + X2AP_INFO("TAC: (NULL)\n"); + } - X2AP_DEBUG("Adding gNB to the list of associated gNBs\n"); - if ((x2ap_eNB_data = x2ap_is_eNB_id_in_list (gNB_id)) == NULL) { - /* - * eNB has not been found in list of associated eNB, - * * * * Add it to the tail of list and initialize data - */ - if ((x2ap_eNB_data = x2ap_is_eNB_assoc_id_in_list (assoc_id)) == NULL) { - /* - * ?? - */ - return -1; - } else { - x2ap_eNB_data->state = X2AP_ENB_STATE_RESETTING; - x2ap_eNB_data->eNB_id = gNB_id; - } - } else { - x2ap_eNB_data->state = X2AP_ENB_STATE_RESETTING; - - /* - * eNB has been found in list, consider the x2 setup request as a reset connection, - * * * * reseting any previous UE state if sctp association is != than the previous one - */ - if (x2ap_eNB_data->assoc_id != assoc_id) { - /* - * ??: Send an overload cause... - */ - X2AP_ERROR("Rejecting x2 setup request as eNB id %d is already associated to an active sctp association" "Previous known: %d, new one: %d\n", gNB_id, x2ap_eNB_data->assoc_id, assoc_id); - - // Panos: Here we should be calling an ENDC specific setup_failure function instead - x2ap_eNB_generate_x2_setup_failure (instance, - assoc_id, - X2AP_Cause_PR_protocol, - X2AP_CauseProtocol_unspecified, - -1); - return -1; - } - /* - * * TODO: call the reset procedure - */ - } - } - else if (ie_GNB_ENDC->id == X2AP_ProtocolIE_ID_id_ServedNRcellsENDCX2ManagementList){ - if (ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list.count > 0) { - x2ap_eNB_data->num_cc = ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list.count; - for (int i=0; ivalue.choice.ServedNRcellsENDCX2ManagementList.list.count;i++) { - servedCellMember = (ServedNRcellsENDCX2ManagementList__Member *)ie_GNB_ENDC->value.choice.ServedNRcellsENDCX2ManagementList.list.array[i]; - x2ap_eNB_data->Nid_cell[i] = servedCellMember->servedNRCellInfo.nrpCI; - //servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity.buf[0] - if (servedCellMember->servedNRCellInfo.fiveGS_TAC != NULL) { - X2AP_INFO("TAC: %02x%02x%02x\n", - servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[0], - servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[1], - servedCellMember->servedNRCellInfo.fiveGS_TAC->buf[2]); - } else { - X2AP_INFO("TAC: (NULL)\n"); - } - - X2AP_INFO("PLMN: %02x%02x%02x\n", - servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity.buf[0], - servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity.buf[1], - servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity.buf[2]); - } - } - } - } + X2AP_INFO("PLMN: %02x%02x%02x\n", + servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity.buf[0], + servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity.buf[1], + servedCellMember->servedNRCellInfo.nrCellID.pLMN_Identity.buf[2]); + if(servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nRFreqInfo.freqBandListNr.list.count > 0){ + X2AP_FreqBandNrItem_t *FreqBandItem = servedCellMember->servedNRCellInfo.nrModeInfo.choice.tdd.nRFreqInfo.freqBandListNr.list.array[0]; + x2ap_eNB_data->servedNrCell_band[i] = FreqBandItem->freqBandIndicatorNr; + X2AP_ENDC_SETUP_REQ(msg).servedNrCell_band[i] = x2ap_eNB_data->servedNrCell_band[i]; + } + } + } + } + } } else { - X2AP_ERROR("%s %d: init_eNB list is empty \n",__FILE__,__LINE__); - return -1; + X2AP_ERROR("%s %d: init_eNB list is empty \n",__FILE__,__LINE__); + return -1; } } instance_p = x2ap_eNB_get_instance(instance); DevAssert(instance_p != NULL); + itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); + return x2ap_eNB_generate_ENDC_x2_setup_response(instance_p, x2ap_eNB_data); } @@ -1641,8 +1673,6 @@ int x2ap_gNB_handle_ENDC_sGNB_addition_request (instance_t instance, uint32_t stream, X2AP_X2AP_PDU_t *pdu) { - - X2AP_SgNBAdditionRequest_t *x2SgNBAdditionRequest; X2AP_SgNBAdditionRequest_IEs_t *ie; @@ -1823,6 +1853,8 @@ int x2ap_eNB_handle_ENDC_sGNB_addition_response (instance_t instance, //Allocate an ITTI X2AP_SGNB_ADDITION_REQ message instead msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_SGNB_ADDITION_REQ_ACK); + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).gnb_x2_assoc_id = assoc_id; + /* X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID */ X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequestAcknowledge_IEs_t, ie, x2SgNBAdditionRequest_ack, X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID, true); @@ -1923,6 +1955,9 @@ int x2ap_eNB_handle_ENDC_sGNB_addition_response (instance_t instance, itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); + /* remove UE from x2, DC preparation is over */ + x2ap_release_id(&instance_p->id_manager, ue_id); + return 0; } @@ -1930,78 +1965,289 @@ static int x2ap_gNB_handle_ENDC_sGNB_reconfiguration_complete (instance_t instance, uint32_t assoc_id, uint32_t stream, - X2AP_X2AP_PDU_t *pdu) { + X2AP_X2AP_PDU_t *pdu) +{ + X2AP_SgNBReconfigurationComplete_t *x2SgNBReconfigurationComplete; + X2AP_SgNBReconfigurationComplete_IEs_t *ie; - X2AP_SgNBReconfigurationComplete_t *x2SgNBReconfigurationComplete; - X2AP_SgNBReconfigurationComplete_IEs_t *ie; + x2ap_eNB_instance_t *instance_p; + x2ap_eNB_data_t *x2ap_eNB_data; + MessageDef *msg; - x2ap_eNB_instance_t *instance_p; - x2ap_eNB_data_t *x2ap_eNB_data; - MessageDef *msg; + int id_target; + int ue_id; - DevAssert (pdu != NULL); - x2SgNBReconfigurationComplete = &pdu->choice.initiatingMessage.value.choice.SgNBReconfigurationComplete; + DevAssert (pdu != NULL); + x2SgNBReconfigurationComplete = &pdu->choice.initiatingMessage.value.choice.SgNBReconfigurationComplete; - /*if (stream == 0) { - X2AP_ERROR ("Received new x2 SgNB Addition request on stream == 0\n"); - // TODO: send a x2 failure response - return 0; - }*/ + /*if (stream == 0) { + X2AP_ERROR ("Received new x2 SgNB Addition request on stream == 0\n"); + // TODO: send a x2 failure response + return 0; + }*/ - X2AP_DEBUG ("Received X2 SgNB Reconfiguration complete message\n"); + X2AP_DEBUG ("Received X2 SgNB Reconfiguration complete message\n"); - x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0); - DevAssert(x2ap_eNB_data != NULL); + x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0); + DevAssert(x2ap_eNB_data != NULL); - X2AP_INFO("X2AP Association id: %d \n",assoc_id); + X2AP_INFO("X2AP Association id: %d \n",assoc_id); - instance_p = x2ap_eNB_get_instance(instance); - DevAssert(instance_p != NULL); + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); - //Allocate an ITTI X2AP_sGNB_reconfiguration_complete message - msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_SGNB_RECONF_COMPLETE); + //Allocate an ITTI X2AP_sGNB_reconfiguration_complete message + msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_SGNB_RECONF_COMPLETE); - /* X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID */ - X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBReconfigurationComplete_IEs_t, ie, x2SgNBReconfigurationComplete, - X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID, true); - if (ie == NULL ) { - X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); - return -1; - } + /* X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID */ + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBReconfigurationComplete_IEs_t, ie, x2SgNBReconfigurationComplete, + X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID, true); + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } - X2AP_ENDC_SGNB_RECONF_COMPLETE(msg).MeNB_ue_x2_id = ie->value.choice.UE_X2AP_ID; + X2AP_ENDC_SGNB_RECONF_COMPLETE(msg).MeNB_ue_x2_id = ie->value.choice.UE_X2AP_ID; - /* X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID */ - X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBReconfigurationComplete_IEs_t, ie, x2SgNBReconfigurationComplete, - X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID, true); - if (ie == NULL ) { - X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); - return -1; - } + /* X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID */ + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBReconfigurationComplete_IEs_t, ie, x2SgNBReconfigurationComplete, + X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID, true); + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } - X2AP_ENDC_SGNB_RECONF_COMPLETE(msg).SgNB_ue_x2_id = ie->value.choice.SgNB_UE_X2AP_ID; + id_target = ie->value.choice.SgNB_UE_X2AP_ID; + X2AP_ENDC_SGNB_RECONF_COMPLETE(msg).SgNB_ue_x2_id = id_target; + ue_id = x2ap_find_id_from_id_target(&instance_p->id_manager, id_target); + if (ue_id == -1) { + X2AP_WARN("incorrect/unknown X2AP IDs for UE (SgNB_UE_X2AP_ID %d), ignoring sGNB reconfiguration complete\n", + id_target); + itti_free(ITTI_MSG_ORIGIN_ID(msg), msg); + return 0; + } - X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBReconfigurationComplete_IEs_t, ie, x2SgNBReconfigurationComplete, - X2AP_ProtocolIE_ID_id_ResponseInformationSgNBReconfComp, true); - if (ie == NULL ) { - X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); - return -1; - } + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBReconfigurationComplete_IEs_t, ie, x2SgNBReconfigurationComplete, + X2AP_ProtocolIE_ID_id_ResponseInformationSgNBReconfComp, true); + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } - if(ie->value.choice.ResponseInformationSgNBReconfComp.present == X2AP_ResponseInformationSgNBReconfComp_PR_success_SgNBReconfComp){ - X2AP_ENDC_SGNB_RECONF_COMPLETE(msg).reconf_response = X2AP_RECONF_RESPONSE_SUCCESS; - } - else { - X2AP_ENDC_SGNB_RECONF_COMPLETE(msg).reconf_response = X2AP_RECONF_RESPONSE_REJECT; - } + if (ie->value.choice.ResponseInformationSgNBReconfComp.present != X2AP_ResponseInformationSgNBReconfComp_PR_success_SgNBReconfComp){ + X2AP_ERROR("%s %d: fatal: unsuccessfulSgNB Reconfiguration Complete\n",__FILE__,__LINE__); + exit(1); + } - itti_send_msg_to_task(TASK_RRC_GNB, instance_p->instance, msg); + x2ap_release_id(&instance_p->id_manager, ue_id); + itti_send_msg_to_task(TASK_RRC_GNB, instance_p->instance, msg); - return 0; + return 0; } +static +int x2ap_gNB_handle_ENDC_sGNB_release_request(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu) +{ + /* the logic in this function is the following: when receiving a release + * request, the UE may exist in X2. Or not. If it's not in X2, it can + * nevertheless be in RRC. + * The release request message may contain the gNB id. Or not. It's better + * to look for the UE using the gNB rather than the eNB id. So if we have + * the gNB id we use it. If not, we use the eNB id. + */ + X2AP_SgNBReleaseRequest_t *req; + X2AP_SgNBReleaseRequest_IEs_t *ie; + x2ap_eNB_instance_t *instance_p; + x2ap_eNB_data_t *x2ap_eNB_data; + MessageDef *msg; + int id_source; + int id_target; + int rnti; + int ue_id; + + DevAssert (pdu != NULL); + req = &pdu->choice.initiatingMessage.value.choice.SgNBReleaseRequest; + + /*if (stream == 0) { + X2AP_ERROR ("Received new x2 SgNB Addition request on stream == 0\n"); + // TODO: send a x2 failure response + return 0; + }*/ + + X2AP_DEBUG ("Received X2 SgNB Release Request message\n"); + + x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0); + DevAssert(x2ap_eNB_data != NULL); + + X2AP_INFO("X2AP Association id: %d \n",assoc_id); + + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + /* X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID */ + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBReleaseRequest_IEs_t, ie, req, + X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID, true); + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + + id_source = ie->value.choice.UE_X2AP_ID; + + /* X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID */ + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBReleaseRequest_IEs_t, ie, req, + X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID, false); + if (ie != NULL) + id_target = ie->value.choice.SgNB_UE_X2AP_ID; + else + id_target = -1; + + /* find ue_id, preferably from id_target if id_target is known */ + ue_id = -1; + if (id_target != -1) + ue_id = x2ap_find_id_from_id_target(&instance_p->id_manager, id_target); + if (ue_id == -1) + ue_id = x2ap_find_id_from_id_source(&instance_p->id_manager, id_source); + + if (ue_id == -1) { + X2AP_WARN("%s %d: no UE found for id_source %d id_target %d\n", + __FILE__, __LINE__, id_source, id_target); + } + + /* the UE may not exist in X2 anymore but exist in RRC + * in which case its rnti is simply the id_target + */ + if (ue_id != -1) { + rnti = x2ap_id_get_rnti(&instance_p->id_manager, ue_id); + + /* remove ue_id */ + x2ap_release_id(&instance_p->id_manager, ue_id); + } else { + rnti = id_target; + } + + if (rnti != -1) { + msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_SGNB_RELEASE_REQUEST); + + X2AP_ENDC_SGNB_RELEASE_REQUEST(msg).rnti = rnti; + + itti_send_msg_to_task(TASK_RRC_GNB, instance_p->instance, msg); + } + + /* this call should maybe not be here, we should check that the + * SgNB Release Request message has been executed properly + */ + x2ap_gNB_generate_ENDC_x2_SgNB_release_request_acknowledge(instance_p, x2ap_eNB_data, + id_source, + rnti != -1 ? rnti : 0); + + return 0; +} + +static +int x2ap_gNB_handle_ENDC_sGNB_release_request_acknowledge(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu) +{ + /* nothing to do - may change at some point */ + X2AP_INFO("received release request acknowledge\n"); + return 0; +} + +static +int x2ap_gNB_handle_ENDC_sGNB_release_required(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu) +{ + /* the logic in this function is the following: when receiving a release + * required we don't care about the UE in X2. We simply send a message + * to RRC with the SgNB id (which is SgNB's RNTI). RRC will look for the + * UE using this RNTI and deal with it. In the meanwhile the X2 layer + * immediately replies with "release confirm" no matter what happens + * in RRC. + */ + X2AP_SgNBReleaseRequired_t *req; + X2AP_SgNBReleaseRequired_IEs_t *ie; + + x2ap_eNB_instance_t *instance_p; + x2ap_eNB_data_t *x2ap_eNB_data; + MessageDef *msg; + + int id_source; + int id_target; + int gnb_rnti; + + DevAssert (pdu != NULL); + req = &pdu->choice.initiatingMessage.value.choice.SgNBReleaseRequired; + + /*if (stream == 0) { + X2AP_ERROR ("Received new x2 SgNB Addition request on stream == 0\n"); + // TODO: send a x2 failure response + return 0; + }*/ + + X2AP_DEBUG ("Received X2 SgNB Release Required message\n"); + + x2ap_eNB_data = x2ap_get_eNB(NULL, assoc_id, 0); + DevAssert(x2ap_eNB_data != NULL); + + X2AP_INFO("X2AP Association id: %d \n",assoc_id); + + instance_p = x2ap_eNB_get_instance(instance); + DevAssert(instance_p != NULL); + + /* X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID */ + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBReleaseRequired_IEs_t, ie, req, + X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID, true); + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + + id_source = ie->value.choice.UE_X2AP_ID; + + /* X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID */ + X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBReleaseRequired_IEs_t, ie, req, + X2AP_ProtocolIE_ID_id_SgNB_UE_X2AP_ID, true); + if (ie == NULL ) { + X2AP_ERROR("%s %d: ie is a NULL pointer \n",__FILE__,__LINE__); + return -1; + } + + id_target = ie->value.choice.SgNB_UE_X2AP_ID; + + gnb_rnti = id_target; + + msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_SGNB_RELEASE_REQUIRED); + X2AP_ENDC_SGNB_RELEASE_REQUIRED(msg).gnb_rnti = gnb_rnti; + itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); + + /* this call should maybe not be here, we should check that the + * SgNB Release Required message has been executed properly + */ + x2ap_gNB_generate_ENDC_x2_SgNB_release_confirm(instance_p, x2ap_eNB_data, + id_source, id_target); + + return 0; +} + +static +int x2ap_gNB_handle_ENDC_sGNB_release_confirm(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + X2AP_X2AP_PDU_t *pdu) +{ + /* nothing to do - may change at some point */ + X2AP_INFO("received release confirm\n"); + return 0; +} diff --git a/openair2/X2AP/x2ap_ids.c b/openair2/X2AP/x2ap_ids.c index 02f1bbfc0e..0750ba5bc9 100644 --- a/openair2/X2AP/x2ap_ids.c +++ b/openair2/X2AP/x2ap_ids.c @@ -70,6 +70,16 @@ int x2ap_find_id_from_id_source(x2ap_id_manager *m, int id_source) return -1; } +int x2ap_find_id_from_id_target(x2ap_id_manager *m, int id_target) +{ + int i; + for (i = 0; i < X2AP_MAX_IDS; i++) + if (m->ids[i].rnti != -1 && + m->ids[i].id_target == id_target) + return i; + return -1; +} + int x2ap_find_id_from_rnti(x2ap_id_manager *m, int rnti) { int i; @@ -107,6 +117,16 @@ void x2ap_set_reloc_overall_timer(x2ap_id_manager *m, int ue_id, uint64_t time) m->ids[ue_id].tx2_reloc_overall_start = time; } +void x2ap_set_dc_prep_timer(x2ap_id_manager *m, int ue_id, uint64_t time) +{ + m->ids[ue_id].t_dc_prep_start = time; +} + +void x2ap_set_dc_overall_timer(x2ap_id_manager *m, int ue_id, uint64_t time) +{ + m->ids[ue_id].t_dc_overall_start = time; +} + int x2ap_id_get_id_source(x2ap_id_manager *m, int ue_id) { return m->ids[ue_id].id_source; diff --git a/openair2/X2AP/x2ap_ids.h b/openair2/X2AP/x2ap_ids.h index f2670f3612..26d97f73c8 100644 --- a/openair2/X2AP/x2ap_ids.h +++ b/openair2/X2AP/x2ap_ids.h @@ -38,7 +38,8 @@ typedef enum { X2ID_STATE_SOURCE_PREPARE, X2ID_STATE_SOURCE_OVERALL, X2ID_STATE_TARGET, - X2ID_STATE_NSA_PREPARE, + X2ID_STATE_NSA_ENB_PREPARE, + X2ID_STATE_NSA_GNB_OVERALL, } x2id_state_t; typedef struct { @@ -55,6 +56,8 @@ typedef struct { /* timers */ uint64_t t_reloc_prep_start; uint64_t tx2_reloc_overall_start; + uint64_t t_dc_prep_start; + uint64_t t_dc_overall_start; } x2ap_id; typedef struct { @@ -66,6 +69,7 @@ int x2ap_allocate_new_id(x2ap_id_manager *m); void x2ap_release_id(x2ap_id_manager *m, int id); int x2ap_find_id(x2ap_id_manager *, int id_source, int id_target); int x2ap_find_id_from_id_source(x2ap_id_manager *, int id_source); +int x2ap_find_id_from_id_target(x2ap_id_manager *, int id_source); int x2ap_find_id_from_rnti(x2ap_id_manager *, int rnti); void x2ap_set_ids(x2ap_id_manager *m, int ue_id, int rnti, int id_source, int id_target); void x2ap_id_set_state(x2ap_id_manager *m, int ue_id, x2id_state_t state); @@ -73,6 +77,8 @@ void x2ap_id_set_state(x2ap_id_manager *m, int ue_id, x2id_state_t state); void x2ap_id_set_target(x2ap_id_manager *m, int ue_id, void *target); void x2ap_set_reloc_prep_timer(x2ap_id_manager *m, int ue_id, uint64_t time); void x2ap_set_reloc_overall_timer(x2ap_id_manager *m, int ue_id, uint64_t time); +void x2ap_set_dc_prep_timer(x2ap_id_manager *m, int ue_id, uint64_t time); +void x2ap_set_dc_overall_timer(x2ap_id_manager *m, int ue_id, uint64_t time); int x2ap_id_get_id_source(x2ap_id_manager *m, int ue_id); int x2ap_id_get_id_target(x2ap_id_manager *m, int ue_id); int x2ap_id_get_rnti(x2ap_id_manager *m, int ue_id); diff --git a/openair2/X2AP/x2ap_timers.c b/openair2/X2AP/x2ap_timers.c index a0a7b61ad7..29e887504f 100644 --- a/openair2/X2AP/x2ap_timers.c +++ b/openair2/X2AP/x2ap_timers.c @@ -28,11 +28,17 @@ #include "x2ap_eNB_management_procedures.h" #include "x2ap_eNB_generate_messages.h" -void x2ap_timers_init(x2ap_timers_t *t, int t_reloc_prep, int tx2_reloc_overall) +void x2ap_timers_init(x2ap_timers_t *t, + int t_reloc_prep, + int tx2_reloc_overall, + int t_dc_prep, + int t_dc_overall) { t->tti = 0; t->t_reloc_prep = t_reloc_prep; t->tx2_reloc_overall = tx2_reloc_overall; + t->t_dc_prep = t_dc_prep; + t->t_dc_overall = t_dc_overall; } void x2ap_check_timers(instance_t instance) @@ -59,14 +65,17 @@ void x2ap_check_timers(instance_t instance) for (i = 0; i < X2AP_MAX_IDS; i++) { if (m->ids[i].rnti == -1) continue; - x2_ongoing++; + + if (m->ids[i].state == X2ID_STATE_SOURCE_PREPARE || + m->ids[i].state == X2ID_STATE_SOURCE_OVERALL) + x2_ongoing++; if (m->ids[i].state == X2ID_STATE_SOURCE_PREPARE && t->tti > m->ids[i].t_reloc_prep_start + t->t_reloc_prep) { LOG_I(X2AP, "X2 timeout reloc prep\n"); /* t_reloc_prep timed out */ cause = X2AP_T_RELOC_PREP_TIMEOUT; - goto timeout; + goto lte_handover_timeout; } if (m->ids[i].state == X2ID_STATE_SOURCE_OVERALL && @@ -74,13 +83,62 @@ void x2ap_check_timers(instance_t instance) LOG_I(X2AP, "X2 timeout reloc overall\n"); /* tx2_reloc_overall timed out */ cause = X2AP_TX2_RELOC_OVERALL_TIMEOUT; - goto timeout; + goto lte_handover_timeout; + } + + if (m->ids[i].state == X2ID_STATE_NSA_ENB_PREPARE && + t->tti > m->ids[i].t_dc_prep_start + t->t_dc_prep) { + int id_source; + int id_target; + + LOG_I(X2AP, "X2 timeout DC prep\n"); + /* t_dc_prep timed out */ + target = x2ap_id_get_target(m, i); + id_source = x2ap_id_get_id_source(m, i); + id_target = x2ap_id_get_id_target(m, i); + x2ap_eNB_generate_ENDC_x2_SgNB_release_request(instance_p, target, + id_source, id_target, + X2AP_CAUSE_T_DC_PREP_TIMEOUT); + + /* inform RRC of timeout */ + msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_DC_PREP_TIMEOUT); + X2AP_ENDC_DC_PREP_TIMEOUT(msg).rnti = x2ap_id_get_rnti(m, i); + itti_send_msg_to_task(TASK_RRC_ENB, instance_p->instance, msg); + + /* remove UE from X2AP */ + x2ap_release_id(m, i); + + continue; + } + + if (m->ids[i].state == X2ID_STATE_NSA_GNB_OVERALL && + t->tti > m->ids[i].t_dc_overall_start + t->t_dc_overall) { + int id_source; + int id_target; + + LOG_I(X2AP, "X2 timeout DC overall\n"); + /* t_dc_overall timed out */ + target = x2ap_id_get_target(m, i); + id_source = x2ap_id_get_id_source(m, i); + id_target = x2ap_id_get_id_target(m, i); + x2ap_eNB_generate_ENDC_x2_SgNB_release_required(instance_p, target, + id_source, id_target, X2AP_CAUSE_T_DC_OVERALL_TIMEOUT); + + /* inform RRC of timeout */ + msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_DC_OVERALL_TIMEOUT); + X2AP_ENDC_DC_OVERALL_TIMEOUT(msg).rnti = x2ap_id_get_rnti(m, i); + itti_send_msg_to_task(TASK_RRC_GNB, instance_p->instance, msg); + + /* remove UE from X2AP */ + x2ap_release_id(m, i); + + continue; } /* no timeout -> check next UE */ continue; -timeout: +lte_handover_timeout: /* inform target about timeout */ target = x2ap_id_get_target(m, i); x2ap_eNB_generate_x2_handover_cancel(instance_p, target, i, cause); diff --git a/openair2/X2AP/x2ap_timers.h b/openair2/X2AP/x2ap_timers.h index d4579422d5..f32b73e87b 100644 --- a/openair2/X2AP/x2ap_timers.h +++ b/openair2/X2AP/x2ap_timers.h @@ -36,9 +36,15 @@ typedef struct { /* timer values (unit: TTI, ie. millisecond when in realtime) */ int t_reloc_prep; int tx2_reloc_overall; + int t_dc_prep; + int t_dc_overall; } x2ap_timers_t; -void x2ap_timers_init(x2ap_timers_t *t, int t_reloc_prep, int tx2_reloc_overall); +void x2ap_timers_init(x2ap_timers_t *t, + int t_reloc_prep, + int tx2_reloc_overall, + int t_dc_prep, + int t_dc_overall); void x2ap_check_timers(instance_t instance); uint64_t x2ap_timer_get_tti(x2ap_timers_t *t); diff --git a/openair3/GTPV1-U/gtpv1u_eNB.c b/openair3/GTPV1-U/gtpv1u_eNB.c index f095cce67d..1e2954ba95 100644 --- a/openair3/GTPV1-U/gtpv1u_eNB.c +++ b/openair3/GTPV1-U/gtpv1u_eNB.c @@ -1184,7 +1184,10 @@ int gtpv1u_delete_s1u_tunnel( "0 GTPV1U_ENB_DELETE_TUNNEL_RESP rnti %x teid %x", GTPV1U_ENB_DELETE_TUNNEL_RESP(message_p).rnti, teid_eNB); - return itti_send_msg_to_task(TASK_RRC_ENB, instanceP, message_p); + if (req_pP->from_gnb) + return itti_send_msg_to_task(TASK_RRC_GNB, instanceP, message_p); + else + return itti_send_msg_to_task(TASK_RRC_ENB, instanceP, message_p); } diff --git a/openair3/GTPV1-U/nw-gtpv1u/test-app/nw-helloworld/NwMiniLogMgrEntity.h b/openair3/GTPV1-U/nw-gtpv1u/test-app/nw-helloworld/NwMiniLogMgrEntity.h index 8f2908e52a..18b60aa611 100644 --- a/openair3/GTPV1-U/nw-gtpv1u/test-app/nw-helloworld/NwMiniLogMgrEntity.h +++ b/openair3/GTPV1-U/nw-gtpv1u/test-app/nw-helloworld/NwMiniLogMgrEntity.h @@ -16,13 +16,13 @@ #include "NwEvt.h" #include "NwLog.h" +#ifndef __NW_MINI_LOG_MGR_H__ +#define __NW_MINI_LOG_MGR_H__ + #ifndef NW_ASSERT #define NW_ASSERT assert #endif -#ifndef __NW_MINI_LOG_MGR_H__ -#define __NW_MINI_LOG_MGR_H__ - extern uint32_t g_log_level; diff --git a/openair3/GTPV1-U/nw-gtpv1u/test-app/nw-helloworld/NwMiniTmrMgrEntity.h b/openair3/GTPV1-U/nw-gtpv1u/test-app/nw-helloworld/NwMiniTmrMgrEntity.h index b17228c9cf..a1f16ff89b 100644 --- a/openair3/GTPV1-U/nw-gtpv1u/test-app/nw-helloworld/NwMiniTmrMgrEntity.h +++ b/openair3/GTPV1-U/nw-gtpv1u/test-app/nw-helloworld/NwMiniTmrMgrEntity.h @@ -17,13 +17,13 @@ #include "NwEvt.h" #include "NwLog.h" +#ifndef __NW_MINI_TMR_MGR_H__ +#define __NW_MINI_TMR_MGR_H__ + #ifndef NW_ASSERT #define NW_ASSERT assert #endif -#ifndef __NW_MINI_TMR_MGR_H__ -#define __NW_MINI_TMR_MGR_H__ - typedef struct { NwEventT ev; void* timeoutArg; diff --git a/openair3/GTPV1-U/nw-gtpv1u/test-app/nw-helloworld/NwMiniUdpEntity.h b/openair3/GTPV1-U/nw-gtpv1u/test-app/nw-helloworld/NwMiniUdpEntity.h index 2e19ebbb8e..568c5b0796 100644 --- a/openair3/GTPV1-U/nw-gtpv1u/test-app/nw-helloworld/NwMiniUdpEntity.h +++ b/openair3/GTPV1-U/nw-gtpv1u/test-app/nw-helloworld/NwMiniUdpEntity.h @@ -17,13 +17,13 @@ #include "NwEvt.h" #include "NwLog.h" +#ifndef __NW_MINI_UDP_ENTITY_H__ +#define __NW_MINI_UDP_ENTITY_H__ + #ifndef NW_ASSERT #define NW_ASSERT assert #endif -#ifndef __NW_MINI_UDP_ENTITY_H__ -#define __NW_MINI_UDP_ENTITY_H__ - typedef struct { uint32_t hSocket; NwEventT ev; diff --git a/targets/COMMON/threads_t.h b/targets/COMMON/threads_t.h index 0671f40988..5fb1645444 100644 --- a/targets/COMMON/threads_t.h +++ b/targets/COMMON/threads_t.h @@ -1,5 +1,5 @@ -#ifndef _THREADS_T_H_ -#define _THREADS_T_H_ +#ifndef _TARGETS_COMMON_THREADS_T_H_ +#define _TARGETS_COMMON_THREADS_T_H_ typedef struct threads_s { int main; @@ -18,4 +18,4 @@ typedef struct threads_s { //int dlsch_td1_three; } threads_t; -#endif /* _THREADS_T_H_ */ +#endif /* _TARGETS_COMMON_THREADS_T_H_ */ diff --git a/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.calisson.conf b/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.calisson.conf index d619ab2958..e1360c1f45 100644 --- a/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.calisson.conf +++ b/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.calisson.conf @@ -43,6 +43,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.memphis.conf b/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.memphis.conf index 558676e99b..84c669571c 100644 --- a/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.memphis.conf +++ b/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.memphis.conf @@ -55,6 +55,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.nord.conf b/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.nord.conf index 9a4a863419..bc41de1874 100644 --- a/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.nord.conf +++ b/targets/PROJECTS/CENTOS-LTE-EPC-INTEGRATION/CONF/enb.centos.nord.conf @@ -42,6 +42,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf index 716bfd3b6b..0e3b9fffdf 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-4g.conf @@ -187,6 +187,8 @@ eNBs = enable_x2 = "yes"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf index 27fc90e5e3..5e02f16b02 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf @@ -214,6 +214,8 @@ gNBs = enable_x2 = "yes"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ target_enb_x2_ip_address = ( { ipv4 = "127.0.0.1"; ipv6 = "192:168:30::17"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.50PRB.emtc.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.50PRB.emtc.conf index a761579018..67044f38d9 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.50PRB.emtc.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band13.tm1.50PRB.emtc.conf @@ -367,6 +367,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.100PRB.usrpx310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.100PRB.usrpx310.conf index f248f515b8..e044c186b9 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.100PRB.usrpx310.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.100PRB.usrpx310.conf @@ -148,6 +148,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.25PRB.iris030.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.25PRB.iris030.conf index dee6c298a7..5a547622ab 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.25PRB.iris030.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.25PRB.iris030.conf @@ -184,6 +184,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpx310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpx310.conf index 231581574a..27826e5ce2 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpx310.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpx310.conf @@ -148,6 +148,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band42.tm1.25PRB.iris030.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band42.tm1.25PRB.iris030.conf index 54c12835ef..5df0f107ea 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band42.tm1.25PRB.iris030.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band42.tm1.25PRB.iris030.conf @@ -184,6 +184,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.master.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.master.conf index c0decd362f..cb50cccf2b 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.master.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.master.conf @@ -183,6 +183,8 @@ eNBs = enable_x2 = "yes"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf index feab0d6926..245e4ecf94 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf @@ -151,6 +151,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.iris030.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.iris030.conf index 1a0466aad3..86b481f9d8 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.iris030.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.iris030.conf @@ -184,6 +184,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.replay.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.replay.conf index 753c2d8b5c..1eb5da6a18 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.replay.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.replay.conf @@ -185,6 +185,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210-d2d.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210-d2d.conf index 20646681d2..a929c439be 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210-d2d.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210-d2d.conf @@ -185,6 +185,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf index d6f44e2b96..43288ba324 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf @@ -185,6 +185,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210_ue_expansion.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210_ue_expansion.conf index 8971633ce0..92f2d4e6f1 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210_ue_expansion.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210_ue_expansion.conf @@ -152,6 +152,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { 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 ff8e261783..1cd16d0831 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 @@ -203,6 +203,8 @@ gNBs = enable_x2 = "yes"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ target_enb_x2_ip_address = ( { ipv4 = "192.168.12.196"; ipv6 = "192:168:30::17"; 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 81796ada2c..dfae41f0a6 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 @@ -214,6 +214,8 @@ gNBs = enable_x2 = "yes"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ target_enb_x2_ip_address = ( { ipv4 = "192.168.12.188"; ipv6 = "192:168:30::17"; 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 771f5d1839..dcdfa003a2 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf @@ -203,6 +203,8 @@ gNBs = enable_x2 = "yes"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ target_enb_x2_ip_address = ( { ipv4 = "192.168.12.188"; ipv6 = "192:168:30::17"; 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 9420c488ec..0659641607 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 @@ -208,6 +208,8 @@ gNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ target_enb_x2_ip_address = ( { ipv4 = "192.168.12.108"; ipv6 = "192:168:30::17"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band38.tm1.if4p5.50PRB.lo.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band38.tm1.if4p5.50PRB.lo.conf index d2c1aac31e..e05c64b4e8 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band38.tm1.if4p5.50PRB.lo.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band38.tm1.if4p5.50PRB.lo.conf @@ -154,6 +154,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi-STUB.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi-STUB.conf index 7c2c2e0170..1ef71bedc2 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi-STUB.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi-STUB.conf @@ -154,6 +154,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf index 723147daeb..9ce9f28cc2 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf @@ -185,6 +185,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf index 13fd5fdb75..30cb852a28 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf @@ -154,6 +154,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf index b72e4c59d7..519305b68d 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf @@ -155,6 +155,8 @@ eNBs = enable_x2 = "no"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_enb.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_enb.conf index 4c0d346360..d26ebcd590 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_enb.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_enb.conf @@ -140,6 +140,9 @@ eNBs = discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff"; discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + + //SSB central frequency of NR secondary cell group (for ENDC NSA) + nr_scg_ssb_freq = 641272; } ); @@ -187,6 +190,8 @@ eNBs = enable_x2 = "yes"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ NETWORK_INTERFACES : { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf index 2eed408b53..fd1b62fd3d 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf @@ -214,6 +214,8 @@ gNBs = enable_x2 = "yes"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ target_enb_x2_ip_address = ( { ipv4 = "192.168.18.199"; ipv6 = "192:168:30::17"; 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 f30c928448..6a3f008ec1 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf @@ -212,6 +212,8 @@ gNBs = enable_x2 = "yes"; t_reloc_prep = 1000; /* unit: millisecond */ tx2_reloc_overall = 2000; /* unit: millisecond */ + t_dc_prep = 1000; /* unit: millisecond */ + t_dc_overall = 2000; /* unit: millisecond */ target_enb_x2_ip_address = ( { ipv4 = "192.168.18.199"; ipv6 = "192:168:30::17"; diff --git a/targets/RT/USER/stats.h b/targets/RT/USER/stats.h index 264c8f7af0..15ee4a8087 100644 --- a/targets/RT/USER/stats.h +++ b/targets/RT/USER/stats.h @@ -21,8 +21,8 @@ /* Header file generated by fdesign on Thu Aug 28 12:13:51 2014 */ -#ifndef FD_stats_form_h_ -#define FD_stats_form_h_ +#ifndef _TARGETS_RT_USER_STATS_H_ +#define _TARGETS_RT_USER_STATS_H_ #include @@ -43,4 +43,4 @@ typedef struct { extern FD_stats_form * create_form_stats_form( void ); -#endif /* FD_stats_form_h_ */ +#endif /* _TARGETS_RT_USER_STATS_H_ */