diff --git a/ci-scripts/Jenkinsfile-trig-nsa b/ci-scripts/Jenkinsfile-trig-nsa index 44527a1a383d6af80812e0949e763c3ecde9fb07..2dcaf1a04fef5fa7eac155d0e9098d4eaef547bd 100644 --- a/ci-scripts/Jenkinsfile-trig-nsa +++ b/ci-scripts/Jenkinsfile-trig-nsa @@ -56,21 +56,21 @@ pipeline { booleanParam(name: 'eNB_AllowMergeRequestProcess', value: Boolean.valueOf(ALLOW_MERGE)) ] //calling NSA long sub job - build job: "RAN-NSA-Mini-Module-Long", wait : true, propagate : false, parameters: [ - string(name: 'eNB_MR', value: String.valueOf(MR)), - string(name: 'eNB_Branch', value: String.valueOf(SRC_BRANCH)), - string(name: 'eNB_CommitID', value: String.valueOf(COMMIT_ID)), - string(name: 'eNB_TargetBranch', value: String.valueOf(TARGET_BRANCH)), - booleanParam(name: 'eNB_AllowMergeRequestProcess', value: Boolean.valueOf(ALLOW_MERGE)) - ] +// build job: "RAN-NSA-Mini-Module-Long", wait : true, propagate : false, parameters: [ +// string(name: 'eNB_MR', value: String.valueOf(MR)), +// string(name: 'eNB_Branch', value: String.valueOf(SRC_BRANCH)), +// string(name: 'eNB_CommitID', value: String.valueOf(COMMIT_ID)), +// string(name: 'eNB_TargetBranch', value: String.valueOf(TARGET_BRANCH)), +// booleanParam(name: 'eNB_AllowMergeRequestProcess', value: Boolean.valueOf(ALLOW_MERGE)) +// ] //calling NSA attach/detach job - build job: "RAN-NSA-Mini-Module-Attach-Detach", wait : true, propagate : false, parameters: [ - string(name: 'eNB_MR', value: String.valueOf(MR)), - string(name: 'eNB_Branch', value: String.valueOf(SRC_BRANCH)), - string(name: 'eNB_CommitID', value: String.valueOf(COMMIT_ID)), - string(name: 'eNB_TargetBranch', value: String.valueOf(TARGET_BRANCH)), - booleanParam(name: 'eNB_AllowMergeRequestProcess', value: Boolean.valueOf(ALLOW_MERGE)) - ] +// build job: "RAN-NSA-Mini-Module-Attach-Detach", wait : true, propagate : false, parameters: [ +// string(name: 'eNB_MR', value: String.valueOf(MR)), +// string(name: 'eNB_Branch', value: String.valueOf(SRC_BRANCH)), +// string(name: 'eNB_CommitID', value: String.valueOf(COMMIT_ID)), +// string(name: 'eNB_TargetBranch', value: String.valueOf(TARGET_BRANCH)), +// booleanParam(name: 'eNB_AllowMergeRequestProcess', value: Boolean.valueOf(ALLOW_MERGE)) +// ] } } diff --git a/ci-scripts/checkCodingFormattingRules.sh b/ci-scripts/checkCodingFormattingRules.sh index 3a2fcbb02cbba3692c65b0c597fde6edbc39d4b2..45cf08aa9afeec3a78b761b2ee5f075810601476 100755 --- a/ci-scripts/checkCodingFormattingRules.sh +++ b/ci-scripts/checkCodingFormattingRules.sh @@ -76,8 +76,8 @@ then do IS_NFAPI=`echo $FILE | egrep -c "nfapi/open-nFAPI|nfapi/oai_integration/vendor_ext" || true` IS_OAI_LICENCE_PRESENT=`egrep -c "OAI Public License" $FILE || true` - IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence" $FILE || true` - 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_|openair3/NAS/COMMON/milenage.h" || true` + IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence|License-Identifier: BSD-2-Clause" $FILE || true` + 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_|openair2/UTIL/OPT/packet-rohc.h|openair3/NAS/COMMON/milenage.h" || true` if [ $IS_OAI_LICENCE_PRESENT -eq 0 ] && [ $IS_BSD_LICENCE_PRESENT -eq 0 ] then if [ $IS_NFAPI -eq 0 ] && [ $IS_EXCEPTION -eq 0 ] @@ -197,8 +197,8 @@ do then IS_NFAPI=`echo $FULLFILE | egrep -c "nfapi/open-nFAPI|nfapi/oai_integration/vendor_ext" || true` IS_OAI_LICENCE_PRESENT=`egrep -c "OAI Public License" $FULLFILE || true` - IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence" $FULLFILE || true` - 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_|openair3/NAS/COMMON/milenage.h" || true` + IS_BSD_LICENCE_PRESENT=`egrep -c "the terms of the BSD Licence|License-Identifier: BSD-2-Clause" $FULLFILE || true` + 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_|openair2/UTIL/OPT/packet-rohc.h|openair3/NAS/COMMON/milenage.h" || true` if [ $IS_OAI_LICENCE_PRESENT -eq 0 ] && [ $IS_BSD_LICENCE_PRESENT -eq 0 ] then if [ $IS_NFAPI -eq 0 ] && [ $IS_EXCEPTION -eq 0 ] diff --git a/ci-scripts/cls_oaicitest.py b/ci-scripts/cls_oaicitest.py index 377592781df1c36baba3f730d5f51b0536e165e5..73141aa9b7a6878c30f1857331a3b2d93191a3d2 100644 --- a/ci-scripts/cls_oaicitest.py +++ b/ci-scripts/cls_oaicitest.py @@ -2222,6 +2222,24 @@ class OaiCiTest(): def Iperf_Module(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue,EPC, Module_UE): SSH = sshconnection.SSHConnection() + #RH temporary quick n dirty for test + SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) + cmd = 'echo ' + EPC.Password + ' | sudo -S ip link set dev tun5 mtu 1358' + SSH.command(cmd,'\$',5) + SSH.close() + + + #kill iperf processes before (in case there are still some remaining) + SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword) + cmd = 'killall --signal=SIGKILL iperf' + SSH.command(cmd,'\$',5) + SSH.close() + SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) + cmd = 'killall --signal=SIGKILL iperf' + SSH.command(cmd,'\$',5) + SSH.close() + + iperf_time = self.Iperf_ComputeTime() if self.iperf_direction=="DL": logging.debug("Iperf for Module in DL mode detected") @@ -2231,12 +2249,14 @@ class OaiCiTest(): SSH.command(cmd,'\$',5) cmd = 'echo $USER; nohup /opt/iperf-2.0.10/iperf -s -B ' + UE_IPAddress + ' -u 2>&1 > iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log' SSH.command(cmd,'\$',5) + SSH.close() #client side EPC SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) cmd = 'rm iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log' SSH.command(cmd,'\$',5) cmd = 'iperf -c ' + UE_IPAddress + ' ' + self.iperf_args + ' 2>&1 > iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log' SSH.command(cmd,'\$',int(iperf_time)*5.0) + SSH.close() #copy the 2 resulting files locally SSH.copyin(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword, 'iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log', '.') SSH.copyin(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log', '.') @@ -2252,29 +2272,32 @@ class OaiCiTest(): SSH.command(cmd,'\$',5) cmd = 'echo $USER; nohup iperf -s -u 2>&1 > iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log' SSH.command(cmd,'\$',5) + SSH.close() #client side UE SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword) cmd = 'rm iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log' SSH.command(cmd,'\$',5) SSH.command('/opt/iperf-2.0.10/iperf -c 192.172.0.1 ' + self.iperf_args + ' 2>&1 > iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log', '\$', int(iperf_time)*5.0) + SSH.close() #copy the 2 resulting files locally SSH.copyin(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword, 'iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log', '.') SSH.copyin(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log', '.') #send for analysis - filename='iperf_client_' + self.testCase_id + '_' + self.ue_id + '.log' + filename='iperf_server_' + self.testCase_id + '_' + self.ue_id + '.log' self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, self.iperf_args,filename,1) else : logging.debug("Incorrect or missing IPERF direction in XML") + #kill iperf processes after to be clean SSH.open(Module_UE.HostIPAddress, Module_UE.HostUsername, Module_UE.HostPassword) cmd = 'killall --signal=SIGKILL iperf' SSH.command(cmd,'\$',5) + SSH.close() SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) cmd = 'killall --signal=SIGKILL iperf' SSH.command(cmd,'\$',5) - SSH.close() return diff --git a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpb210.conf b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpb210.conf index 494be845a694c5b3b17d913c4f8ec71ba4ea4e62..0efc071c91ff29af7225442a62afd714935cd841 100644 --- a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpb210.conf +++ b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpb210.conf @@ -142,7 +142,7 @@ gNBs = initialULBWPk2_1 = 6; # used for mixed slot initialULBWPmappingType_1 = 1; - initialULBWPstartSymbolAndLength_1 = 69; # this is SS=0 L=12 + initialULBWPstartSymbolAndLength_1 = 52; # this is SS=10 L=4 initialULBWPk2_2 = 7; # used for Msg.3 during RA initialULBWPmappingType_2 = 1; @@ -225,11 +225,12 @@ gNBs = ); MACRLCs = ( - { - num_cc = 1; - tr_s_preference = "local_L1"; - tr_n_preference = "local_RRC"; - } + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + ulsch_max_slots_inactivity = 100; + } ); L1s = ( diff --git a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf index bc9dcb47cc721158bb1401f0c0c07c9723cf6e28..8d32e8b792e793a9e1a3291f6153e407374c03d3 100644 --- a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf @@ -243,7 +243,7 @@ RUs = ( ## beamforming 4x4 matrix: #bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000, 0x00000000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00007fff]; - sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2"; + sdr_addrs = "addr=192.168.30.2,mgmt_addr=192.168.30.2,second_addr=192.168.50.2"; clock_src = "external"; } ); 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 205922af0c25b6a87766bffd8c80cf7bb14db4d3..86293f2297a343711135a9cc9e1948675235a07b 100644 --- a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf @@ -126,7 +126,7 @@ gNBs = initialULBWPk2_1 = 6; # used for mixed slot initialULBWPmappingType_1 = 1; - initialULBWPstartSymbolAndLength_1 = 69; # this is SS=10 L=2 + initialULBWPstartSymbolAndLength_1 = 52; # this is SS=10 L=4 initialULBWPk2_2 = 7; # used for Msg.3 during RA initialULBWPmappingType_2 = 1; diff --git a/ci-scripts/datalog_rt_stats.yaml b/ci-scripts/datalog_rt_stats.yaml index 3680d2a19bdb7f484ab061dfd33db0a65d0a48b5..548caa0bddbb201fc14fdf6c6f66a142d40a5ace 100644 --- a/ci-scripts/datalog_rt_stats.yaml +++ b/ci-scripts/datalog_rt_stats.yaml @@ -10,15 +10,15 @@ ColNames : Ref : feprx : 60.0 feptx_prec : 8.0 - feptx_ofdm : 85.0 + feptx_ofdm : 50.0 feptx_total : 75.0 L1 Tx processing : 300.0 DLSCH encoding : 230.0 L1 Rx processing : 175.0 PUSCH inner-receiver : 100.0 PUSCH decoding : 140.0 - DL & UL scheduling timing stats : 15.0 - UL Indication : 20.0 + DL & UL scheduling timing stats : 37.0 + UL Indication : 38.0 Threshold : feprx : 1.25 feptx_prec : 1.25 diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index b8992573cdaedce50b227cb59eea42e94a0d1a58..e7c2cbc6cdf5cc0d88fe4ccabb133fb14956ec57 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1021,7 +1021,6 @@ add_boolean_option(PHY_TX_THREAD False "enable UE_EXPANSION w add_boolean_option(PRE_SCD_THREAD False "enable UE_EXPANSION with max 256 UE") add_boolean_option(UESIM_EXPANSION False "enable UESIM_EXPANSION with max 256 UE") add_boolean_option(ITTI_SIM False "enable itti simulator") -add_boolean_option(RFSIM_NAS False "enable rfsim nas") ######################## # Include order @@ -2464,108 +2463,6 @@ set (libnas_utils_OBJS ${NAS_SRC}COMMON/UTIL/OctetString.c ) -if(NAS_UE) - set(libnas_ue_api_OBJS - ${NAS_SRC}UE/API/USER/at_command.c - ${NAS_SRC}UE/API/USER/at_error.c - ${NAS_SRC}UE/API/USER/at_response.c - ${NAS_SRC}UE/API/USER/user_api.c - ${NAS_SRC}UE/API/USER/user_indication.c - ${NAS_SRC}UE/API/USIM/aka_functions.c - ${NAS_SRC}UE/API/USIM/usim_api.c - ) - set(libnas_ue_emm_OBJS - ${NAS_SRC}UE/EMM/Attach.c - ${NAS_SRC}UE/EMM/Authentication.c - ${NAS_SRC}UE/EMM/Detach.c - ${NAS_SRC}UE/EMM/emm_main.c - ${NAS_SRC}UE/EMM/EmmStatusHdl.c - ${NAS_SRC}UE/EMM/Identification.c - ${NAS_SRC}UE/EMM/IdleMode.c - ${NAS_SRC}UE/EMM/LowerLayer.c - ${NAS_SRC}UE/EMM/SecurityModeControl.c - ${NAS_SRC}UE/EMM/ServiceRequestHdl.c - ${NAS_SRC}UE/EMM/TrackingAreaUpdate.c - ) - set(libnas_ue_emm_sap_OBJS - ${NAS_SRC}UE/EMM/SAP/emm_as.c - ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredAttachNeeded.c - ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredAttemptingToAttach.c - ${NAS_SRC}UE/EMM/SAP/EmmDeregistered.c - ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredInitiated.c - ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredLimitedService.c - ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredNoCellAvailable.c - ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredNoImsi.c - ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredNormalService.c - ${NAS_SRC}UE/EMM/SAP/EmmDeregisteredPlmnSearch.c - ${NAS_SRC}UE/EMM/SAP/emm_esm.c - ${NAS_SRC}UE/EMM/SAP/emm_fsm.c - ${NAS_SRC}UE/EMM/SAP/EmmNull.c - ${NAS_SRC}UE/EMM/SAP/emm_recv.c - ${NAS_SRC}UE/EMM/SAP/emm_reg.c - ${NAS_SRC}UE/EMM/SAP/EmmRegisteredAttemptingToUpdate.c - ${NAS_SRC}UE/EMM/SAP/EmmRegistered.c - ${NAS_SRC}UE/EMM/SAP/EmmRegisteredImsiDetachInitiated.c - ${NAS_SRC}UE/EMM/SAP/EmmRegisteredInitiated.c - ${NAS_SRC}UE/EMM/SAP/EmmRegisteredLimitedService.c - ${NAS_SRC}UE/EMM/SAP/EmmRegisteredNoCellAvailable.c - ${NAS_SRC}UE/EMM/SAP/EmmRegisteredNormalService.c - ${NAS_SRC}UE/EMM/SAP/EmmRegisteredPlmnSearch.c - ${NAS_SRC}UE/EMM/SAP/EmmRegisteredUpdateNeeded.c - ${NAS_SRC}UE/EMM/SAP/emm_sap.c - ${NAS_SRC}UE/EMM/SAP/emm_send.c - ${NAS_SRC}UE/EMM/SAP/EmmServiceRequestInitiated.c - ${NAS_SRC}UE/EMM/SAP/EmmTrackingAreaUpdatingInitiated.c - ) - set (libnas_ue_esm_OBJS - ${NAS_SRC}UE/ESM/DedicatedEpsBearerContextActivation.c - ${NAS_SRC}UE/ESM/DefaultEpsBearerContextActivation.c - ${NAS_SRC}UE/ESM/EpsBearerContextDeactivation.c - ${NAS_SRC}UE/ESM/esm_ebr.c - ${NAS_SRC}UE/ESM/esm_ebr_context.c - ${NAS_SRC}UE/ESM/esm_ip.c - ${NAS_SRC}UE/ESM/esm_main.c - ${NAS_SRC}UE/ESM/esm_pt.c - ${NAS_SRC}UE/ESM/EsmStatusHdl.c - ${NAS_SRC}UE/ESM/PdnConnectivity.c - ${NAS_SRC}UE/ESM/PdnDisconnect.c - ) - set(libnas_ue_esm_sap_OBJS - ${NAS_SRC}UE/ESM/SAP/esm_recv.c - ${NAS_SRC}UE/ESM/SAP/esm_send.c - ${NAS_SRC}UE/ESM/SAP/esm_sap.c - ) - add_library(LIB_NAS_UE - ${NAS_SRC}UE/nas_itti_messaging.c - ${NAS_SRC}UE/nas_network.c - ${NAS_SRC}UE/nas_parser.c - ${NAS_SRC}UE/nas_proc.c - ${NAS_SRC}UE/nas_user.c - ${libnas_api_OBJS} - ${libnas_ue_api_OBJS} - ${libnas_emm_msg_OBJS} - ${libnas_esm_msg_OBJS} - ${libnas_ies_OBJS} - ${libnas_utils_OBJS} - ${libnas_ue_emm_OBJS} - ${libnas_ue_emm_sap_OBJS} - ${libnas_ue_esm_OBJS} - ${libnas_ue_esm_sap_OBJS} - ) - add_dependencies(LIB_NAS_UE rrc_flag) - set(NAS_UE_LIB LIB_NAS_UE) - - include_directories(${NAS_SRC}UE) - include_directories(${NAS_SRC}UE/API/USER) - include_directories(${NAS_SRC}UE/API/USIM) - include_directories(${NAS_SRC}UE/EMM) - include_directories(${NAS_SRC}UE/EMM/SAP) - include_directories(${NAS_SRC}UE/ESM) - include_directories(${NAS_SRC}UE/ESM/SAP) -endif() - - -if(ITTI_SIM OR RFSIM_NAS) set(libnas_ue_api_OBJS ${NAS_SRC}UE/API/USER/at_command.c ${NAS_SRC}UE/API/USER/at_error.c @@ -2683,6 +2580,27 @@ if(ITTI_SIM OR RFSIM_NAS) add_dependencies(LIB_NAS_SIMUE rrc_flag) set(NAS_SIM_LIB LIB_NAS_SIMUE) + add_library(LIB_NAS_UE + ${NAS_SRC}UE/nas_itti_messaging.c + ${NAS_SRC}UE/nas_network.c + ${NAS_SRC}UE/nas_parser.c + ${NAS_SRC}UE/nas_proc.c + ${NAS_SRC}UE/nas_user.c + ${libnas_api_OBJS} + ${libnas_ue_api_OBJS} + ${libnas_emm_msg_OBJS} + ${libnas_esm_msg_OBJS} + ${libnas_ies_OBJS} + ${libnas_utils_OBJS} + ${libnas_ue_emm_OBJS} + ${libnas_ue_emm_sap_OBJS} + ${libnas_ue_esm_OBJS} + ${libnas_ue_esm_sap_OBJS} + ) + add_dependencies(LIB_NAS_UE rrc_flag) + set(NAS_UE_LIB LIB_NAS_UE) + + include_directories(${NAS_SRC}NR_UE) include_directories(${NAS_SRC}UE) include_directories(${NAS_SRC}UE/API/USER) @@ -2691,7 +2609,6 @@ if(ITTI_SIM OR RFSIM_NAS) include_directories(${NAS_SRC}UE/EMM/SAP) include_directories(${NAS_SRC}UE/ESM) include_directories(${NAS_SRC}UE/ESM/SAP) -endif() # nbiot add_definitions("-DNUMBER_OF_UE_MAX_NB_IoT=16") diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 29257e482f3fb745ff2fc2a3907db196191c3de8..3472b14efcf09695f156d57ee6cbd69cc89ff1b3 100755 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -1101,7 +1101,9 @@ (Test16: 11 PTRS, 0 Interpolated Symbols), (Test17: Mapping type A, 2 DMRS Symbols), (Test18: Mapping type A, 3 DMRS Symbols), - (Test19: Mapping type B, 4 DMRS Symbols)</desc> + (Test19: Mapping type B, 4 DMRS Symbols), + (Test20: 4x4 MIMO, 1 Layer), + (Test21: 4x4 MIMO, 2 Layers)</desc> <pre_compile_prog></pre_compile_prog> <compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog> <compile_prog_args> --phy_simulators -c </compile_prog_args> @@ -1126,8 +1128,10 @@ -n100 -s5 -T 2 0 4 -n100 -s2 -U 2 0 1 -n100 -s2 -U 2 0 2 - -n100 -s2 -U 2 1 3</main_exec_args> - <tags>nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11 nr_dlsim.test12 nr_dlsim.test13 nr_dlsim.test14 nr_dlsim.test15 nr_dlsim.test16 nr_dlsim.test17 nr_dlsim.test18 nr_dlsim.test19</tags> + -n100 -s2 -U 2 1 3 + -n10 -s20 -U 3 0 0 2 -gR -x1 -y4 -z4 + -n10 -s20 -U 3 0 0 2 -gR -x2 -y4 -z4</main_exec_args> + <tags>nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11 nr_dlsim.test12 nr_dlsim.test13 nr_dlsim.test14 nr_dlsim.test15 nr_dlsim.test16 nr_dlsim.test17 nr_dlsim.test18 nr_dlsim.test19 nr_dlsim.test20 nr_dlsim.test21</tags> <search_expr_true>PDSCH test OK</search_expr_true> <search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false> <nruns>3</nruns> @@ -1314,11 +1318,11 @@ -n100 -s5 -T 2 1 2 -U 2 0 2 -n100 -s5 -T 2 2 2 -U 2 1 2 -n100 -s5 -a4 -b8 -T 2 1 2 -U 2 1 3 - -n100 -s2 -Z - -n100 -s2 -Z -r75 - -n100 -s2 -Z -r216 -R217 - -n100 -s2 -Z -r270 -R273 - -n100 -s2 -Z -U 2 0 2 + -n100 -s5 -Z + -n100 -s5 -Z -r75 + -n50 -s5 -Z -r216 -R217 + -n50 -s5 -Z -r270 -R273 + -n100 -s5 -Z -U 2 0 2 -n100 -m16 -s10 -z2</main_exec_args> <tags>nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 nr_ulsim.test9 nr_ulsim.test10 nr_ulsim.test11 nr_ulsim.test12 nr_ulsim.test13 nr_ulsim.test14 nr_ulsim.test15</tags> diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index d95b30e052406ccdf9c95a957caf977d4b65134d..7e7556248eb5461705ff3beb7a0c28b3ead4ae49 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -68,7 +68,6 @@ USRP_REC_PLAY="False" BUILD_ECLIPSE=0 NR="False" ITTI_SIM="False" -RFSIM_NAS="False" SANITIZE_ADDRESS="False" OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope msc" RU=0 @@ -275,7 +274,6 @@ function main() { RU=0 nrUE=1 rfsimNas=1 - RFSIM_NAS="True" NR="True" echo_info "Will compile NR UE" shift;; @@ -633,7 +631,6 @@ function main() { echo "set ( SKIP_SHARED_LIB_FLAG $SKIP_SHARED_LIB_FLAG )" >> $cmake_file echo "set ( RU $RU )" >> $cmake_file echo "set ( ITTI_SIM $ITTI_SIM )" >> $cmake_file - echo "set ( RFSIM_NAS $RFSIM_NAS )" >> $cmake_file echo "set ( SANITIZE_ADDRESS $SANITIZE_ADDRESS )" >> $cmake_file echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file cd $DIR/$build_dir/build diff --git a/cmake_targets/install_external_packages.ubuntu20 b/cmake_targets/install_external_packages.ubuntu20 index 4b1cda42f8c32e017afb276ed45cbba283b303b7..95293198b971c90e77ada8243831ca334e83fabb 100755 --- a/cmake_targets/install_external_packages.ubuntu20 +++ b/cmake_targets/install_external_packages.ubuntu20 @@ -159,16 +159,8 @@ install_protobuf_from_source(){ #cd protobuf-2.6.1/ rm -rf /tmp/protobuf-cpp-3.3.0.tar.gz* /tmp/protobuf-3.3.0 wget --tries=3 --retry-connrefused https://github.com/google/protobuf/releases/download/v3.3.0/protobuf-cpp-3.3.0.tar.gz - tar -xzvf protobuf-cpp-3.3.0.tar.gz --owner $(id -u) --group $(id -g) --no-same-owner - cd protobuf-3.3.0/ - else - export LD_LIBRARY_PATH=/usr/local/lib #protoc needs to know where toclook for shared libs - rm -rf /tmp/protobuf - git clone --depth=1 --branch=v3.3.0 https://github.com/protocolbuffers/protobuf.git /tmp/protobuf - cd /tmp/protobuf - git submodule update --init --recursive - ./autogen.sh - fi + tar -xzvf protobuf-cpp-3.3.0.tar.gz --owner "$USER" --group "$(groups | cut -d" " -f1)" --no-same-owner + cd protobuf-3.3.0/ || exit ./configure echo "Compiling protobuf" make -j"$(nproc)" @@ -339,6 +331,10 @@ check_install_ubuntu_packages() { $SUDO apt install -y software-properties-common case "$(get_distribution_release)" in "ubuntu20.04") + specific_packages="libtasn1-6-dev libgnutls28-dev iproute2 libconfig-dev" + LAPACK_LIBNAME="liblapack.so-x86_64-linux-gnu" + LAPACK_TARGET="/usr/lib/x86_64-linux-gnu/atlas/liblapack.so" + ;; "ubuntu21.04") specific_packages="libtasn1-6-dev libgnutls28-dev iproute2 libconfig-dev" LAPACK_LIBNAME="liblapack.so-x86_64-linux-gnu" diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 30fdb7eb1ec860c22a855465d15d671f4e66947f..9880b66685f6097b720ad2fca8a63ba4aaade752 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -113,7 +113,7 @@ check_supported_distribution() { "rhel7.6") return 0 ;; "rhel7.7") return 0 ;; "rhel7.8") return 0 ;; - "rhel7.9") return 0 ;; + "rhel7.9") return 0 ;; "rhel8.2") return 0 ;; "rhel8.3") return 0 ;; "rhel8.4") return 0 ;; diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h index 0cbae7ae2c79fa784ed078601fc71de313fad6b8..fa95d5a6fee9436755a6c42207cf1a598985742b 100644 --- a/common/utils/LOG/log.h +++ b/common/utils/LOG/log.h @@ -434,6 +434,7 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int # define LOG_M(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format, 0);} while(0) # define LOG_VAR(A,B) A B +# define T_ACTIVE(a) (0) # endif /* T_TRACER */ /* avoid warnings for variables only used in LOG macro's but set outside debug section */ #define GCC_NOTUSED __attribute__((unused)) diff --git a/common/utils/minimal_stub.c b/common/utils/minimal_stub.c index 86454fe53f87dad750a11d7c0a1f07d67b5e5379..79e35bf7a6f8cef12bd29cb156711f5f67a884d6 100644 --- a/common/utils/minimal_stub.c +++ b/common/utils/minimal_stub.c @@ -1,4 +1,6 @@ +#ifndef T_TRACER int T_stdout; +#endif void exit_function(const char *file, const char *function, const int line, const char *s) { } diff --git a/common/utils/ocp_itti/intertask_interface.cpp b/common/utils/ocp_itti/intertask_interface.cpp index c774da57e6176a467592ee0ce9b097aee2be4c55..4e5323aec98c85d0c807ad195bbfa6ed4f022c8e 100644 --- a/common/utils/ocp_itti/intertask_interface.cpp +++ b/common/utils/ocp_itti/intertask_interface.cpp @@ -136,7 +136,7 @@ extern "C" { LOG_E(TMR,"Queue for %s task contains %ld messages\n", itti_get_task_name(destination_task_id), s ); if ( s > 50 ) - LOG_I(TMR,"Queue for %s task size: %ld\n",itti_get_task_name(destination_task_id), s+1); + LOG_I(TMR,"Queue for %s task size: %ld (last message %s)\n",itti_get_task_name(destination_task_id), s+1,ITTI_MSG_NAME(message)); t->message_queue.insert(t->message_queue.begin(), message); eventfd_t sem_counter = 1; diff --git a/common/utils/utils.h b/common/utils/utils.h index da7c453b0375d25165350b0bb4bcd474e14a7579..16631586c413ec7532812da13f28ecd79dd7a9c1 100644 --- a/common/utils/utils.h +++ b/common/utils/utils.h @@ -7,6 +7,7 @@ extern "C" { #endif +#define sizeofArray(a) (sizeof(a)/sizeof(*(a))) void *calloc_or_fail(size_t size); void *malloc_or_fail(size_t size); diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md index 2171fc2f1fd567a655701ea92fa468d9f7c43919..7c202dc52de2c52aefdb53edebb4872b9674266e 100644 --- a/doc/FEATURE_SET.md +++ b/doc/FEATURE_SET.md @@ -257,7 +257,7 @@ The following features are valid for the gNB and the 5G-NR UE. * FDD * Normal CP * 30 kHz subcarrier spacing -* Bandwidths up to 80MHz (217 Physical Resource Blocks) +* Bandwidths: 10, 20, 40, 80, 100MHz (273 Physical Resource Blocks) * Intermediate downlink and uplink frequencies to interface with IF equipment * Single antenna port (single beam) * Slot format: 14 OFDM symbols in UL or DL @@ -277,10 +277,20 @@ The following features are valid for the gNB and the 5G-NR UE. - user-specific search space configured by RRC - DCI formats: 00, 10 (01 and 11 **under integration**) * Generation of NR-PDSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc). - - Single symbol DMRS, DMRS-TypeA-Position Pos2, DMRS configuration type 1 - - PDSCH mapping type A + - PDSCH mapping type A and B + - DMRS configuration type 1 and 2 + - Single and multiple DMRS symbols + - PTRS support + - Support for 1, 2 and 4 TX antennas + - Support for up to 2 layers (currently limited to DMRS configuration type 2) * NR-CSI Generation of sequence at PHY (**under integration**) * NR-PUSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc). + - PUSCH mapping type A and B + - DMRS configuration type 1 and 2 + - Single and multiple DMRS symbols + - PTRS support + - Support for 1 RX antenna + - Support for 1 layer * NR-PUCCH - Format 0 (2 bits, mainly for ACK/NACK) - Format 2 (up to 64 bits, mainly for CSI feedback) @@ -320,27 +330,33 @@ The following features are valid for the gNB and the 5G-NR UE. - Creates TUN interface to PDCP to inject and receive user-place traffic - Will only work with OAI gNB configured in the same mode -## UE PHY Layer ## +## NR UE PHY Layer ## * Initial synchronization * Time tracking based on PBCH DMRS -* Time tracking based on PBCH DMRS * Frequency offset estimation -* PBCH RX -* PDCCH RX -* PDSCH RX, including a first version of dual stream receiver for PDSCH * 30KHz SCS for FR1 and 120 KHz SCS for FR2 -* Generation of NR-PSS/NR-SSS +* Reception of NR-PSS/NR-SSS * NR-PBCH supports multiple SSBs and flexible periodicity -* Generation of NR-PDCCH for SIB1 (including generation of DCI, polar encoding, scrambling, modulation, RB mapping, etc) +* Reception of NR-PDCCH for SIB1 (including reception of DCI, polar decoding, de-scrambling, de-modulation, RB de-mapping, etc) - common search space configured by MIB - user-specific search space configured by RRC - DCI formats: 00, 10 (01 and 11 **under integration**) -* Generation of NR-PDSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc). - - Single symbol DMRS, DMRS-TypeA-Position Pos2, DMRS configuration type 1 - - PDSCH mapping type A +* Reception of NR-PDSCH (including Segmentation, LDPC decoding, rate de-matching, de-scrambling, de-modulation, RB de-mapping, etc). + - PDSCH mapping type A and B + - DMRS configuration type 1 and 2 + - Single and multiple DMRS symbols + - PTRS support + - Support for 1, 2 and 4 RX antennas + - Support for up to 2 layers (currently limited to DMRS configuration type 2) * NR-CSI Generation of sequence at PHY (**under integration**) * NR-PUSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc). + - PUSCH mapping type A and B + - DMRS configuration type 1 and 2 + - Single and multiple DMRS symbols + - PTRS support + - Support for 1 TX antenna + - Support for 1 layer * NR-PUCCH - Format 0 (2 bits, mainly for ACK/NACK) - Format 2 (up to 64 bits, mainly for CSI feedback) @@ -351,7 +367,7 @@ The following features are valid for the gNB and the 5G-NR UE. * Encoder and decoder for short block -## UE Higher Layers ## +## NR UE Higher Layers ## **UE MAC** * Minimum system information (MSI) diff --git a/executables/main-ocp.c b/executables/main-ocp.c index c5f18419a3d397319fc106d2086423493738eab7..0355582b2b4e76848588cd22a580dd4577569ab0 100644 --- a/executables/main-ocp.c +++ b/executables/main-ocp.c @@ -73,7 +73,6 @@ int sync_var=-1; //!< protected by mutex \ref sync_mutex. int config_sync_var=-1; volatile int oai_exit = 0; double cpuf; -msc_interface_t msc_interface; THREAD_STRUCT thread_struct; uint16_t sf_ahead=4; diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index ea675eba9e8caf737f41edff715b8135da91ac36..e9319f9d3c1070bc604662e481e352d26d4800f3 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -86,7 +86,7 @@ #include "T.h" #include "nfapi/oai_integration/vendor_ext.h" #include <nfapi/oai_integration/nfapi_pnf.h> -#include <PHY/NR_TRANSPORT/nr_ulsch.h> +#include <openair1/PHY/NR_TRANSPORT/nr_ulsch.h> #include <PHY/NR_ESTIMATION/nr_ul_estimation.h> //#define DEBUG_THREADS 1 @@ -356,7 +356,7 @@ void *nrL1_stats_thread(void *param) { while (!oai_exit) { sleep(1); fd=fopen("nrL1_stats.log","w"); - AssertFatal(fd!=NULL,"Cannot open ngL1_stats.log\n"); + AssertFatal(fd!=NULL,"Cannot open nrL1_stats.log\n"); dump_nr_I0_stats(fd,gNB); dump_pusch_stats(fd,gNB); // nr_dump_uci_stats(fd,eNB,eNB->proc.L1_proc_tx.frame_tx); @@ -383,6 +383,7 @@ void init_gNB_Tpool(int inst) { sprintf(ul_pool+2+s_offset,",-1"); s_offset += 3; } + if (getenv("noThreads")) strcpy(ul_pool, "n"); initTpool(ul_pool, gNB->threadPool, false); // ULSCH decoder result FIFO gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t)); diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 421ff4ad3ec54401399652ad2403343181a6e9b1..be6d13daad99a6d8863032cb4b07551f46a53b7d 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -746,9 +746,9 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { // currently we switch beams every 10 slots (should = 1 TDD period in FR2) and we take the beam index of the first symbol of the first slot of this period int beam=0; if (slot%10==0) { - if (ru->common.beam_id[0][slot*fp->symbols_per_slot] < 8) { - beam = ru->common.beam_id[0][slot*fp->symbols_per_slot] | 8; - } + if ( ru->common.beam_id && (ru->common.beam_id[0][slot*fp->symbols_per_slot] < 8)) { + beam = ru->common.beam_id[0][slot*fp->symbols_per_slot] | 8; + } } /* if (slot==0 || slot==40) beam=0|8; @@ -892,6 +892,18 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) { cfg->tx_bw = 80e6; cfg->rx_bw = 80e6; } + break; + case 133 : + if (fp->threequarter_fs) { + AssertFatal(1==0,"N_RB %d cannot use 3/4 sampling\n",N_RB); + } + else { + cfg->sample_rate=61.44e6; + cfg->samples_per_frame = 614400; + cfg->tx_bw = 50e6; + cfg->rx_bw = 50e6; + } + break; case 106: if (fp->threequarter_fs) { @@ -906,7 +918,7 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) { cfg->tx_bw = 40e6; cfg->rx_bw = 40e6; } - break; + break; case 51: if (fp->threequarter_fs) { cfg->sample_rate=23.04e6; @@ -2049,6 +2061,7 @@ static void NRRCconfig_RU(void) RC.ru[j]->att_rx = *(RUParamList.paramarray[j][RU_ATT_RX_IDX].uptr); RC.ru[j]->if_frequency = *(RUParamList.paramarray[j][RU_IF_FREQUENCY].u64ptr); RC.ru[j]->if_freq_offset = *(RUParamList.paramarray[j][RU_IF_FREQ_OFFSET].iptr); + RC.ru[j]->do_precoding = *(RUParamList.paramarray[j][RU_DO_PRECODING].iptr); if (config_isparamset(RUParamList.paramarray[j], RU_BF_WEIGHTS_LIST_IDX)) { RC.ru[j]->nb_bfw = RUParamList.paramarray[j][RU_BF_WEIGHTS_LIST_IDX].numelt; diff --git a/executables/nr-softmodem-common.h b/executables/nr-softmodem-common.h index 813ffcf8fac29f3060f72dbe74057fb8cb03755a..00f786dfdcfd6d0459a47357431a1595bc4c7e59 100644 --- a/executables/nr-softmodem-common.h +++ b/executables/nr-softmodem-common.h @@ -69,6 +69,7 @@ #define CONFIG_HLP_EXMCAL "Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n" #define CONFIG_HLP_ITTIL "Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n" #define CONFIG_HLP_DLMCS_PHYTEST "Set the downlink MCS for PHYTEST mode\n" +#define CONFIG_HLP_DLNL_PHYTEST "Set the downlink nrOfLayers for PHYTEST mode\n" #define CONFIG_HLP_STMON "Enable processing timing measurement of lte softmodem on per subframe basis \n" #define CONFIG_HLP_PRB "Set the PRB, valid values: 6, 25, 50, 100 \n" #define CONFIG_HLP_MSLOTS "Skip the missed slots/subframes \n" diff --git a/executables/nr-softmodem.h b/executables/nr-softmodem.h index 928558013c8e6bd3dbc6bbfc4fdecbdadb5b7a43..896c363cbf15ed17d06d6ea242d8c912f9e9b4a1 100644 --- a/executables/nr-softmodem.h +++ b/executables/nr-softmodem.h @@ -22,6 +22,7 @@ {"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \ {"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, i8ptr:&threequarter_fs, defintval:0, TYPE_INT8, 0}, \ {"m" , CONFIG_HLP_DLMCS_PHYTEST,0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \ + {"l" , CONFIG_HLP_DLNL_PHYTEST,0, uptr:&target_dl_Nl, defintval:0, TYPE_UINT, 0}, \ {"t" , CONFIG_HLP_ULMCS_PHYTEST,0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \ {"M" , CONFIG_HLP_DLBW_PHYTEST,0, uptr:&target_dl_bw, defintval:0, TYPE_UINT, 0}, \ {"T" , CONFIG_HLP_ULBW_PHYTEST,0, uptr:&target_ul_bw, defintval:0, TYPE_UINT, 0}, \ @@ -34,6 +35,7 @@ #include "threads_t.h" extern threads_t threads; extern uint32_t target_dl_mcs; +extern uint32_t target_dl_Nl; extern uint32_t target_ul_mcs; extern uint32_t target_dl_bw; extern uint32_t target_ul_bw; diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index cbc79912a2c96f0b1679790e72695702dc2008fd..23982c6bc33ffc579b4cf589a00cafc8a5fea007 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -86,9 +86,7 @@ unsigned short config_frames[4] = {2,9,11,13}; #include "executables/softmodem-common.h" #include "executables/thread-common.h" -#if defined(ITTI_SIM) || defined(RFSIM_NAS) #include "nr_nas_msg_sim.h" -#endif extern const char *duplex_mode[]; THREAD_STRUCT thread_struct; @@ -195,12 +193,10 @@ int create_tasks_nrue(uint32_t ue_nb) { LOG_E(NR_RRC, "Create task for RRC UE failed\n"); return -1; } -#if defined(ITTI_SIM) || defined(RFSIM_NAS) if (itti_create_task (TASK_NAS_NRUE, nas_nrue_task, NULL) < 0) { LOG_E(NR_RRC, "Create task for NAS UE failed\n"); return -1; } -#endif } itti_wait_ready(0); @@ -364,8 +360,8 @@ void init_openair0(void) { openair0_cfg[card].num_rb_dl = frame_parms->N_RB_DL; openair0_cfg[card].clock_source = get_softmodem_params()->clock_source; openair0_cfg[card].time_source = get_softmodem_params()->timing_source; - openair0_cfg[card].tx_num_channels = min(2, frame_parms->nb_antennas_tx); - openair0_cfg[card].rx_num_channels = min(2, frame_parms->nb_antennas_rx); + openair0_cfg[card].tx_num_channels = min(4, frame_parms->nb_antennas_tx); + openair0_cfg[card].rx_num_channels = min(4, frame_parms->nb_antennas_rx); LOG_I(PHY, "HW: Configuring card %d, sample_rate %f, tx/rx num_channels %d/%d, duplex_mode %s\n", card, diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index f9be62797472f1f3cc7b96977bc1bc08ab4b755e..dcff18f02580f14aefc17d649c798ab1b6b23e42 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -595,27 +595,6 @@ void init_nr_transport(PHY_VARS_gNB *gNB) { exit(-1); } - /* - LOG_I(PHY,"Initializing nFAPI for ULSCH, UE %d\n",i); - // [hna] added here for RT implementation - uint8_t harq_pid = 0; - nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &gNB->ulsch[i+1][j]->harq_processes[harq_pid]->ulsch_pdu; - - // --------- setting rel15_ul parameters ---------- - rel15_ul->rnti = 0x1234; - rel15_ul->ulsch_pdu_rel15.start_rb = 0; - rel15_ul->ulsch_pdu_rel15.number_rbs = 50; - rel15_ul->ulsch_pdu_rel15.start_symbol = 2; - rel15_ul->ulsch_pdu_rel15.number_symbols = 12; - rel15_ul->ulsch_pdu_rel15.length_dmrs = gNB->dmrs_UplinkConfig.pusch_maxLength; - rel15_ul->ulsch_pdu_rel15.Qm = 2; - rel15_ul->ulsch_pdu_rel15.R = 679; - rel15_ul->ulsch_pdu_rel15.mcs = 9; - rel15_ul->ulsch_pdu_rel15.rv = 0; - rel15_ul->ulsch_pdu_rel15.n_layers = 1; - /////////////////////////////////////////////////// - */ - } } diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c index 8189a7ab341b6ab266df8633e050c3aaf503fe1b..097c2b3ad2dd4e6b95ac5859a23b541070b64a92 100644 --- a/openair1/PHY/INIT/nr_init_ru.c +++ b/openair1/PHY/INIT/nr_init_ru.c @@ -122,36 +122,39 @@ int nr_phy_init_RU(RU_t *ru) { ru->num_gNB,NUMBER_OF_gNB_MAX); LOG_I(PHY,"[INIT] %s() ru->num_gNB:%d \n", __FUNCTION__, ru->num_gNB); + + if (ru->do_precoding == 1) { + int beam_count = 0; + if (ru->nb_tx>1) {//Enable beamforming when nb_tx > 1 + for (p=0;p<ru->nb_log_antennas;p++) { + //if ((fp->L_ssb >> (63-p)) & 0x01)//64 bit-map with the MSB @2â¶Â³ corresponds to SSB ssb_index 0 + beam_count++; + } + AssertFatal(ru->nb_bfw==(beam_count*ru->nb_tx),"Number of beam weights from config file is %d while the expected number is %d",ru->nb_bfw,(beam_count*ru->nb_tx)); - int beam_count = 0; - if (ru->nb_tx>1) {//Enable beamforming when nb_tx > 1 - for (p=0;p<ru->nb_log_antennas;p++) { - //if ((fp->L_ssb >> (63-p)) & 0x01)//64 bit-map with the MSB @2â¶Â³ corresponds to SSB ssb_index 0 - beam_count++; - } - AssertFatal(ru->nb_bfw==(beam_count*ru->nb_tx),"Number of beam weights from config file is %d while the expected number is %d",ru->nb_bfw,(beam_count*ru->nb_tx)); - - int l_ind = 0; for (i=0; i<ru->num_gNB; i++) { + int l_ind = 0; for (p=0;p<ru->nb_log_antennas;p++) { //if ((fp->L_ssb >> (63-p)) & 0x01) { - ru->beam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*)); - for (j=0; j<ru->nb_tx; j++) { - ru->beam_weights[i][p][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t)); - for (re=0; re<fp->ofdm_symbol_size; re++) - ru->beam_weights[i][p][j][re] = ru->bw_list[j][l_ind]; - //printf("Beam Weight %08x for beam %d and tx %d\n",ru->bw_list[i][l_ind],p,j); - l_ind++; - } // for j - //} + ru->beam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*)); + for (j=0; j<ru->nb_tx; j++) { + ru->beam_weights[i][p][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t)); + AssertFatal(ru->bw_list[i],"ru->bw_list[%d] is null\n",i); + for (re=0; re<fp->ofdm_symbol_size; re++) + ru->beam_weights[i][p][j][re] = ru->bw_list[i][l_ind]; + //printf("Beam Weight %08x for beam %d and tx %d\n",ru->bw_list[i][l_ind],p,j); + l_ind++; + } // for j + //} } // for p } //for i - } + } - ru->common.beam_id = (uint8_t**)malloc16_clear(ru->nb_tx*sizeof(uint8_t*)); - for(i=0; i< ru->nb_tx; ++i) { - ru->common.beam_id[i] = (uint8_t*)malloc16_clear(fp->symbols_per_slot*fp->slots_per_frame*sizeof(uint8_t)); - memset(ru->common.beam_id[i],255,fp->symbols_per_slot*fp->slots_per_frame); + ru->common.beam_id = (uint8_t**)malloc16_clear(ru->nb_tx*sizeof(uint8_t*)); + for(i=0; i< ru->nb_tx; ++i) { + ru->common.beam_id[i] = (uint8_t*)malloc16_clear(fp->symbols_per_slot*fp->slots_per_frame*sizeof(uint8_t)); + memset(ru->common.beam_id[i],255,fp->symbols_per_slot*fp->slots_per_frame); + } } } // !=IF5 diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index a9c71d158256b3cbfdb5631977958fb34f19c6a5..68947b0c6bdf4b09b58c878500035c299172e245 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -143,8 +143,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, uint16_t N_n_scid[2] = {0,1}; // [HOTFIX] This is a temporary implementation of scramblingID0 and scramblingID1 which are given by DMRS-UplinkConfig int n_scid; abstraction_flag = 0; - // dmrs_UplinkConfig_t *dmrs_Uplink_Config = &ue->pusch_config.dmrs_UplinkConfig; - // ptrs_UplinkConfig_t *ptrs_Uplink_Config = &ue->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig; LOG_I(PHY, "Initializing UE vars (abstraction %u) for gNB TXant %u, UE RXant %u\n", abstraction_flag, fp->nb_antennas_tx, fp->nb_antennas_rx); //LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_UE][MOD %02u][]\n", ue->Mod_id+NB_gNB_INST); phy_init_nr_top(ue); @@ -188,29 +186,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, /////////////////////////PUSCH DMRS init///////////////////////// /////////// - - // default values until overwritten by RRCConnectionReconfiguration - - for (i=0; i<MAX_NR_OF_UL_ALLOCATIONS; i++) { - ue->pusch_config.pusch_TimeDomainResourceAllocation[i] = (PUSCH_TimeDomainResourceAllocation_t *)malloc16(sizeof(PUSCH_TimeDomainResourceAllocation_t)); - ue->pusch_config.pusch_TimeDomainResourceAllocation[i]->mappingType = typeB; - } - - for (i=0;i<MAX_NR_OF_DL_ALLOCATIONS;i++){ - ue->PDSCH_Config.pdsch_TimeDomainResourceAllocation[i] = (PDSCH_TimeDomainResourceAllocation_t *)malloc16(sizeof(PDSCH_TimeDomainResourceAllocation_t)); - ue->PDSCH_Config.pdsch_TimeDomainResourceAllocation[i]->mappingType = typeA; - } - - //------------- config DMRS parameters--------------// - // dmrs_Uplink_Config->pusch_dmrs_type = pusch_dmrs_type1; - // dmrs_Uplink_Config->pusch_dmrs_AdditionalPosition = pusch_dmrs_pos0; - // dmrs_Uplink_Config->pusch_maxLength = pusch_len1; - //-------------------------------------------------// - ue->dmrs_DownlinkConfig.pdsch_dmrs_type = pdsch_dmrs_type1; - ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition = pdsch_dmrs_pos0; - ue->dmrs_DownlinkConfig.pdsch_maxLength = pdsch_len1; - //-------------------------------------------------// - ue->nr_gold_pusch_dmrs = (uint32_t ****)malloc16(fp->slots_per_frame*sizeof(uint32_t ***)); pusch_dmrs = ue->nr_gold_pusch_dmrs; n_scid = 0; // This quantity is indicated by higher layer parameter dmrs-SeqInitialization diff --git a/openair1/PHY/LTE_TRANSPORT/transport_common.h b/openair1/PHY/LTE_TRANSPORT/transport_common.h index 93ca7195deeb40a6f9a312ea7ec8134d5ef59556..135f3cdf4bb1b372e775f42e4cbfe04590748568 100644 --- a/openair1/PHY/LTE_TRANSPORT/transport_common.h +++ b/openair1/PHY/LTE_TRANSPORT/transport_common.h @@ -65,22 +65,6 @@ #define MAX_NUM_CHANNEL_BITS (14*1200*6) // 14 symbols, 1200 REs, 12 bits/RE #define MAX_NUM_RE (14*1200) -#if !defined(SI_RNTI) - #define SI_RNTI (rnti_t)0xffff - #define SI_RNTI_MBMS (rnti_t)0xfff9 -#endif -#if !defined(M_RNTI) - #define M_RNTI (rnti_t)0xfffd -#endif -#if !defined(P_RNTI) - #define P_RNTI (rnti_t)0xfffe -#endif -#if !defined(CBA_RNTI) - #define CBA_RNTI (rnti_t)0xfff4 -#endif -#if !defined(C_RNTI) - #define C_RNTI (rnti_t)0x1234 -#endif // These are the codebook indexes according to Table 6.3.4.2.3-1 of 36.211 //1 layer #define PMI_2A_11 0 diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c index 5a4b1adbb84ff7dc7a273f223606d058e7ce615d..920b78eac2b0880311bbac733c9b4fcbcd84ca76 100644 --- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c +++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c @@ -111,9 +111,10 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue, int32_t *output, unsigned short p, unsigned char lp, - unsigned short nb_pdsch_rb) + unsigned short nb_pdsch_rb, + uint8_t config_type) { - int8_t w,config_type; + int8_t w; short *mod_table; unsigned char idx=0; @@ -121,18 +122,16 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue, array_of_w *wf; array_of_w *wt; - config_type = ue->dmrs_DownlinkConfig.pdsch_dmrs_type; - - wf = (config_type==pdsch_dmrs_type1) ? wf1 : wf2; - wt = (config_type==pdsch_dmrs_type1) ? wt1 : wt2; + wf = (config_type==NFAPI_NR_DMRS_TYPE1) ? wf1 : wf2; + wt = (config_type==NFAPI_NR_DMRS_TYPE1) ? wt1 : wt2; if (config_type > 1) LOG_E(PHY,"Bad PDSCH DMRS config type %d\n", config_type); - if ((p>=1000) && (p<((config_type==pdsch_dmrs_type1) ? 1008 : 1012))) { + if ((p>=1000) && (p<((config_type==NFAPI_NR_DMRS_TYPE1) ? 1008 : 1012))) { if (ue->frame_parms.Ncp == NORMAL) { - for (int i=0; i<nb_pdsch_rb*((config_type==pdsch_dmrs_type1) ? 6:4); i++) { + for (int i=0; i<nb_pdsch_rb*((config_type==NFAPI_NR_DMRS_TYPE1) ? 6:4); i++) { w = (wf[p-1000][i&1])*(wt[p-1000][lp]); mod_table = (w==1) ? nr_rx_mod_table : nr_rx_nmod_table; diff --git a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h index 54279a8ad5faf85ace67cc4d4a477db15ce151af..1fca2be2a187dd7643d7898ccfba7bd71b09e94c 100644 --- a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h +++ b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h @@ -52,7 +52,8 @@ int nr_pdsch_dmrs_rx(PHY_VARS_NR_UE *ue, int32_t *output, unsigned short p, unsigned char lp, - unsigned short nb_pdsch_rb); + unsigned short nb_pdsch_rb, + uint8_t config_type); void nr_gold_pbch(PHY_VARS_NR_UE* ue); diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c index ea9675618422895ad556652a0fc8933b13849ebd..54e6b2ac79a497a7660061e738ecea606dba99db 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c @@ -70,7 +70,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, uint32_t **gold_pdcch_dmrs, int32_t *txdataF, int16_t amp, - NR_DL_FRAME_PARMS frame_parms) { + NR_DL_FRAME_PARMS *frame_parms) { int16_t mod_dmrs[NR_MAX_CSET_DURATION][NR_MAX_PDCCH_DMRS_LENGTH>>1] __attribute__((aligned(16))); // 3 for the max coreset duration uint16_t cset_start_sc; @@ -85,7 +85,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, // compute rb_offset and n_prb based on frequency allocation nr_fill_cce_list(gNB,0,pdcch_pdu_rel15); get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource,&n_rb,&rb_offset); - cset_start_sc = frame_parms.first_carrier_offset + (pdcch_pdu_rel15->BWPStart + rb_offset) * NR_NB_SC_PER_RB; + cset_start_sc = frame_parms->first_carrier_offset + (pdcch_pdu_rel15->BWPStart + rb_offset) * NR_NB_SC_PER_RB; for (int d=0;d<pdcch_pdu_rel15->numDlDci;d++) { /*The coreset is initialised @@ -94,7 +94,6 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, * in time: by its first slot and its first symbol*/ const nfapi_nr_dl_dci_pdu_t *dci_pdu = &pdcch_pdu_rel15->dci_pdu[d]; - LOG_D(PHY,"DCI pdu %d, rnti %x, aggregation %d CCE %d Scrambling_Id %x ScramblingRNTI %x PayloadSizeBits %d\n",d,dci_pdu->RNTI,dci_pdu->AggregationLevel,dci_pdu->CceIndex,dci_pdu->ScramblingId,dci_pdu->ScramblingRNTI,dci_pdu->PayloadSizeBits); cset_start_symb = pdcch_pdu_rel15->StartSymbolIndex; cset_nsymb = pdcch_pdu_rel15->DurationSymbols; dci_idx = 0; @@ -165,8 +164,8 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, /// Resource mapping - if (cset_start_sc >= frame_parms.ofdm_symbol_size) - cset_start_sc -= frame_parms.ofdm_symbol_size; + if (cset_start_sc >= frame_parms->ofdm_symbol_size) + cset_start_sc -= frame_parms->ofdm_symbol_size; // Get cce_list indices by reg_idx in ascending order int reg_list_index = 0; @@ -191,8 +190,8 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, k = cset_start_sc + gNB->cce_list[d][cce_idx].reg_list[reg_in_cce_idx].start_sc_idx; - if (k >= frame_parms.ofdm_symbol_size) - k -= frame_parms.ofdm_symbol_size; + if (k >= frame_parms->ofdm_symbol_size) + k -= frame_parms->ofdm_symbol_size; l = cset_start_symb + symbol_idx; @@ -206,26 +205,26 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, for (int m = 0; m < NR_NB_SC_PER_RB; m++) { if (m == (k_prime << 2) + 1) { // DMRS if not already mapped - ((int16_t *) txdataF)[(l * frame_parms.ofdm_symbol_size + k) << 1] = + ((int16_t *) txdataF)[(l * frame_parms->ofdm_symbol_size + k) << 1] = (amp * mod_dmrs[l][dmrs_idx << 1]) >> 15; - ((int16_t *) txdataF)[((l * frame_parms.ofdm_symbol_size + k) << 1) + 1] = + ((int16_t *) txdataF)[((l * frame_parms->ofdm_symbol_size + k) << 1) + 1] = (amp * mod_dmrs[l][(dmrs_idx << 1) + 1]) >> 15; #ifdef DEBUG_PDCCH_DMRS - printf("PDCCH DMRS: l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1], - ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]); + printf("PDCCH DMRS: l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1], + ((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]); #endif dmrs_idx++; k_prime++; } else { // DCI payload - ((int16_t *) txdataF)[(l * frame_parms.ofdm_symbol_size + k) << 1] = (amp * mod_dci[dci_idx << 1]) >> 15; - ((int16_t *) txdataF)[((l * frame_parms.ofdm_symbol_size + k) << 1) + 1] = + ((int16_t *) txdataF)[(l * frame_parms->ofdm_symbol_size + k) << 1] = (amp * mod_dci[dci_idx << 1]) >> 15; + ((int16_t *) txdataF)[((l * frame_parms->ofdm_symbol_size + k) << 1) + 1] = (amp * mod_dci[(dci_idx << 1) + 1]) >> 15; #ifdef DEBUG_DCI - printf("PDCCH: l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1], - ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]); + printf("PDCCH: l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms->ofdm_symbol_size + k)<<1], + ((int16_t *)txdataF)[((l*frame_parms->ofdm_symbol_size + k)<<1)+1]); #endif dci_idx++; @@ -233,8 +232,8 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, k++; - if (k >= frame_parms.ofdm_symbol_size) - k -= frame_parms.ofdm_symbol_size; + if (k >= frame_parms->ofdm_symbol_size) + k -= frame_parms->ofdm_symbol_size; } // m } // reg_in_cce_idx @@ -254,17 +253,15 @@ void nr_generate_dci_top(PHY_VARS_gNB *gNB, uint32_t **gold_pdcch_dmrs, int32_t *txdataF, int16_t amp, - NR_DL_FRAME_PARMS frame_parms) { + NR_DL_FRAME_PARMS *frame_parms) { AssertFatal(pdcch_pdu!=NULL || ul_dci_pdu!=NULL,"At least one pointer has to be !NULL\n"); - if (pdcch_pdu && ul_dci_pdu) { + if (pdcch_pdu) { nr_generate_dci(gNB,&pdcch_pdu->pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms); - nr_generate_dci(gNB,&ul_dci_pdu->pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms); } - else if (pdcch_pdu) - nr_generate_dci(gNB,&pdcch_pdu->pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms); - else + if (ul_dci_pdu) { nr_generate_dci(gNB,&ul_dci_pdu->pdcch_pdu_rel15,gold_pdcch_dmrs,txdataF,amp,frame_parms); + } } diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.h b/openair1/PHY/NR_TRANSPORT/nr_dci.h index 1b57acc6f40ff7edb2352486a827b9d446d6e55f..e3b53f9cf9658656cb5bb5132b1f3a65b2ad98bc 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.h +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.h @@ -35,7 +35,7 @@ void nr_generate_dci_top(PHY_VARS_gNB *gNB, uint32_t **gold_pdcch_dmrs, int32_t *txdataF, int16_t amp, - NR_DL_FRAME_PARMS frame_parms); + NR_DL_FRAME_PARMS *frame_parms); void nr_pdcch_scrambling(uint32_t *in, uint32_t size, diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index b1dbc7c7d94fe8a879150098c67fac07acdb8205..03bd0ddf6cffc715982fe69d38e95d597442b437 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -448,7 +448,7 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB, (void*)&txdataF_precoding[ap][2*(l*frame_parms->ofdm_symbol_size + txdataF_offset+ k)], NR_NB_SC_PER_RB*sizeof(int32_t)); else - memset((void*)&txdataF[ap][rel15->StartSymbolIndex*frame_parms->ofdm_symbol_size + txdataF_offset +k], + memset((void*)&txdataF[ap][l*frame_parms->ofdm_symbol_size + txdataF_offset + k], 0, NR_NB_SC_PER_RB*sizeof(int32_t)); k += NR_NB_SC_PER_RB; diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index 1e372eb9e0b75704c3750e5eaadbd499440c8330..2ae2549df31743e6d7263e1087c8d0714bf34091 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -192,14 +192,15 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, AssertFatal(harq->d[r], "cannot allocate harq->d[%d]\n", r); // max size for coded output bzero(harq->c[r], 8448); bzero(harq->d[r], (3 * 8448)); - harq->e = malloc16(14 * N_RB * 12 * 8); - AssertFatal(harq->e, "cannot allocate harq->e\n"); - bzero(harq->e, 14 * N_RB * 12 * 8); - harq->f = malloc16(14 * N_RB * 12 * 8); - AssertFatal(harq->f, "cannot allocate harq->f\n"); - bzero(harq->f, 14 * N_RB * 12 * 8); } + harq->e = malloc16(N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS); + AssertFatal(harq->e, "cannot allocate harq->e\n"); + bzero(harq->e, N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS); + harq->f = malloc16(N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS); + AssertFatal(harq->f, "cannot allocate harq->f\n"); + bzero(harq->f, N_RB * NR_SYMBOLS_PER_SLOT * NR_NB_SC_PER_RB * 8 * NR_MAX_NB_LAYERS); + return(dlsch); } @@ -267,6 +268,8 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_DLSCH_ENCODING, VCD_FUNCTION_IN); A = rel15->TBSize[0]<<3; + if ( dlsch->rnti != SI_RNTI ) + trace_NRpdu(DIRECTION_DOWNLINK, a, rel15->TBSize[0], 0, WS_C_RNTI, dlsch->rnti, frame, slot,0, 0); NR_gNB_SCH_STATS_t *stats=NULL; int first_free=-1; diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index 34c647810d7ef73712ee08c53374158ea9d90cae..000348ae8728ef2fd2656f86db9ba317c827c5a6 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -858,38 +858,50 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, memset(prachF, 0, sizeof(int16_t)*2*1024 ); if (LOG_DUMPFLAG(PRACH)) { - LOG_M("prach_rxF0.m","prach_rxF0",rxsigF[0],N_ZC,1,1); - LOG_M("prach_rxF1.m","prach_rxF1",rxsigF[1],6144,1,1); + LOG_M("prach_rxF0.m","prach_rxF0",rxsigF[0],N_ZC,1,1); + LOG_M("prach_rxF1.m","prach_rxF1",rxsigF[1],6144,1,1); } for (aa=0;aa<nb_rx; aa++) { // Do componentwise product with Xu* on each antenna - for (offset=0; offset<(N_ZC<<1); offset+=2) { - prachF[offset] = (int16_t)(((int32_t)Xu[offset]*rxsigF[aa][offset] + (int32_t)Xu[offset+1]*rxsigF[aa][offset+1])>>15); - prachF[offset+1] = (int16_t)(((int32_t)Xu[offset]*rxsigF[aa][offset+1] - (int32_t)Xu[offset+1]*rxsigF[aa][offset])>>15); - } + for (offset=0; offset<(N_ZC<<1); offset+=2) { + prachF[offset] = (int16_t)(((int32_t)Xu[offset]*rxsigF[aa][offset] + (int32_t)Xu[offset+1]*rxsigF[aa][offset+1])>>15); + prachF[offset+1] = (int16_t)(((int32_t)Xu[offset]*rxsigF[aa][offset+1] - (int32_t)Xu[offset+1]*rxsigF[aa][offset])>>15); + } - // Now do IFFT of size 1024 (N_ZC=839) or 256 (N_ZC=139) - if (N_ZC == 839) { - log2_ifft_size = 10; - idft(IDFT_1024,prachF,prach_ifft_tmp,1); - // compute energy and accumulate over receive antennas - for (i=0;i<2048;i++) - prach_ifft[i] += ((int32_t)prach_ifft_tmp[i<<1]*(int32_t)prach_ifft_tmp[i<<1] + (int32_t)prach_ifft_tmp[1+(i<<1)]*(int32_t)prach_ifft_tmp[1+(i<<1)])>>10; - } else { - idft(IDFT_256,prachF,prach_ifft_tmp,1); - log2_ifft_size = 8; - // compute energy and accumulate over receive antennas and repetitions for BR - for (i=0;i<256;i++) - prach_ifft[i] += ((int32_t)prach_ifft_tmp[i<<1]*(int32_t)prach_ifft_tmp[(i<<1)] + (int32_t)prach_ifft_tmp[1+(i<<1)]*(int32_t)prach_ifft_tmp[1+(i<<1)])>>10; - } - - if (LOG_DUMPFLAG(PRACH)) { - if (aa==0) LOG_M("prach_rxF_comp0.m","prach_rxF_comp0",prachF,1024,1,1); + // Now do IFFT of size 1024 (N_ZC=839) or 256 (N_ZC=139) + if (N_ZC == 839) { + idft(IDFT_1024,prachF,prach_ifft_tmp,1); + // compute energy and accumulate over receive antennas + for (i=0;i<1024;i++) + prach_ifft[i] += (int32_t)prach_ifft_tmp[i<<1]*(int32_t)prach_ifft_tmp[i<<1] + (int32_t)prach_ifft_tmp[1+(i<<1)]*(int32_t)prach_ifft_tmp[1+(i<<1)]; + } else { + idft(IDFT_256,prachF,prach_ifft_tmp,1); + log2_ifft_size = 8; + // compute energy and accumulate over receive antennas and repetitions for BR + for (i=0;i<256;i++) + prach_ifft[i] += (int32_t)prach_ifft_tmp[i<<1]*(int32_t)prach_ifft_tmp[(i<<1)] + (int32_t)prach_ifft_tmp[1+(i<<1)]*(int32_t)prach_ifft_tmp[1+(i<<1)]; + } + + if (LOG_DUMPFLAG(PRACH)) { + if (aa==0) LOG_M("prach_rxF_comp0.m","prach_rxF_comp0",prachF,1024,1,1); if (aa==1) LOG_M("prach_rxF_comp1.m","prach_rxF_comp1",prachF,1024,1,1); - } + } + }// antennas_rx + + // Normalization of energy over ifft and receive antennas + if (N_ZC == 839) { + log2_ifft_size = 10; + for (i=0;i<1024;i++) + prach_ifft[i] = (prach_ifft[i]>>log2_ifft_size)/nb_rx; + } else { + log2_ifft_size = 8; + for (i=0;i<256;i++) + prach_ifft[i] = (prach_ifft[i]>>log2_ifft_size)/nb_rx; + } + } // new dft // check energy in nth time shift, for @@ -900,10 +912,10 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, lev = (int32_t)prach_ifft[(preamble_shift2+i)]; levdB = dB_fixed_times10(lev); if (levdB>*max_preamble_energy) { - LOG_D(PHY,"preamble_index %d, delay %d en %d dB > %d dB\n",preamble_index,i,levdB,*max_preamble_energy); - *max_preamble_energy = levdB; - *max_preamble_delay = i; // Note: This has to be normalized to the 30.72 Ms/s sampling rate - *max_preamble = preamble_index; + LOG_D(PHY,"preamble_index %d, delay %d en %d dB > %d dB\n",preamble_index,i,levdB,*max_preamble_energy); + *max_preamble_energy = levdB; + *max_preamble_delay = i; // Note: This has to be normalized to the 30.72 Ms/s sampling rate + *max_preamble = preamble_index; } } }// preamble_index diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h index 2ca8e24af1315c05230c7c2df20cb90c0b9b3474..80c10d74b15a4c7bc82862efe7142d049975320f 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h @@ -91,6 +91,7 @@ int16_t find_nr_ulsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type); void dump_pusch_stats(FILE *fd,PHY_VARS_gNB *gNB); +void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB); void clear_pusch_stats(PHY_VARS_gNB *gNB); NR_gNB_SCH_STATS_t *get_ulsch_stats(PHY_VARS_gNB *gNB,NR_gNB_ULSCH_t *ulsch); diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index 909d0b8954036a72584605e3a996733972b40e4d..8c4394e6e9e933b1a7e17d0290671965fd64897d 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -36,7 +36,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - uint8_t eNB_offset, + uint8_t gNB_id, unsigned char Ns, unsigned char symbol, int dmrss, @@ -70,7 +70,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, k = nushift; #ifdef DEBUG_CH - printf("PBCH DMRS Correlation : ThreadId %d, eNB_offset %d , OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, eNB_offset,ue->frame_parms.ofdm_symbol_size, + printf("PBCH DMRS Correlation : ThreadId %d, gNB_id %d , OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, gNB_id,ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp,Ns,k, symbol); #endif @@ -198,7 +198,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - uint8_t eNB_offset, + uint8_t gNB_id, unsigned char Ns, unsigned char symbol, int dmrss, @@ -213,10 +213,8 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, int ch_offset,symbol_offset; //int slot_pbch; - //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1]; - uint8_t nushift; - int **dl_ch_estimates =ue->pbch_vars[eNB_offset]->dl_ch_estimates; + int **dl_ch_estimates =ue->pbch_vars[gNB_id]->dl_ch_estimates; int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF; nushift = ue->frame_parms.Nid_cell%4; @@ -239,7 +237,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, k = nushift; #ifdef DEBUG_CH - printf("PBCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size, + printf("PBCH Channel Estimation : ThreadId %d, gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, gNB_id,ch_offset,ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp,Ns,k, symbol); #endif @@ -456,12 +454,12 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, // do ifft of channel estimate for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) for (p=0; p<ue->frame_parms.nb_antenna_ports_gNB; p++) { - if (ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p*ue->frame_parms.nb_antennas_rx)+aarx]) + if (ue->pbch_vars[gNB_id]->dl_ch_estimates[(p*ue->frame_parms.nb_antennas_rx)+aarx]) { LOG_D(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d ch_offset %d\n", Ns, proc->thread_id, symbol, ch_offset); idft(idftsizeidx, - (int16_t*) &ue->pbch_vars[eNB_offset]->dl_ch_estimates[(p*ue->frame_parms.nb_antennas_rx)+aarx][ch_offset], - (int16_t*) ue->pbch_vars[eNB_offset]->dl_ch_estimates_time[(p*ue->frame_parms.nb_antennas_rx)+aarx],1); + (int16_t*) &ue->pbch_vars[gNB_id]->dl_ch_estimates[(p*ue->frame_parms.nb_antennas_rx)+aarx][ch_offset], + (int16_t*) ue->pbch_vars[gNB_id]->dl_ch_estimates_time[(p*ue->frame_parms.nb_antennas_rx)+aarx],1); } } } @@ -474,7 +472,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - uint8_t eNB_offset, + uint8_t gNB_id, unsigned char Ns, unsigned char symbol, unsigned short coreset_start_subcarrier, @@ -487,9 +485,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr; int ch_offset,symbol_offset; - //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1]; - - int **dl_ch_estimates =ue->pdcch_vars[proc->thread_id][eNB_offset]->dl_ch_estimates; + int **dl_ch_estimates =ue->pdcch_vars[proc->thread_id][gNB_id]->dl_ch_estimates; int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF; @@ -500,10 +496,9 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol; - k = coreset_start_subcarrier; #ifdef DEBUG_PDCCH - printf("PDCCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, eNB_offset,ch_offset,ue->frame_parms.ofdm_symbol_size, + printf("PDCCH Channel Estimation : ThreadId %d, gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, gNB_id,ch_offset,ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp,Ns,k, symbol); #endif @@ -521,11 +516,12 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, // generate pilot int pilot[nb_rb_coreset * 3] __attribute__((aligned(16))); - nr_pdcch_dmrs_rx(ue,eNB_offset,Ns,ue->nr_gold_pdcch[eNB_offset][Ns][symbol], &pilot[0],2000,nb_rb_coreset); + nr_pdcch_dmrs_rx(ue,gNB_id,Ns,ue->nr_gold_pdcch[gNB_id][Ns][symbol], &pilot[0],2000,nb_rb_coreset); for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) { + k = coreset_start_subcarrier; pil = (int16_t *)&pilot[0]; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+k+1)]; dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset]; @@ -656,7 +652,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - uint8_t eNB_offset, + uint8_t gNB_id, bool is_SI, unsigned char Ns, unsigned short p, @@ -673,10 +669,12 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, int16_t *fl,*fm,*fr,*fml,*fmr,*fmm,*fdcl,*fdcr,*fdclh,*fdcrh, *frl, *frr; int ch_offset,symbol_offset; - //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1]; + NR_UE_DLSCH_t **dlsch = ue->dlsch[proc->thread_id][gNB_id]; + const unsigned char harq_pid = dlsch[0]->current_harq_pid; + NR_DL_UE_HARQ_t *dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; uint8_t nushift; - int **dl_ch_estimates =ue->pdsch_vars[proc->thread_id][eNB_offset]->dl_ch_estimates; + int **dl_ch_estimates =ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_estimates; int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF; if (ue->high_speed_flag == 0) @@ -690,7 +688,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, int re_offset = k; #ifdef DEBUG_CH - printf("PDSCH Channel Estimation : ThreadId %d, eNB_offset %d ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, eNB_offset,ch_offset,symbol_offset,ue->frame_parms.ofdm_symbol_size, + printf("PDSCH Channel Estimation : ThreadId %d, gNB_id %d ch_offset %d, symbol_offset %d OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n",proc->thread_id, gNB_id,ch_offset,symbol_offset,ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp,Ns,k, symbol); #endif @@ -699,19 +697,19 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, if (is_SI) { rb_offset -= BWPStart; } - uint8_t config_type = ue->dmrs_DownlinkConfig.pdsch_dmrs_type; + uint8_t config_type = dlsch0_harq->dmrsConfigType; int8_t delta = get_delta(p, config_type); // checking if re-initialization of scrambling IDs is needed - if ((ue->dmrs_DownlinkConfig.scramblingID0 != ue->scramblingID[0]) || (ue->dmrs_DownlinkConfig.scramblingID1 != ue->scramblingID[1])){ - ue->scramblingID[0]=ue->dmrs_DownlinkConfig.scramblingID0; - ue->scramblingID[1]=ue->dmrs_DownlinkConfig.scramblingID1; + /*if ((XXX.scramblingID0 != ue->scramblingID[0]) || (XXX.scramblingID1 != ue->scramblingID[1])){ + ue->scramblingID[0] = XXX.scramblingID0; + ue->scramblingID[1] = XXX.scramblingID1; nr_gold_pdsch(ue,ue->scramblingID); - } + }*/ - nr_pdsch_dmrs_rx(ue,Ns,ue->nr_gold_pdsch[eNB_offset][Ns][symbol][0], &pilot[0],1000+p,0,nb_rb_pdsch+rb_offset); + nr_pdsch_dmrs_rx(ue, Ns, ue->nr_gold_pdsch[gNB_id][Ns][symbol][0], &pilot[0], 1000+p, 0, nb_rb_pdsch+rb_offset, config_type); - if (config_type == pdsch_dmrs_type1){ + if (config_type == NFAPI_NR_DMRS_TYPE1){ nushift = (p>>1)&1; if (p<4) ue->frame_parms.nushift = nushift; switch (delta) { @@ -751,7 +749,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, return -1; break; } - } else {//pdsch_dmrs_type2 + } else {//NFAPI_NR_DMRS_TYPE2 nushift = delta; if (p<6) ue->frame_parms.nushift = nushift; switch (delta) { @@ -793,7 +791,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, } for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) { - pil = (int16_t *)&pilot[rb_offset*((config_type==pdsch_dmrs_type1) ? 6:4)]; + pil = (int16_t *)&pilot[rb_offset*((config_type==NFAPI_NR_DMRS_TYPE1) ? 6:4)]; k = k % ue->frame_parms.ofdm_symbol_size; re_offset = k; rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+re_offset+nushift)]; @@ -811,7 +809,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, printf("dl_ch addr %p nushift %d\n",dl_ch,nushift); #endif - if (config_type == pdsch_dmrs_type1) { + if (config_type == NFAPI_NR_DMRS_TYPE1) { // Treat first 2 pilots specially (left edge) ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); @@ -944,11 +942,11 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, // check if PRB crosses DC and improve estimates around DC if ((bwp_start_subcarrier < ue->frame_parms.ofdm_symbol_size) && (bwp_start_subcarrier+nb_rb_pdsch*12 >= ue->frame_parms.ofdm_symbol_size)) { - dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset]; + dl_ch = (int16_t *)&dl_ch_estimates[p*ue->frame_parms.nb_antennas_rx+aarx][ch_offset]; uint16_t idxDC = 2*(ue->frame_parms.ofdm_symbol_size - bwp_start_subcarrier); uint16_t idxPil = idxDC/2; re_offset = k; - pil = (int16_t *)&pilot[rb_offset*((config_type==pdsch_dmrs_type1) ? 6:4)]; + pil = (int16_t *)&pilot[rb_offset*((config_type==NFAPI_NR_DMRS_TYPE1) ? 6:4)]; pil += (idxPil-2); dl_ch += (idxDC-4); dl_ch = memset(dl_ch, 0, sizeof(int16_t)*10); @@ -994,7 +992,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, 8); } } - } else { //pdsch_dmrs_type2 |dmrs_r,dmrs_l,0,0,0,0,dmrs_r,dmrs_l,0,0,0,0| + } else { //NFAPI_NR_DMRS_TYPE2 |dmrs_r,dmrs_l,0,0,0,0,dmrs_r,dmrs_l,0,0,0,0| // Treat first 4 pilots specially (left edge) ch_l[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); @@ -1224,16 +1222,15 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, * * NAME : nr_pdsch_ptrs_processing * - * PARAMETERS : ue : ue data structure + * PARAMETERS : PHY_VARS_NR_UE : ue data structure * NR_UE_PDSCH : pdsch_vars pointer * NR_DL_FRAME_PARMS : frame_parms pointer * NR_DL_UE_HARQ_t : dlsch0_harq pointer * NR_DL_UE_HARQ_t : dlsch1_harq pointer - * uint8_t : eNB_id, + * uint8_t : gNB_id, * uint8_t : nr_slot_rx, * unsigned char : symbol, * uint32_t : nb_re_pdsch, - * unsigned char : harq_pid * uint16_t : rnti * RX_type_t : rx_type * RETURN : Nothing @@ -1249,11 +1246,10 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, NR_DL_FRAME_PARMS *frame_parms, NR_DL_UE_HARQ_t *dlsch0_harq, NR_DL_UE_HARQ_t *dlsch1_harq, - uint8_t eNB_id, + uint8_t gNB_id, uint8_t nr_slot_rx, unsigned char symbol, uint32_t nb_re_pdsch, - unsigned char harq_pid, uint16_t rnti, RX_type_t rx_type) { @@ -1284,7 +1280,7 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, ptrsSymbPos = &dlsch0_harq->ptrs_symbols; ptrsSymbIdx = &dlsch0_harq->ptrs_symbol_index; ptrsReOffset = &dlsch0_harq->PTRSReOffset; - dmrsConfigType = &dlsch0_harq->ptrs_symbol_index; + dmrsConfigType = &dlsch0_harq->dmrsConfigType; nb_rb = &dlsch0_harq->nb_rb; } if(dlsch1_harq) { @@ -1297,13 +1293,13 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, ptrsSymbPos = &dlsch1_harq->ptrs_symbols; ptrsSymbIdx = &dlsch1_harq->ptrs_symbol_index; ptrsReOffset = &dlsch1_harq->PTRSReOffset; - dmrsConfigType = &dlsch1_harq->ptrs_symbol_index; + dmrsConfigType = &dlsch1_harq->dmrsConfigType; nb_rb = &dlsch1_harq->nb_rb; } /* loop over antennas */ for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - phase_per_symbol = (int16_t*)pdsch_vars[eNB_id]->ptrs_phase_per_slot[aarx]; - ptrs_re_symbol = (int32_t*)pdsch_vars[eNB_id]->ptrs_re_per_slot[aarx]; + phase_per_symbol = (int16_t*)pdsch_vars[gNB_id]->ptrs_phase_per_slot[aarx]; + ptrs_re_symbol = (int32_t*)pdsch_vars[gNB_id]->ptrs_re_per_slot[aarx]; ptrs_re_symbol[symbol] = 0; phase_per_symbol[(2*symbol)+1] = 0; // Imag /* set DMRS estimates to 0 angle with magnitude 1 */ @@ -1337,11 +1333,11 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, /*------------------------------------------------------------------------------------------------------- */ nr_ptrs_cpe_estimation(*K_ptrs,*ptrsReOffset,*dmrsConfigType,*nb_rb, rnti, - (int16_t *)&pdsch_vars[eNB_id]->dl_ch_ptrs_estimates_ext[aarx][symbol*nb_re_pdsch], + (int16_t *)&pdsch_vars[gNB_id]->dl_ch_ptrs_estimates_ext[aarx][symbol*nb_re_pdsch], nr_slot_rx, symbol,frame_parms->ofdm_symbol_size, - (int16_t*)&pdsch_vars[eNB_id]->rxdataF_comp0[aarx][(symbol * nb_re_pdsch)], - ue->nr_gold_pdsch[eNB_id][nr_slot_rx][symbol][0], + (int16_t*)&pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(symbol * nb_re_pdsch)], + ue->nr_gold_pdsch[gNB_id][nr_slot_rx][symbol][0], &phase_per_symbol[2* symbol], &ptrs_re_symbol[symbol]); } @@ -1360,9 +1356,9 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, } } #ifdef DEBUG_DL_PTRS - LOG_M("ptrsEst.m","est",pdsch_vars[eNB_id]->ptrs_phase_per_slot[aarx],frame_parms->symbols_per_slot,1,1 ); + LOG_M("ptrsEst.m","est",pdsch_vars[gNB_id]->ptrs_phase_per_slot[aarx],frame_parms->symbols_per_slot,1,1 ); LOG_M("rxdataF_bf_ptrs_comp.m","bf_ptrs_cmp", - &pdsch_vars[eNB_id]->rxdataF_comp0[aarx][(*startSymbIndex) * NR_NB_SC_PER_RB * (*nb_rb) ], + &pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(*startSymbIndex) * NR_NB_SC_PER_RB * (*nb_rb) ], (*nb_rb) * NR_NB_SC_PER_RB * (*nbSymb),1,1); #endif /*------------------------------------------------------------------------------------------------------- */ @@ -1375,9 +1371,9 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, #ifdef DEBUG_DL_PTRS printf("[PHY][DL][PTRS]: Rotate Symbol %2d with %d + j* %d\n", i, phase_per_symbol[2* i],phase_per_symbol[(2* i) +1]); #endif - rotate_cpx_vector((int16_t*)&pdsch_vars[eNB_id]->rxdataF_comp0[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)], + rotate_cpx_vector((int16_t*)&pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)], &phase_per_symbol[2* i], - (int16_t*)&pdsch_vars[eNB_id]->rxdataF_comp0[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)], + (int16_t*)&pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)], ((*nb_rb) * NR_NB_SC_PER_RB), 15); }// if not DMRS Symbol }// symbol loop diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h index 1466fabe5d5f1a549922e5729d250d2d22075267..c5330ce2f2e7e2a98f3d77591046f4ea8bb6cc84 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h @@ -34,17 +34,14 @@ /*! \brief This function performs channel estimation including frequency and temporal interpolation -\param phy_vars_ue Pointer to UE PHY variables -\param eNB_id Index of target eNB -\param eNB_offset Offset for interfering eNB (in terms cell ID mod 3) +\param ue Pointer to UE PHY variables +\param gNB_id Index of target gNB \param Ns slot number (0..19) -\param p antenna port -\param l symbol within slot -\param symbol symbol within frame +\param symbol symbol within slot */ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - uint8_t eNB_offset, + uint8_t gNB_id, unsigned char Ns, unsigned char symbol, unsigned short coreset_start_subcarrier, @@ -52,7 +49,7 @@ int nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - uint8_t eNB_offset, + uint8_t gNB_id, unsigned char Ns, unsigned char symbol, int dmrss, @@ -60,7 +57,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - uint8_t eNB_offset, + uint8_t gNB_id, unsigned char Ns, unsigned char symbol, int dmrss, @@ -69,7 +66,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - uint8_t eNB_offset, + uint8_t gNB_id, bool is_SI, unsigned char Ns, unsigned short p, @@ -80,7 +77,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, PHY_VARS_NR_UE *ue, - module_id_t eNB_id, + module_id_t gNB_id, uint8_t frame, uint8_t subframe, unsigned char clear, @@ -102,7 +99,7 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue, void phy_adjust_gain_nr(PHY_VARS_NR_UE *ue, uint32_t rx_power_fil_dB, - uint8_t eNB_id); + uint8_t gNB_id); int16_t get_nr_PL(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index); @@ -111,11 +108,10 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, NR_DL_FRAME_PARMS *frame_parms, NR_DL_UE_HARQ_t *dlsch0_harq, NR_DL_UE_HARQ_t *dlsch1_harq, - uint8_t eNB_id, + uint8_t gNB_id, uint8_t nr_slot_rx, unsigned char symbol, uint32_t nb_re_pdsch, - unsigned char harq_pid, uint16_t rnti, RX_type_t rx_type); diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index 5d4d9df47e26782831a77b9e741d5684497396cc..cffdf5092d90e796dce3efb9164796d6e965ea33 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -761,7 +761,7 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) avgs = cmax(avgs, avgP[aarx]); - log2_maxh = (log2_approx(avgs) / 2) + 5; //+frame_parms->nb_antennas_rx; + log2_maxh = (log2_approx(avgs) / 2) + 1; //+frame_parms->nb_antennas_rx; #ifdef UE_DEBUG_TRACE LOG_D(PHY,"slot %d: pdcch log2_maxh = %d (%d,%d)\n",slot,log2_maxh,avgP[0],avgs); #endif diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 2046c13eaa626f1caa7c2bf8d801023d00a1a625..2174f569da290c93a1d0887d6782758ea36003ac 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -84,8 +84,8 @@ unsigned char offset_mumimo_llr_drange[29][3]={{8,8,8},{7,7,7},{7,7,7},{7,7,7},{ */ //unsigned char offset_mumimo_llr_drange[29][3]= {{0, 6, 5},{0, 4, 5},{0, 4, 5},{0, 5, 4},{0, 5, 6},{0, 5, 3},{0, 4, 4},{0, 4, 4},{0, 3, 3},{0, 1, 2},{1, 1, 0},{1, 3, 2},{3, 4, 1},{2, 0, 0},{2, 2, 2},{1, 1, 1},{2, 1, 0},{2, 1, 1},{1, 0, 1},{1, 0, 1},{0, 0, 0},{1, 0, 0},{0, 0, 0},{0, 1, 0},{1, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0},{0, 0, 0}}; -#define print_ints(s,x) printf("%s %d %d %d %d\n",s,(x)[0],(x)[1],(x)[2],(x)[3]) -#define print_shorts(s,x) printf("%s %d,%d,%d,%d,%d,%d,%d,%d\n",s,(x)[0],(x)[1],(x)[2],(x)[3],(x)[4],(x)[5],(x)[6],(x)[7]) +#define print_ints(s,x) printf("%s = %d %d %d %d\n",s,(x)[0],(x)[1],(x)[2],(x)[3]) +#define print_shorts(s,x) printf("%s = [%d+j*%d, %d+j*%d, %d+j*%d, %d+j*%d]\n",s,(x)[0],(x)[1],(x)[2],(x)[3],(x)[4],(x)[5],(x)[6],(x)[7]) static void nr_dlsch_dual_stream_correlation_core(int **dl_ch_estimates_ext, int **dl_ch_estimates_ext_i, @@ -99,17 +99,21 @@ static void nr_dlsch_dual_stream_correlation_core(int **dl_ch_estimates_ext, uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp, int **dl_ch_mag, int **dl_ch_magb, + int **dl_ch_magr, int **dl_ch_estimates_ext, unsigned short nb_rb, unsigned char n_rx, unsigned char mod_order, int shift, - unsigned char symbol); + unsigned char symbol, + int length); static void nr_dlsch_layer_demapping(int16_t **llr_cw, uint8_t Nl, uint8_t mod_order, - uint16_t length, + uint32_t length, + int32_t codeword_TB0, + int32_t codeword_TB1, int16_t **llr_layers); @@ -182,8 +186,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, //int16_t *pllr_symbol_cw0_deint; //int16_t *pllr_symbol_cw1_deint; //uint16_t bundle_L = 2; - uint8_t pilots=0; - uint8_t config_type;// We should not use ue->dmrs_DownlinkConfig.pdsch_dmrs_type; uint16_t n_tx=1, n_rx=1; int32_t median[16]; uint32_t len; @@ -340,8 +342,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, printf("Demod dlsch0_harq->pmi_alloc %d\n", dlsch0_harq->pmi_alloc); #endif - pilots = ((1<<symbol)&dlsch0_harq->dlDmrsSymbPos)>0 ? 1 : 0; - config_type = dlsch0_harq->dmrsConfigType; + uint8_t pilots = (dlsch0_harq->dlDmrsSymbPos >> symbol) & 1; + uint8_t config_type = dlsch0_harq->dmrsConfigType; if (beamforming_mode==0) {//No beamforming #if UE_TIMING_TRACE @@ -385,7 +387,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, return(-1); } - len = (pilots==1)? ((config_type==pdsch_dmrs_type1)?nb_rb*(12-6*dlsch0_harq->n_dmrs_cdm_groups): nb_rb*(12-4*dlsch0_harq->n_dmrs_cdm_groups)):(nb_rb*12); + len = (pilots==1)? ((config_type==NFAPI_NR_DMRS_TYPE1)?nb_rb*(12-6*dlsch0_harq->n_dmrs_cdm_groups): nb_rb*(12-4*dlsch0_harq->n_dmrs_cdm_groups)):(nb_rb*12); #if UE_TIMING_TRACE stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]); @@ -412,7 +414,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, symbol, pilots, len, - nb_rb); + nb_rb_pdsch); #if UE_TIMING_TRACE stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]); @@ -434,7 +436,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, avg, symbol, len, - nb_rb); + nb_rb_pdsch); avgs = 0; for (aatx=0;aatx<n_tx;aatx++) for (aarx=0;aarx<n_rx;aarx++) { @@ -443,7 +445,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, //LOG_I(PHY, "avgs Power per SC is %d\n", avgs); median[(aatx*frame_parms->nb_antennas_rx)+aarx] = avg[(aatx*frame_parms->nb_antennas_rx)+aarx]; } - pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2)+3; + pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1; //LOG_I(PHY, "avgs Power per SC is %d lg2_maxh %d\n", avgs, pdsch_vars[gNB_id]->log2_maxh); if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) { @@ -505,10 +507,10 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, frame_parms, n_tx, symbol, - pilots, + len, first_symbol_flag, dlsch0_harq->Qm, - nb_rb, + nb_rb_pdsch, pdsch_vars[gNB_id]->log2_maxh, measurements); // log2_maxh+I0_shift } @@ -556,20 +558,24 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, (n_tx>1)? pdsch_vars[gNB_id]->rho : NULL, pdsch_vars[gNB_id]->dl_ch_mag0, pdsch_vars[gNB_id]->dl_ch_magb0, + pdsch_vars[gNB_id]->dl_ch_magr0, n_tx, n_rx, symbol, - nb_rb); + nb_rb_pdsch, + len); if (n_tx == 2)//Apply zero forcing for 2 Tx layers nr_zero_forcing_rx_2layers(pdsch_vars[gNB_id]->rxdataF_comp0, pdsch_vars[gNB_id]->dl_ch_mag0, pdsch_vars[gNB_id]->dl_ch_magb0, + pdsch_vars[gNB_id]->dl_ch_magr0, pdsch_vars[gNB_id]->dl_ch_estimates_ext, - nb_rb, + nb_rb_pdsch, n_rx, dlsch0_harq->Qm, pdsch_vars[gNB_id]->log2_maxh, - symbol); + symbol, + len); } else if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) { nr_dlsch_detection_mrc_core(pdsch_vars[gNB_id]->rxdataF_comp0, @@ -635,14 +641,13 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, nr_slot_rx, symbol, (nb_rb*12), - harq_pid, dlsch[0]->rnti,rx_type); pdsch_vars[gNB_id]->dl_valid_re[symbol-1] -= pdsch_vars[gNB_id]->ptrs_re_per_slot[0][symbol]; } /* at last symbol in a slot calculate LLR's for whole slot */ if(symbol == (startSymbIdx + nbSymb -1)) { - for(uint8_t i =startSymbIdx; i <= nbSymb;i++) { + for(uint8_t i =startSymbIdx; i < (startSymbIdx+nbSymb);i++) { /* re evaluating the first symbol flag as LLR's are done in symbol loop */ if(i == startSymbIdx && i < 3) { first_symbol_flag =1; @@ -662,16 +667,29 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pdsch_vars[gNB_id]->dl_valid_re[i-1], nr_slot_rx, beamforming_mode); } - } - - //nr_dlsch_deinterleaving(symbol,bundle_L,(int16_t*)pllr_symbol_cw0,(int16_t*)pllr_symbol_cw0_deint, nb_rb_pdsch); - if (rx_type==rx_IC_dual_stream) { + int dmrs_type = dlsch[0]->harq_processes[harq_pid]->dmrsConfigType; + uint8_t nb_re_dmrs; + uint16_t dmrs_len = get_num_dmrs(dlsch[0]->harq_processes[harq_pid]->dlDmrsSymbPos); + if (dmrs_type==NFAPI_NR_DMRS_TYPE1) { + nb_re_dmrs = 6*dlsch[0]->harq_processes[harq_pid]->n_dmrs_cdm_groups; + } else { + nb_re_dmrs = 4*dlsch[0]->harq_processes[harq_pid]->n_dmrs_cdm_groups; + } + dlsch[0]->harq_processes[harq_pid]->G = nr_get_G(dlsch[0]->harq_processes[harq_pid]->nb_rb, + dlsch[0]->harq_processes[harq_pid]->nb_symbols, + nb_re_dmrs, + dmrs_len, + dlsch[0]->harq_processes[harq_pid]->Qm, + dlsch[0]->harq_processes[harq_pid]->Nl); nr_dlsch_layer_demapping(pdsch_vars[gNB_id]->llr, dlsch[0]->harq_processes[harq_pid]->Nl, dlsch[0]->harq_processes[harq_pid]->Qm, dlsch[0]->harq_processes[harq_pid]->G, + codeword_TB0, + codeword_TB1, pdsch_vars[gNB_id]->layer_llr); + } #if UE_TIMING_TRACE @@ -780,7 +798,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, NR_DL_FRAME_PARMS *frame_parms, uint8_t nb_aatx, unsigned char symbol, - uint8_t pilots, + int length, uint8_t first_symbol_flag, unsigned char mod_order, unsigned short nb_rb, @@ -794,8 +812,8 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, unsigned char aatx,aarx,atx; __m128i *dl_ch128,*dl_ch128_2,*dl_ch_mag128,*dl_ch_mag128b,*dl_ch_mag128r,*rxdataF128,*rxdataF_comp128,*rho128; __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b,QAM_amp128r; - QAM_amp128b = _mm_setzero_si128(); + uint32_t nb_rb_0 = length/12 + ((length%12)?1:0); for (aatx=0; aatx<nb_aatx; aatx++) { if (mod_order == 4) { QAM_amp128 = _mm_set1_epi16(QAM16_n1); // 2/sqrt(10) @@ -822,7 +840,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, rxdataF128 = (__m128i *)&rxdataF_ext[aarx][symbol*nb_rb*12]; rxdataF_comp128 = (__m128i *)&rxdataF_comp[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12]; - for (rb=0; rb<nb_rb; rb++) { + for (rb=0; rb<nb_rb_0; rb++) { if (mod_order>2) { // get channel amplitude if not QPSK @@ -832,7 +850,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, mmtmpD1 = _mm_madd_epi16(dl_ch128[1],dl_ch128[1]); mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); - mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); + mmtmpD0 = _mm_packs_epi32(mmtmpD0,mmtmpD1); //|H[0]|^2 |H[1]|^2 |H[2]|^2 |H[3]|^2 |H[4]|^2 |H[5]|^2 |H[6]|^2 |H[7]|^2 // store channel magnitude here in a new field of dlsch @@ -841,6 +859,13 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, dl_ch_mag128r[0] = dl_ch_mag128[0]; dl_ch_mag128[0] = _mm_mulhi_epi16(dl_ch_mag128[0],QAM_amp128); dl_ch_mag128[0] = _mm_slli_epi16(dl_ch_mag128[0],1); + + dl_ch_mag128b[0] = _mm_mulhi_epi16(dl_ch_mag128b[0],QAM_amp128b); + dl_ch_mag128b[0] = _mm_slli_epi16(dl_ch_mag128b[0],1); + + dl_ch_mag128r[0] = _mm_mulhi_epi16(dl_ch_mag128r[0],QAM_amp128r); + dl_ch_mag128r[0] = _mm_slli_epi16(dl_ch_mag128r[0],1); + //print_ints("Re(ch):",(int16_t*)&mmtmpD0); //print_shorts("QAM_amp:",(int16_t*)&QAM_amp128); //print_shorts("mag:",(int16_t*)&dl_ch_mag128[0]); @@ -850,39 +875,28 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, dl_ch_mag128[1] = _mm_mulhi_epi16(dl_ch_mag128[1],QAM_amp128); dl_ch_mag128[1] = _mm_slli_epi16(dl_ch_mag128[1],1); - if (pilots==0) { - mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128[2]); - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0); - - dl_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1); - dl_ch_mag128b[2] = dl_ch_mag128[2]; - dl_ch_mag128r[2] = dl_ch_mag128[2]; - - dl_ch_mag128[2] = _mm_mulhi_epi16(dl_ch_mag128[2],QAM_amp128); - dl_ch_mag128[2] = _mm_slli_epi16(dl_ch_mag128[2],1); - } - - dl_ch_mag128b[0] = _mm_mulhi_epi16(dl_ch_mag128b[0],QAM_amp128b); - dl_ch_mag128b[0] = _mm_slli_epi16(dl_ch_mag128b[0],1); - - dl_ch_mag128b[1] = _mm_mulhi_epi16(dl_ch_mag128b[1],QAM_amp128b); dl_ch_mag128b[1] = _mm_slli_epi16(dl_ch_mag128b[1],1); - dl_ch_mag128r[0] = _mm_mulhi_epi16(dl_ch_mag128r[0],QAM_amp128r); - dl_ch_mag128r[0] = _mm_slli_epi16(dl_ch_mag128r[0],1); - dl_ch_mag128r[1] = _mm_mulhi_epi16(dl_ch_mag128r[1],QAM_amp128r); dl_ch_mag128r[1] = _mm_slli_epi16(dl_ch_mag128r[1],1); - if (pilots==0) { - dl_ch_mag128b[2] = _mm_mulhi_epi16(dl_ch_mag128b[2],QAM_amp128b); - dl_ch_mag128b[2] = _mm_slli_epi16(dl_ch_mag128b[2],1); + mmtmpD0 = _mm_madd_epi16(dl_ch128[2],dl_ch128[2]);//[H_I(0)^2+H_Q(0)^2 H_I(1)^2+H_Q(1)^2 H_I(2)^2+H_Q(2)^2 H_I(3)^2+H_Q(3)^2] + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD1 = _mm_packs_epi32(mmtmpD0,mmtmpD0);//[|H(0)|^2 |H(1)|^2 |H(2)|^2 |H(3)|^2 |H(0)|^2 |H(1)|^2 |H(2)|^2 |H(3)|^2] - dl_ch_mag128r[2] = _mm_mulhi_epi16(dl_ch_mag128r[2],QAM_amp128r); - dl_ch_mag128r[2] = _mm_slli_epi16(dl_ch_mag128r[2],1); - } + dl_ch_mag128[2] = _mm_unpacklo_epi16(mmtmpD1,mmtmpD1);//[|H(0)|^2 |H(0)|^2 |H(1)|^2 |H(1)|^2 |H(2)|^2 |H(2)|^2 |H(3)|^2 |H(3)|^2] + dl_ch_mag128b[2] = dl_ch_mag128[2]; + dl_ch_mag128r[2] = dl_ch_mag128[2]; + + dl_ch_mag128[2] = _mm_mulhi_epi16(dl_ch_mag128[2],QAM_amp128); + dl_ch_mag128[2] = _mm_slli_epi16(dl_ch_mag128[2],1); + + dl_ch_mag128b[2] = _mm_mulhi_epi16(dl_ch_mag128b[2],QAM_amp128b); + dl_ch_mag128b[2] = _mm_slli_epi16(dl_ch_mag128b[2],1); + + dl_ch_mag128r[2] = _mm_mulhi_epi16(dl_ch_mag128r[2],QAM_amp128r); + dl_ch_mag128r[2] = _mm_slli_epi16(dl_ch_mag128r[2],1); } // multiply by conjugated channel @@ -905,15 +919,17 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, // print_ints("c0",&mmtmpD2); // print_ints("c1",&mmtmpD3); rxdataF_comp128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - //printf("arx%d atx%d rb_index %d symbol%d\n",aarx,aatx,rb,symbol); - // print_shorts("rx:",rxdataF128); - // print_shorts("ch:",dl_ch128); - // print_shorts("pack:",rxdataF_comp128); - - //printf("arx%d atx%d rb_index %d symbol%d\n",aarx,aatx,rb,symbol); - //print_shorts("rx:",(int16_t*)&rxdataF128[0]); - //print_shorts("ch:",(int16_t*)&dl_ch128[0]); - //print_shorts("pack:",(int16_t*)&rxdataF_comp128[0]); + +#ifdef DEBUG_DLSCH_DEMOD + printf("%%arx%d atx%d rb_index %d symbol %d shift %d\n",aarx,aatx,rb,symbol,output_shift); + printf("rx_%d(%d,:)",aarx+1,rb+1); + print_shorts(" ",(int16_t *)&rxdataF128[0]); + printf("ch_%d%d(%d,:)",aarx+1,aatx+1,rb+1); + print_shorts(" ",(int16_t *)&dl_ch128[0]); + printf("rx_comp_%d%d(%d,:)",aarx+1,aatx+1,rb+1); + print_shorts(" ",(int16_t *)&rxdataF_comp128[0]); +#endif + // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch128[1],rxdataF128[1]); // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) @@ -932,40 +948,30 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, //print_shorts("ch:",(int16_t*)&dl_ch128[1]); //print_shorts("pack:",(int16_t*)&rxdataF_comp128[1]); - if (pilots==0) { - // multiply by conjugated channel - mmtmpD0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[2]); - // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) - mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); - mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); - mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]); - // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) - mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); - mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); - mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); - mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); + // multiply by conjugated channel + mmtmpD0 = _mm_madd_epi16(dl_ch128[2],rxdataF128[2]); + // mmtmpD0 contains real part of 4 consecutive outputs (32-bit) + mmtmpD1 = _mm_shufflelo_epi16(dl_ch128[2],_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1)); + mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)conjugate); + mmtmpD1 = _mm_madd_epi16(mmtmpD1,rxdataF128[2]); + // mmtmpD1 contains imag part of 4 consecutive outputs (32-bit) + mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift); + mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift); + mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1); + mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1); - rxdataF_comp128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); - //print_shorts("rx:",(int16_t*)&rxdataF128[2]); - //print_shorts("ch:",(int16_t*)&dl_ch128[2]); - //print_shorts("pack:",(int16_t*)&rxdataF_comp128[2]); - - dl_ch128+=3; - dl_ch_mag128+=3; - dl_ch_mag128b+=3; - dl_ch_mag128r+=3; - rxdataF128+=3; - rxdataF_comp128+=3; - } - else { // we have a smaller PDSCH in symbols with pilots so skip last group of 4 REs and increment less - dl_ch128+=2; - dl_ch_mag128+=2; - dl_ch_mag128b+=2; - dl_ch_mag128r+=2; - rxdataF128+=2; - rxdataF_comp128+=2; - } + rxdataF_comp128[2] = _mm_packs_epi32(mmtmpD2,mmtmpD3); + //print_shorts("rx:",(int16_t*)&rxdataF128[2]); + //print_shorts("ch:",(int16_t*)&dl_ch128[2]); + //print_shorts("pack:",(int16_t*)&rxdataF_comp128[2]); + + dl_ch128+=3; + dl_ch_mag128+=3; + dl_ch_mag128b+=3; + dl_ch_mag128r+=3; + rxdataF128+=3; + rxdataF_comp128+=3; } } } @@ -989,7 +995,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, rho128 = (__m128i *)&rho[aarx][aatx*nb_aatx+atx][symbol*nb_rb*12]; dl_ch128_2 = (__m128i *)&dl_ch_estimates_ext[atx*frame_parms->nb_antennas_rx+aarx][symbol*nb_rb*12]; - for (rb=0; rb<nb_rb; rb++) { + for (rb=0; rb<nb_rb_0; rb++) { // multiply by conjugated channel mmtmpD0 = _mm_madd_epi16(dl_ch128[0],dl_ch128_2[0]); // print_ints("re",&mmtmpD0); @@ -1085,7 +1091,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, //measurements->rx_correlation[0][0][aarx] = signal_energy(&rho[aarx][aatx*nb_aatx+atx][symbol*nb_rb*12],rb*12); avg_rho_re[aarx][aatx*nb_aatx+atx] = 16*avg_rho_re[aarx][aatx*nb_aatx+atx]/(nb_rb*12); avg_rho_im[aarx][aatx*nb_aatx+atx] = 16*avg_rho_im[aarx][aatx*nb_aatx+atx]/(nb_rb*12); - printf("rho[rx]%d tx%d tx%d = Re: %d Im: %d\n",aarx, aatx,atx, avg_rho_re[aarx][aatx*nb_aatx+atx], avg_rho_im[aarx][aatx*nb_aatx+atx]); + //printf("rho[rx]%d tx%d tx%d = Re: %d Im: %d\n",aarx, aatx,atx, avg_rho_re[aarx][aatx*nb_aatx+atx], avg_rho_im[aarx][aatx*nb_aatx+atx]); } } } @@ -1097,7 +1103,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, #elif defined(__arm__) unsigned short rb; - unsigned char aatx,aarx,symbol_mod,pilots=0; + unsigned char aatx,aarx,symbol_mod; int16x4_t *dl_ch128,*dl_ch128_2,*rxdataF128; int32x4_t mmtmpD0,mmtmpD1,mmtmpD0b,mmtmpD1b; @@ -1110,14 +1116,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; - if ((symbol_mod == 0) || (symbol_mod == (4-frame_parms->Ncp))) { - if (frame_parms->nb_antenna_ports_gNB==1) { // 10 out of 12 so don't reduce size - nb_rb=1+(5*nb_rb/6); - } - else { - pilots=1; - } - } + uint32_t nb_rb_0 = length/12 + ((length%12)?1:0); for (aatx=0; aatx<frame_parms->nb_antenna_ports_gNB; aatx++) { if (mod_order == 4) { @@ -1136,7 +1135,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, rxdataF128 = (int16x4_t*)&rxdataF_ext[aarx][symbol*frame_parms->N_RB_DL*12]; rxdataF_comp128 = (int16x4x2_t*)&rxdataF_comp[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12]; - for (rb=0; rb<nb_rb; rb++) { + for (rb=0; rb<nb_rb_0; rb++) { if (mod_order>2) { // get channel amplitude if not QPSK mmtmpD0 = vmull_s16(dl_ch128[0], dl_ch128[0]); @@ -1152,23 +1151,20 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, mmtmpD1 = vmull_s16(dl_ch128[3], dl_ch128[3]); mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); mmtmpD3 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - if (pilots==0) { - mmtmpD0 = vmull_s16(dl_ch128[4], dl_ch128[4]); - mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); - mmtmpD1 = vmull_s16(dl_ch128[5], dl_ch128[5]); - mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); - mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - } + + mmtmpD0 = vmull_s16(dl_ch128[4], dl_ch128[4]); + mmtmpD0 = vqshlq_s32(vqaddq_s32(mmtmpD0,vrev64q_s32(mmtmpD0)),output_shift128); + mmtmpD1 = vmull_s16(dl_ch128[5], dl_ch128[5]); + mmtmpD1 = vqshlq_s32(vqaddq_s32(mmtmpD1,vrev64q_s32(mmtmpD1)),output_shift128); + mmtmpD4 = vcombine_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); dl_ch_mag128b[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128b); dl_ch_mag128b[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128b); dl_ch_mag128[0] = vqdmulhq_s16(mmtmpD2,QAM_amp128); dl_ch_mag128[1] = vqdmulhq_s16(mmtmpD3,QAM_amp128); - if (pilots==0) { - dl_ch_mag128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128b); - dl_ch_mag128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128); - } + dl_ch_mag128b[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128b); + dl_ch_mag128[2] = vqdmulhq_s16(mmtmpD4,QAM_amp128); } mmtmpD0 = vmull_s16(dl_ch128[0], rxdataF128[0]); @@ -1202,36 +1198,29 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); rxdataF_comp128[1] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - if (pilots==0) { - mmtmpD0 = vmull_s16(dl_ch128[4], rxdataF128[4]); - mmtmpD1 = vmull_s16(dl_ch128[5], rxdataF128[5]); - mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), - vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); - mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[4],*(int16x4_t*)conj)), rxdataF128[4]); - mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[5],*(int16x4_t*)conj)), rxdataF128[5]); - mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), - vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); + mmtmpD0 = vmull_s16(dl_ch128[4], rxdataF128[4]); + mmtmpD1 = vmull_s16(dl_ch128[5], rxdataF128[5]); + mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), + vpadd_s32(vget_low_s32(mmtmpD1),vget_high_s32(mmtmpD1))); + + mmtmpD0b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[4],*(int16x4_t*)conj)), rxdataF128[4]); + mmtmpD1b = vmull_s16(vrev32_s16(vmul_s16(dl_ch128[5],*(int16x4_t*)conj)), rxdataF128[5]); + mmtmpD1 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0b),vget_high_s32(mmtmpD0b)), + vpadd_s32(vget_low_s32(mmtmpD1b),vget_high_s32(mmtmpD1b))); - mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); - mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); - rxdataF_comp128[2] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); + mmtmpD0 = vqshlq_s32(mmtmpD0,output_shift128); + mmtmpD1 = vqshlq_s32(mmtmpD1,output_shift128); + rxdataF_comp128[2] = vzip_s16(vmovn_s32(mmtmpD0),vmovn_s32(mmtmpD1)); - dl_ch128+=6; - dl_ch_mag128+=3; - dl_ch_mag128b+=3; - rxdataF128+=6; - rxdataF_comp128+=3; + dl_ch128+=6; + dl_ch_mag128+=3; + dl_ch_mag128b+=3; + rxdataF128+=6; + rxdataF_comp128+=3; - } else { // we have a smaller PDSCH in symbols with pilots so skip last group of 4 REs and increment less - dl_ch128+=4; - dl_ch_mag128+=2; - dl_ch_mag128b+=2; - rxdataF128+=4; - rxdataF_comp128+=2; - } } } } @@ -1241,7 +1230,7 @@ void nr_dlsch_channel_compensation(int **rxdataF_ext, rho128 = (int16x4x2_t*)&rho[aarx][symbol*frame_parms->N_RB_DL*12]; dl_ch128 = (int16x4_t*)&dl_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_DL*12]; dl_ch128_2 = (int16x4_t*)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; - for (rb=0; rb<nb_rb; rb++) { + for (rb=0; rb<nb_rb_0; rb++) { mmtmpD0 = vmull_s16(dl_ch128[0], dl_ch128_2[0]); mmtmpD1 = vmull_s16(dl_ch128[1], dl_ch128_2[1]); mmtmpD0 = vcombine_s32(vpadd_s32(vget_low_s32(mmtmpD0),vget_high_s32(mmtmpD0)), @@ -1540,14 +1529,10 @@ void nr_dlsch_scale_channel(int **dl_ch_estimates_ext, dl_ch128[1] = _mm_mulhi_epi16(dl_ch128[1],ch_amp128); dl_ch128[1] = _mm_slli_epi16(dl_ch128[1],3); - if (pilots) { - dl_ch128+=2; - } else { - dl_ch128[2] = _mm_mulhi_epi16(dl_ch128[2],ch_amp128); - dl_ch128[2] = _mm_slli_epi16(dl_ch128[2],3); - dl_ch128+=3; + dl_ch128[2] = _mm_mulhi_epi16(dl_ch128[2],ch_amp128); + dl_ch128[2] = _mm_slli_epi16(dl_ch128[2],3); + dl_ch128+=3; - } } } } @@ -1579,6 +1564,7 @@ void nr_dlsch_channel_level(int **dl_ch_estimates_ext, //x = (x>4) ? 4 : x; int16_t y = (len)>>x; //printf("len = %d = %d * 2^(%d)\n",len,y,x); + uint32_t nb_rb_0 = len/12 + ((len%12)?1:0); AssertFatal(y!=0,"Cannot divide by zero: in function %s of file %s\n", __func__, __FILE__); @@ -1589,7 +1575,7 @@ void nr_dlsch_channel_level(int **dl_ch_estimates_ext, dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx*frame_parms->nb_antennas_rx)+aarx][symbol*nb_rb*12]; - for (rb=0;rb<nb_rb;rb++) { + for (rb=0;rb<nb_rb_0;rb++) { avg128D = _mm_add_epi32(avg128D,_mm_srai_epi32(_mm_madd_epi16(dl_ch128[0],dl_ch128[0]),x)); avg128D = _mm_add_epi32(avg128D,_mm_srai_epi32(_mm_madd_epi16(dl_ch128[1],dl_ch128[1]),x)); avg128D = _mm_add_epi32(avg128D,_mm_srai_epi32(_mm_madd_epi16(dl_ch128[2],dl_ch128[2]),x)); @@ -1614,7 +1600,7 @@ void nr_dlsch_channel_level(int **dl_ch_estimates_ext, int16x4_t *dl_ch128; symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; - + uint32_t nb_rb_0 = len/12 + ((len%12)?1:0); for (aatx=0; aatx<frame_parms->nb_antenna_ports_gNB; aatx++) for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { //clear average level @@ -1623,7 +1609,7 @@ void nr_dlsch_channel_level(int **dl_ch_estimates_ext, dl_ch128=(int16x4_t *)&dl_ch_estimates_ext[(aatx<<1)+aarx][symbol*frame_parms->N_RB_DL*12]; - for (rb=0; rb<nb_rb; rb++) { + for (rb=0; rb<nb_rb_0; rb++) { // printf("rb %d : ",rb); // print_shorts("ch",&dl_ch128[0]); avg128D = vqaddq_s32(avg128D,vmull_s16(dl_ch128[0],dl_ch128[0])); @@ -2072,7 +2058,7 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, unsigned char j=0; - if (config_type==pdsch_dmrs_type1) { + if (config_type==NFAPI_NR_DMRS_TYPE1) { AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2, "n_dmrs_cdm_groups %d is illegal\n",n_dmrs_cdm_groups); nushift = n_dmrs_cdm_groups -1;//delta in Table 7.4.1.1.2-1 @@ -2097,7 +2083,7 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, rxF = &rxdataF[aarx][(k+(symbol*(frame_parms->ofdm_symbol_size)))]; for (rb = 0; rb < nb_rb_pdsch; rb++) { - if (k>frame_parms->ofdm_symbol_size) { + if (k>=frame_parms->ofdm_symbol_size) { k = k-frame_parms->ofdm_symbol_size; rxF = &rxdataF[aarx][(k+(symbol*(frame_parms->ofdm_symbol_size)))]; } @@ -2108,7 +2094,7 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, rxF_ext+=12; } else {//the symbol contains DMRS j=0; - if (config_type==pdsch_dmrs_type1){ + if (config_type==NFAPI_NR_DMRS_TYPE1){ if (nushift == 0) {//data is multiplexed for (i = (1-nushift); i<12; i+=2) { rxF_ext[j]=rxF[i]; @@ -2118,7 +2104,7 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, dl_ch0_ext+=6; rxF_ext+=6; } - } else {//pdsch_dmrs_type2 + } else {//NFAPI_NR_DMRS_TYPE2 for (i = (2+nushift); i<6; i++) { rxF_ext[j]=rxF[i]; dl_ch0_ext[j]=dl_ch0[i]; @@ -2166,7 +2152,7 @@ unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF, int *dl_ch0,*dl_ch0_ext,*rxF,*rxF_ext; int8_t validDmrsEst = 0; //store last DMRS Symbol index - if (config_type==pdsch_dmrs_type1) { + if (config_type==NFAPI_NR_DMRS_TYPE1) { AssertFatal(n_dmrs_cdm_groups == 1 || n_dmrs_cdm_groups == 2, "n_dmrs_cdm_groups %d is illegal\n",n_dmrs_cdm_groups); nushift = n_dmrs_cdm_groups -1;//delta in Table 7.4.1.1.2-1 @@ -2181,7 +2167,7 @@ unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF, for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { k = frame_parms->first_carrier_offset + NR_NB_SC_PER_RB*start_rb; - if (k>frame_parms->ofdm_symbol_size) + if (k>=frame_parms->ofdm_symbol_size) k = k-frame_parms->ofdm_symbol_size; rxF_ext = &rxdataF_ext[aarx][symbol*(nb_rb_pdsch*12)]; @@ -2204,7 +2190,7 @@ unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF, } else {//the symbol contains DMRS j=0; - if (config_type==pdsch_dmrs_type1) { + if (config_type==NFAPI_NR_DMRS_TYPE1) { if (nushift == 0) {//data is multiplexed for (i = (1-nushift); i<12; i+=2) { if (aatx==0) rxF_ext[j]=rxF[i]; @@ -2215,7 +2201,7 @@ unsigned short nr_dlsch_extract_rbs_multiple(int **rxdataF, if (aatx==0) rxF_ext+=6; } } - else {//pdsch_dmrs_type2 + else {//NFAPI_NR_DMRS_TYPE2 for (i = (2+nushift); i<6; i++) { if (aatx==0) rxF_ext[j]=rxF[i]; dl_ch0_ext[j]=dl_ch0[i]; @@ -2250,43 +2236,55 @@ void nr_dlsch_detection_mrc(int **rxdataF_comp, int ***rho, int **dl_ch_mag, int **dl_ch_magb, + int **dl_ch_magr, short n_tx, short n_rx, unsigned char symbol, - unsigned short nb_rb) { + unsigned short nb_rb, + int length) { #if defined(__x86_64__)||defined(__i386__) unsigned char aatx, aarx; int i; - __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b; + __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128_1,*dl_ch_mag128_0b,*dl_ch_mag128_1b,*dl_ch_mag128_0r,*dl_ch_mag128_1r; + + uint32_t nb_rb_0 = length/12 + ((length%12)?1:0); if (n_rx>1) { for (aatx=0; aatx<n_tx; aatx++) { rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[(aatx*n_rx)][symbol*nb_rb*12];//aarx=0 dl_ch_mag128_0 = (__m128i *)&dl_ch_mag[(aatx*n_rx)][symbol*nb_rb*12];//aarx=0 dl_ch_mag128_0b = (__m128i *)&dl_ch_magb[(aatx*n_rx)][symbol*nb_rb*12]; + dl_ch_mag128_0r = (__m128i *)&dl_ch_magr[(aatx*n_rx)][symbol*nb_rb*12]; for (aarx=1; aarx<n_rx; aarx++) { rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[(aatx*n_rx)+aarx][symbol*nb_rb*12];// aarx=1,..., n_rx-1 dl_ch_mag128_1 = (__m128i *)&dl_ch_mag[(aatx*n_rx)+aarx][symbol*nb_rb*12]; dl_ch_mag128_1b = (__m128i *)&dl_ch_magb[(aatx*n_rx)+aarx][symbol*nb_rb*12]; + dl_ch_mag128_1r = (__m128i *)&dl_ch_magr[(aatx*n_rx)+aarx][symbol*nb_rb*12]; - // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM llr computation) - for (i=0; i<nb_rb*3; i++) { + // MRC on each re of rb, both on MF output and magnitude (for 16QAM/64QAM/256 llr computation) + for (i=0; i<nb_rb_0*3; i++) { rxdataF_comp128_0[i] = _mm_adds_epi16(rxdataF_comp128_0[i],rxdataF_comp128_1[i]); dl_ch_mag128_0[i] = _mm_adds_epi16(dl_ch_mag128_0[i],dl_ch_mag128_1[i]); dl_ch_mag128_0b[i] = _mm_adds_epi16(dl_ch_mag128_0b[i],dl_ch_mag128_1b[i]); - /*if (i==0) { - * printf("atx%d symbol%d\n",aatx,symbol); - * printf("mrc comp0 re: %d mrc comp0 im: %d \n",((int16_t*)&rxdataF_comp128_0[0])[0],((int16_t*)&rxdataF_comp128_0[0])[1]); - * printf("mrc mag0 = %d = %d \n",((int16_t*)&dl_ch_mag128_0[0])[0],((int16_t*)&dl_ch_mag128_0[0])[1]); - * printf("mrc mag0b = %d = %d \n",((int16_t*)&dl_ch_mag128_0b[0])[0],((int16_t*)&dl_ch_mag128_0b[0])[1]); - * }*/ + dl_ch_mag128_0r[i] = _mm_adds_epi16(dl_ch_mag128_0r[i],dl_ch_mag128_1r[i]); } } } +#ifdef DEBUG_DLSCH_DEMOD + for (i=0; i<nb_rb_0*3; i++) { + printf("symbol%d RB %d\n",symbol,i/3); + rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[0][symbol*nb_rb*12]; + rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[n_rx][symbol*nb_rb*12]; + print_shorts("tx 1 mrc_re/mrc_Im:",(int16_t*)&rxdataF_comp128_0[i]); + print_shorts("tx 2 mrc_re/mrc_Im:",(int16_t*)&rxdataF_comp128_1[i]); + // printf("mrc mag0 = %d = %d \n",((int16_t*)&dl_ch_mag128_0[0])[0],((int16_t*)&dl_ch_mag128_0[0])[1]); + // printf("mrc mag0b = %d = %d \n",((int16_t*)&dl_ch_mag128_0b[0])[0],((int16_t*)&dl_ch_mag128_0b[0])[1]); + } +#endif if (rho) { /*rho128_0 = (__m128i *) &rho[0][symbol*frame_parms->N_RB_DL*12]; rho128_1 = (__m128i *) &rho[1][symbol*frame_parms->N_RB_DL*12]; - for (i=0; i<nb_rb*3; i++) { + for (i=0; i<nb_rb_0*3; i++) { // print_shorts("mrc rho0:",&rho128_0[i]); // print_shorts("mrc rho1:",&rho128_1[i]); rho128_0[i] = _mm_adds_epi16(_mm_srai_epi16(rho128_0[i],1),_mm_srai_epi16(rho128_1[i],1)); @@ -2308,7 +2306,8 @@ void nr_det_HhH(int32_t *after_mf_00,//a int32_t *after_mf_11,//d int32_t *det_fin,//1/ad-bc unsigned short nb_rb, - unsigned char symbol) + unsigned char symbol, + int32_t shift) { int16_t nr_conjug2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ; unsigned short rb; @@ -2343,24 +2342,16 @@ void nr_det_HhH(int32_t *after_mf_00,//a det_re_128 = _mm_sub_epi32(ad_re_128, bc_re_128); //det_im_128 = _mm_sub_epi32(ad_im_128, bc_im_128); - //convert back to Q15 before packing - det_re_128 = _mm_srai_epi32(det_re_128,8);//(2^15/64*2) - //det_im_128 = _mm_srai_epi32(det_im_128,8); - - //tmp_det0 = _mm_unpacklo_epi32(det_re_128,det_im_128); - ////print_ints("unpack lo:",&tmp_det0[rb]); - //tmp_det1 = _mm_unpackhi_epi32(det_re_128,det_im_128); - ////print_ints("unpack hi:",&tmp_det1[rb]); - //det_matrix_128[0] = _mm_packs_epi32(tmp_det0,tmp_det1); + //det in Q30 format det_fin_128[0] = _mm_abs_epi32(det_re_128); - /*if ((rb==0)&&(symbol==1)) { - * printf("\n Computing det_HhH_inv \n"); - * print_ints("det_re_128:",(int32_t*)&det_re_128); - * print_ints("det_im_128:",(int32_t*)&det_im_128); - * print_ints("det_fin_128:",(int32_t*)&det_fin_128[0]); - * }*/ +#ifdef DEBUG_DLSCH_DEMOD + printf("\n Computing det_HhH_inv \n"); + //print_ints("det_re_128:",(int32_t*)&det_re_128); + //print_ints("det_im_128:",(int32_t*)&det_im_128); + print_ints("det_fin_128:",(int32_t*)&det_fin_128[0]); +#endif det_fin_128+=1; after_mf_00_128+=1; after_mf_01_128+=1; @@ -2455,7 +2446,67 @@ void nr_conjch0_mult_ch1(int *ch0, _mm_empty(); _m_empty(); } +__m128i nr_comp_muli_sum(__m128i input_x, + __m128i input_y, + __m128i input_w, + __m128i input_z, + __m128i det) +{ + int16_t nr_conjug2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ; + + __m128i xy_re_128, xy_im_128, wz_re_128, wz_im_128; + __m128i output, tmp_z0, tmp_z1; + + // complex multiplication (x_re + jx_im)*(y_re + jy_im) = (x_re*y_re - x_im*y_im) + j(x_im*y_re + x_re*y_im) + // the real part + xy_re_128 = _mm_sign_epi16(input_x,*(__m128i*)&nr_conjug2[0]); + xy_re_128 = _mm_madd_epi16(xy_re_128,input_y); //Re: (x_re*y_re - x_im*y_im) + + // the imag part + xy_im_128 = _mm_shufflelo_epi16(input_x,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the low 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits + xy_im_128 = _mm_shufflehi_epi16(xy_im_128,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the high 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits + xy_im_128 = _mm_madd_epi16(xy_im_128,input_y);//Im: (x_im*y_re + x_re*y_im) + + // complex multiplication (w_re + jw_im)*(z_re + jz_im) = (w_re*z_re - w_im*z_im) + j(w_im*z_re + w_re*z_im) + // the real part + wz_re_128 = _mm_sign_epi16(input_w,*(__m128i*)&nr_conjug2[0]); + wz_re_128 = _mm_madd_epi16(wz_re_128,input_z); //Re: (w_re*z_re - w_im*z_im) + + // the imag part + wz_im_128 = _mm_shufflelo_epi16(input_w,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the low 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits + wz_im_128 = _mm_shufflehi_epi16(wz_im_128,_MM_SHUFFLE(2,3,0,1));//permutes IQs for the high 64 bits as [I_a0 Q_a1 I_a2 Q_a3]_64bits to [Q_a1 I_a0 Q_a3 I_a2]_64bits + wz_im_128 = _mm_madd_epi16(wz_im_128,input_z);//Im: (w_im*z_re + w_re*z_im) + + + xy_re_128 = _mm_sub_epi32(xy_re_128, wz_re_128); + xy_im_128 = _mm_sub_epi32(xy_im_128, wz_im_128); + //print_ints("rx_re:",(int32_t*)&xy_re_128[0]); + //print_ints("rx_Img:",(int32_t*)&xy_im_128[0]); + //divide by matrix det and convert back to Q15 before packing + int sum_det =0; + for (int k=0; k<4;k++) { + sum_det += ((((int *)&det[0])[k])>>2); + //printf("det_%d = %d log2 =%d \n",k,(((int *)&det[0])[k]),log2_approx(((int *)&det[0])[k])); + } + + xy_re_128 = _mm_slli_epi32(xy_re_128,5); + xy_re_128 = _mm_srai_epi32(xy_re_128,log2_approx(sum_det)); + xy_re_128 = _mm_slli_epi32(xy_re_128,5); + + xy_im_128 = _mm_slli_epi32(xy_im_128,5); + xy_im_128 = _mm_srai_epi32(xy_im_128,log2_approx(sum_det)); + xy_im_128 = _mm_slli_epi32(xy_im_128,5); + tmp_z0 = _mm_unpacklo_epi32(xy_re_128,xy_im_128); + //print_ints("unpack lo:",&tmp_z0[0]); + tmp_z1 = _mm_unpackhi_epi32(xy_re_128,xy_im_128); + //print_ints("unpack hi:",&tmp_z1[0]); + output = _mm_packs_epi32(tmp_z0,tmp_z1); + + _mm_empty(); + _m_empty(); + return(output); +} /* Zero Forcing Rx function: nr_construct_HhH_elements() * * @@ -2534,15 +2585,16 @@ void nr_construct_HhH_elements(int *conjch00_ch00, if (conjch21_ch20 != NULL) after_mf_10_128[0] =_mm_adds_epi16(after_mf_10_128[0],conjch21_ch20_128[0]); if (conjch31_ch30 != NULL) after_mf_10_128[0] =_mm_adds_epi16(after_mf_10_128[0],conjch31_ch30_128[0]); - /*if ((rb==0)&&(symbol==1)) +#ifdef DEBUG_DLSCH_DEMOD + if ((rb<=30)) { printf(" \n construct_HhH_elements \n"); print_shorts("after_mf_00_128:",(int16_t*)&after_mf_00_128[0]); print_shorts("after_mf_01_128:",(int16_t*)&after_mf_01_128[0]); print_shorts("after_mf_10_128:",(int16_t*)&after_mf_10_128[0]); print_shorts("after_mf_11_128:",(int16_t*)&after_mf_11_128[0]); - }*/ - + } +#endif conjch00_ch00_128+=1; conjch10_ch10_128+=1; conjch01_ch01_128+=1; @@ -2579,16 +2631,18 @@ void nr_construct_HhH_elements(int *conjch00_ch00, uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp, int **dl_ch_mag, int **dl_ch_magb, + int **dl_ch_magr, int **dl_ch_estimates_ext, unsigned short nb_rb, unsigned char n_rx, unsigned char mod_order, int shift, - unsigned char symbol) + unsigned char symbol, + int length) { int *ch00, *ch01, *ch10, *ch11; int *ch20, *ch30, *ch21, *ch31; - + uint32_t nb_rb_0 = length/12 + ((length%12)?1:0); /* we need at least alignment to 16 bytes, let's put 32 to be sure * (maybe not necessary but doesn't hurt) */ @@ -2656,49 +2710,49 @@ uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp, nr_conjch0_mult_ch1(ch00, ch00, conjch00_ch00, - nb_rb, + nb_rb_0, shift); // (1/2^log2_maxh)*conj_H_10xH_10: (1/(64*2))conjH_10*H_10*2^15 nr_conjch0_mult_ch1(ch10, ch10, conjch10_ch10, - nb_rb, + nb_rb_0, shift); // conj_H_00xH_01 nr_conjch0_mult_ch1(ch00, ch01, conjch00_ch01, - nb_rb, + nb_rb_0, shift); // this shift is equal to the channel level log2_maxh // conj_H_10xH_11 nr_conjch0_mult_ch1(ch10, ch11, conjch10_ch11, - nb_rb, + nb_rb_0, shift); // conj_H_01xH_01 nr_conjch0_mult_ch1(ch01, ch01, conjch01_ch01, - nb_rb, + nb_rb_0, shift); // conj_H_11xH_11 nr_conjch0_mult_ch1(ch11, ch11, conjch11_ch11, - nb_rb, + nb_rb_0, shift); // conj_H_01xH_00 nr_conjch0_mult_ch1(ch01, ch00, conjch01_ch00, - nb_rb, + nb_rb_0, shift); // conj_H_11xH_10 nr_conjch0_mult_ch1(ch11, ch10, conjch11_ch10, - nb_rb, + nb_rb_0, shift); } if (n_rx==4){ @@ -2706,52 +2760,52 @@ uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp, nr_conjch0_mult_ch1(ch20, ch20, conjch20_ch20, - nb_rb, + nb_rb_0, shift); // (1/2^log2_maxh)*conj_H_30xH_30: (1/(64*2*4))conjH_30*H_30*2^15 nr_conjch0_mult_ch1(ch30, ch30, conjch30_ch30, - nb_rb, + nb_rb_0, shift); // (1/2^log2_maxh)*conj_H_20xH_20: (1/(64*2))conjH_20*H_20*2^15 nr_conjch0_mult_ch1(ch20, ch21, conjch20_ch21, - nb_rb, + nb_rb_0, shift); nr_conjch0_mult_ch1(ch30, ch31, conjch30_ch31, - nb_rb, + nb_rb_0, shift); nr_conjch0_mult_ch1(ch21, ch21, conjch21_ch21, - nb_rb, + nb_rb_0, shift); nr_conjch0_mult_ch1(ch31, ch31, conjch31_ch31, - nb_rb, + nb_rb_0, shift); // (1/2^log2_maxh)*conj_H_20xH_20: (1/(64*2))conjH_20*H_20*2^15 nr_conjch0_mult_ch1(ch21, ch20, conjch21_ch20, - nb_rb, + nb_rb_0, shift); nr_conjch0_mult_ch1(ch31, ch30, conjch31_ch30, - nb_rb, + nb_rb_0, shift); nr_construct_HhH_elements(conjch00_ch00, @@ -2774,7 +2828,7 @@ uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp, af_mf_01, af_mf_10, af_mf_11, - nb_rb, + nb_rb_0, symbol); } if (n_rx==2){ @@ -2798,7 +2852,7 @@ uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp, af_mf_01, af_mf_10, af_mf_11, - nb_rb, + nb_rb_0, symbol); } //det_HhH = ad -bc @@ -2807,8 +2861,9 @@ uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp, af_mf_10,//c af_mf_11,//d determ_fin, - nb_rb, - symbol); + nb_rb_0, + symbol, + shift); /* 2- Compute the channel matrix inversion ********************************** * * |(conj_H_00xH_00+conj_H_10xH_10) (conj_H_00xH_01+conj_H_10xH_11)| @@ -2822,92 +2877,106 @@ uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp, * * **************************************************************************/ - __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128b_0,*dl_ch_mag128_1,*dl_ch_mag128b_1,*determ_fin_128; - __m128i mmtmpD2,mmtmpD3,mmtmpD0,mmtmpD1,QAM_amp128,QAM_amp128b; + __m128i *rxdataF_comp128_0,*rxdataF_comp128_1,*dl_ch_mag128_0,*dl_ch_mag128b_0,*dl_ch_mag128r_0,*determ_fin_128;//*dl_ch_mag128_1,*dl_ch_mag128b_1,*dl_ch_mag128r_1 + __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3; __m128i *after_mf_a_128,*after_mf_b_128, *after_mf_c_128, *after_mf_d_128; + __m128i QAM_amp128,QAM_amp128b,QAM_amp128r; determ_fin_128 = (__m128i *)&determ_fin[0]; rxdataF_comp128_0 = (__m128i *)&rxdataF_comp[0][symbol*nb_rb*12];//aatx=0 @ aarx =0 rxdataF_comp128_1 = (__m128i *)&rxdataF_comp[n_rx][symbol*nb_rb*12];//aatx=1 @ aarx =0 - dl_ch_mag128_0 = (__m128i *)&dl_ch_mag[0][symbol*nb_rb*12]; - dl_ch_mag128_1 = (__m128i *)&dl_ch_mag[n_rx][symbol*nb_rb*12]; - dl_ch_mag128b_0 = (__m128i *)&dl_ch_magb[0][symbol*nb_rb*12]; - dl_ch_mag128b_1 = (__m128i *)&dl_ch_magb[n_rx][symbol*nb_rb*12]; - after_mf_a_128 = (__m128i *)af_mf_00; after_mf_b_128 = (__m128i *)af_mf_01; after_mf_c_128 = (__m128i *)af_mf_10; after_mf_d_128 = (__m128i *)af_mf_11; - QAM_amp128b = _mm_setzero_si128(); - - if (mod_order == 4) { - QAM_amp128 = _mm_set1_epi16(QAM16_n1); // 2/sqrt(10) - QAM_amp128b = _mm_setzero_si128(); - } else if (mod_order == 6) { - QAM_amp128 = _mm_set1_epi16(QAM64_n1); // - QAM_amp128b = _mm_set1_epi16(QAM64_n2); + if (mod_order>2) { + if (mod_order == 4) { + QAM_amp128 = _mm_set1_epi16(QAM16_n1); //2/sqrt(10) + QAM_amp128b = _mm_setzero_si128(); + QAM_amp128r = _mm_setzero_si128(); + } else if (mod_order == 6) { + QAM_amp128 = _mm_set1_epi16(QAM64_n1); //4/sqrt{42} + QAM_amp128b = _mm_set1_epi16(QAM64_n2); //2/sqrt{42} + QAM_amp128r = _mm_setzero_si128(); + } else if (mod_order == 8) { + QAM_amp128 = _mm_set1_epi16(QAM256_n1); //8/sqrt{170} + QAM_amp128b = _mm_set1_epi16(QAM256_n2);//4/sqrt{170} + QAM_amp128r = _mm_set1_epi16(QAM256_n3);//2/sqrt{170} + } + dl_ch_mag128_0 = (__m128i *)&dl_ch_mag[0][symbol*nb_rb*12]; + dl_ch_mag128b_0 = (__m128i *)&dl_ch_magb[0][symbol*nb_rb*12]; + dl_ch_mag128r_0 = (__m128i *)&dl_ch_magr[0][symbol*nb_rb*12]; } - for (int rb=0; rb<3*nb_rb; rb++) { + for (int rb=0; rb<3*nb_rb_0; rb++) { if (mod_order>2) { - // get channel determ (da -bc) if not QPSK - mmtmpD0 = _mm_packs_epi32(determ_fin_128[0],determ_fin_128[0]);//convert 32 bits to 16 bits + int sum_det =0; + for (int k=0; k<4;k++) { + sum_det += ((((int *)&determ_fin_128[0])[k])>>2); + //printf("det_%d = %d\n",k,sum_det); + } + + mmtmpD2 = _mm_slli_epi32(determ_fin_128[0],5); + mmtmpD2 = _mm_srai_epi32(mmtmpD2,log2_approx(sum_det)); + mmtmpD2 = _mm_slli_epi32(mmtmpD2,5); + + mmtmpD3 = _mm_unpacklo_epi32(mmtmpD2,mmtmpD2); + + mmtmpD2 = _mm_unpackhi_epi32(mmtmpD2,mmtmpD2); - dl_ch_mag128_0[0] = _mm_unpacklo_epi16(mmtmpD0,mmtmpD0); - dl_ch_mag128b_0[0] = dl_ch_mag128_0[0]; + mmtmpD2 = _mm_packs_epi32(mmtmpD3,mmtmpD2); + + dl_ch_mag128_0[0] = mmtmpD2; + dl_ch_mag128b_0[0] = mmtmpD2; + dl_ch_mag128r_0[0] = mmtmpD2; dl_ch_mag128_0[0] = _mm_mulhi_epi16(dl_ch_mag128_0[0],QAM_amp128); - dl_ch_mag128_0[0] = _mm_slli_epi16(dl_ch_mag128_0[0],1);//aatx=0 @ aarx =0 - dl_ch_mag128_1[0] = dl_ch_mag128_0[0];//aatx=1 @ aarx =0 + dl_ch_mag128_0[0] = _mm_slli_epi16(dl_ch_mag128_0[0],1); dl_ch_mag128b_0[0] = _mm_mulhi_epi16(dl_ch_mag128b_0[0],QAM_amp128b); - dl_ch_mag128b_0[0] = _mm_slli_epi16(dl_ch_mag128b_0[0],1);//aatx=0 @ aarx = - dl_ch_mag128b_1[0] = dl_ch_mag128b_0[0];//aatx=1 @ aarx =0 - - if ((rb==0)&&(symbol==1)) { - printf("\n Signal mag after ZF \n"); - print_shorts("mag layer 1:",(int16_t*)&dl_ch_mag128_0[0]); - print_shorts("mag layer 2:",(int16_t*)&dl_ch_mag128_1[0]); - print_shorts("magb layer 1:",(int16_t*)&dl_ch_mag128b_0[0]); - print_shorts("magb layer 2:",(int16_t*)&dl_ch_mag128b_1[0]); - } + dl_ch_mag128b_0[0] = _mm_slli_epi16(dl_ch_mag128b_0[0],1); + + dl_ch_mag128r_0[0] = _mm_mulhi_epi16(dl_ch_mag128r_0[0],QAM_amp128r); + dl_ch_mag128r_0[0] = _mm_slli_epi16(dl_ch_mag128r_0[0],1); + + //print_shorts("mag layer 1:",(int16_t*)&dl_ch_mag128_0[0]); + //print_shorts("mag layer 2:",(int16_t*)&dl_ch_mag128_1[0]); + //print_shorts("magb layer 1:",(int16_t*)&dl_ch_mag128b_0[0]); + //print_shorts("magb layer 2:",(int16_t*)&dl_ch_mag128b_1[0]); + //print_shorts("magr layer 1:",(int16_t*)&dl_ch_mag128r_0[0]); + //print_shorts("magr layer 2:",(int16_t*)&dl_ch_mag128r_1[0]); } // multiply by channel Inv //rxdataF_zf128_0 = rxdataF_comp128_0*d - b*rxdataF_comp128_1 //rxdataF_zf128_1 = rxdataF_comp128_1*a - c*rxdataF_comp128_0 - mmtmpD2 = nr_inv_comp_muli(rxdataF_comp128_0[0],//x - after_mf_d_128[0]);//y - mmtmpD3 = nr_inv_comp_muli(rxdataF_comp128_1[0],//x - after_mf_b_128[0]);//y - //mmtmpD2[0] - mmtmpD3[0] - //rxdataF_zf128_0 - mmtmpD0 = _mm_sub_epi16(mmtmpD2, mmtmpD3); - - mmtmpD2 = nr_inv_comp_muli(rxdataF_comp128_1[0],//x - after_mf_a_128[0]);//y - mmtmpD3 = nr_inv_comp_muli(rxdataF_comp128_0[0],//x - after_mf_c_128[0]);//y - //mmtmpD2[0] - mmtmpD3[0] - //rxdataF_zf128_1 - mmtmpD1 = _mm_sub_epi16(mmtmpD2, mmtmpD3); + //printf("layer_1 \n"); + mmtmpD0 = nr_comp_muli_sum(rxdataF_comp128_0[0], + after_mf_d_128[0], + rxdataF_comp128_1[0], + after_mf_b_128[0], + determ_fin_128[0]); + + //printf("layer_2 \n"); + mmtmpD1 = nr_comp_muli_sum(rxdataF_comp128_1[0], + after_mf_a_128[0], + rxdataF_comp128_0[0], + after_mf_c_128[0], + determ_fin_128[0]); rxdataF_comp128_0[0] = mmtmpD0; rxdataF_comp128_1[0] = mmtmpD1; - - /*if ((rb==0)&&(symbol==1)) { - printf("\n Rx signal after ZF \n"); - print_shorts("Rx layer 1:",(int16_t*)&rxdataF_comp128_0[0]); - print_shorts("Rx layer 2:",(int16_t*)&rxdataF_comp128_1[0]); - }*/ - +#ifdef DEBUG_DLSCH_DEMOD + printf("\n Rx signal after ZF l%d rb%d\n",symbol,rb); + print_shorts(" Rx layer 1:",(int16_t*)&rxdataF_comp128_0[0]); + print_shorts(" Rx layer 2:",(int16_t*)&rxdataF_comp128_1[0]); +#endif determ_fin_128 += 1; dl_ch_mag128_0 += 1; dl_ch_mag128b_0 += 1; - dl_ch_mag128_1 += 1; - dl_ch_mag128b_1 += 1; + dl_ch_mag128r_0 += 1; rxdataF_comp128_0 += 1; rxdataF_comp128_1 += 1; after_mf_a_128 += 1; @@ -2923,13 +2992,18 @@ uint8_t nr_zero_forcing_rx_2layers(int **rxdataF_comp, static void nr_dlsch_layer_demapping(int16_t **llr_cw, uint8_t Nl, uint8_t mod_order, - uint16_t length, + uint32_t length, + int32_t codeword_TB0, + int32_t codeword_TB1, int16_t **llr_layers) { switch (Nl) { - case 1: - memcpy((void*)llr_layers[0], (void*)llr_cw[0], (length)*sizeof(int16_t)); + if (codeword_TB1 == -1) + memcpy((void*)llr_cw[0], (void*)llr_layers[0], (length)*sizeof(int16_t)); + else if (codeword_TB0 == -1) + memcpy((void*)llr_cw[1], (void*)llr_layers[0], (length)*sizeof(int16_t)); + break; case 2: @@ -2937,11 +3011,15 @@ static void nr_dlsch_layer_demapping(int16_t **llr_cw, case 4: for (int i=0; i<(length/Nl/mod_order); i++){ for (int l=0; l<Nl; l++) { - for (int m=0; m<mod_order; m++){ - llr_cw[0][Nl*i+l*mod_order+m] = llr_layers[l][i*mod_order+m]; - } + for (int m=0; m<mod_order; m++){ + if (codeword_TB1 == -1) + llr_cw[0][Nl*mod_order*i+l*mod_order+m] = llr_layers[l][i*mod_order+m];//i:0 -->0 1 2 3 + else if (codeword_TB0 == -1) + llr_cw[1][Nl*mod_order*i+l*mod_order+m] = llr_layers[l][i*mod_order+m];//i:0 -->0 1 2 3 + //if (i<4) printf("length%d: llr_layers[l%d][m%d]=%d: \n",length,l,m,llr_layers[l][i*mod_order+m]); + } + } } - } break; default: @@ -3009,299 +3087,110 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars, switch (dlsch0_harq->Qm) { case 2 : - if ((rx_type==rx_standard) || (codeword_TB1 == -1)) { - nr_dlsch_qpsk_llr(frame_parms, - pdsch_vars[gNB_id]->rxdataF_comp0, - pllr_symbol_cw0, - symbol, - len, - first_symbol_flag, - nb_rb, - beamforming_mode); - - } else if (codeword_TB0 == -1){ - - nr_dlsch_qpsk_llr(frame_parms, - pdsch_vars[gNB_id]->rxdataF_comp0, - pllr_symbol_cw1, - symbol, - len, - first_symbol_flag, - nb_rb, - beamforming_mode); - } - else if (rx_type >= rx_IC_single_stream) { - if (dlsch1_harq->Qm == 2) { - nr_dlsch_qpsk_qpsk_llr(frame_parms, + switch (rx_type) { + case rx_standard : + for(int l =0; l<dlsch0_harq->Nl; l++) + nr_dlsch_qpsk_llr(frame_parms, + pdsch_vars[gNB_id]->rxdataF_comp0[l*frame_parms->nb_antennas_rx], + pdsch_vars[gNB_id]->layer_llr[l]+llr_offset_symbol, + symbol, + len, + first_symbol_flag, + nb_rb, + beamforming_mode); + break; + case rx_IC_single_stream ://not implemented yet + /*nr_dlsch_qpsk_qpsk_llr(frame_parms, pdsch_vars[gNB_id]->rxdataF_comp0, rxdataF_comp_ptr, pdsch_vars[gNB_id]->dl_ch_rho2_ext, pdsch_vars[gNB_id]->layer_llr[0], symbol,len,first_symbol_flag,nb_rb, adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,nr_slot_rx,symbol), - pdsch_vars[gNB_id]->llr128); - if (rx_type==rx_IC_dual_stream) { - nr_dlsch_qpsk_qpsk_llr(frame_parms, - rxdataF_comp_ptr, - pdsch_vars[gNB_id]->rxdataF_comp0, - pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round], - pdsch_vars[gNB_id]->layer_llr[1], - symbol,len,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,nr_slot_rx,symbol), - pdsch_vars[gNB_id]->llr128_2ndstream); - } - } - else if (dlsch1_harq->Qm == 4) { - nr_dlsch_qpsk_16qam_llr(frame_parms, - pdsch_vars[gNB_id]->rxdataF_comp0, - rxdataF_comp_ptr,//i - dl_ch_mag_ptr,//i - pdsch_vars[gNB_id]->dl_ch_rho2_ext, - pdsch_vars[gNB_id]->layer_llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,nr_slot_rx,symbol), - pdsch_vars[gNB_id]->llr128); - if (rx_type==rx_IC_dual_stream) { - nr_dlsch_16qam_qpsk_llr(frame_parms, - rxdataF_comp_ptr, - pdsch_vars[gNB_id]->rxdataF_comp0,//i - dl_ch_mag_ptr, - pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round], - pdsch_vars[gNB_id]->layer_llr[1], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,nr_slot_rx,symbol), - pdsch_vars[gNB_id]->llr128_2ndstream); - } - } - else { - nr_dlsch_qpsk_64qam_llr(frame_parms, - pdsch_vars[gNB_id]->rxdataF_comp0, - rxdataF_comp_ptr,//i - dl_ch_mag_ptr,//i - pdsch_vars[gNB_id]->dl_ch_rho2_ext, - pdsch_vars[gNB_id]->layer_llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,nr_slot_rx,symbol), - pdsch_vars[gNB_id]->llr128); - if (rx_type==rx_IC_dual_stream) { - nr_dlsch_64qam_qpsk_llr(frame_parms, - rxdataF_comp_ptr, - pdsch_vars[gNB_id]->rxdataF_comp0,//i - dl_ch_mag_ptr, - pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round], - pdsch_vars[gNB_id]->layer_llr[1], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,nr_slot_rx,symbol), - pdsch_vars[gNB_id]->llr128_2ndstream); - } - } + pdsch_vars[gNB_id]->llr128);*/ + break; + case rx_IC_dual_stream ://not implemented yet + /*nr_dlsch_qpsk_qpsk_llr(frame_parms, + rxdataF_comp_ptr, + pdsch_vars[gNB_id]->rxdataF_comp0, + pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round], + pdsch_vars[gNB_id]->layer_llr[1], + symbol,len,first_symbol_flag,nb_rb, + adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,nr_slot_rx,symbol), + pdsch_vars[gNB_id]->llr128_2ndstream);*/ + break; + case rx_SIC_dual_stream ://not implemented yet + break; } break; case 4 : - if ((rx_type==rx_standard ) || (codeword_TB1 == -1)) { - nr_dlsch_16qam_llr(frame_parms, - pdsch_vars[gNB_id]->rxdataF_comp0, - pdsch_vars[gNB_id]->llr[0], - pdsch_vars[gNB_id]->dl_ch_mag0, - symbol,len,first_symbol_flag,nb_rb, - pdsch_vars[gNB_id]->llr128, - beamforming_mode); - } else if (codeword_TB0 == -1){ - nr_dlsch_16qam_llr(frame_parms, - pdsch_vars[gNB_id]->rxdataF_comp0, - pdsch_vars[gNB_id]->llr[1], - pdsch_vars[gNB_id]->dl_ch_mag0, - symbol,len,first_symbol_flag,nb_rb, - pdsch_vars[gNB_id]->llr128_2ndstream, - beamforming_mode); - } - else if (rx_type >= rx_IC_single_stream) { - if (dlsch1_harq->Qm == 2) { - nr_dlsch_16qam_qpsk_llr(frame_parms, - pdsch_vars[gNB_id]->rxdataF_comp0, - rxdataF_comp_ptr,//i - pdsch_vars[gNB_id]->dl_ch_mag0, - pdsch_vars[gNB_id]->dl_ch_rho2_ext, - pdsch_vars[gNB_id]->layer_llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,nr_slot_rx,symbol), - pdsch_vars[gNB_id]->llr128); - if (rx_type==rx_IC_dual_stream) { - nr_dlsch_qpsk_16qam_llr(frame_parms, - rxdataF_comp_ptr, - pdsch_vars[gNB_id]->rxdataF_comp0,//i - pdsch_vars[gNB_id]->dl_ch_mag0,//i - pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round], - pdsch_vars[gNB_id]->layer_llr[1], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,nr_slot_rx,symbol), - pdsch_vars[gNB_id]->llr128_2ndstream); - } - } - else if (dlsch1_harq->Qm == 4) { - nr_dlsch_16qam_16qam_llr(frame_parms, - pdsch_vars[gNB_id]->rxdataF_comp0, - rxdataF_comp_ptr,//i - pdsch_vars[gNB_id]->dl_ch_mag0, - dl_ch_mag_ptr,//i - pdsch_vars[gNB_id]->dl_ch_rho2_ext, - pdsch_vars[gNB_id]->layer_llr[0], - symbol,len,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,nr_slot_rx,symbol), - pdsch_vars[gNB_id]->llr128); - if (rx_type==rx_IC_dual_stream) { - nr_dlsch_16qam_16qam_llr(frame_parms, - rxdataF_comp_ptr, - pdsch_vars[gNB_id]->rxdataF_comp0,//i - dl_ch_mag_ptr, - pdsch_vars[gNB_id]->dl_ch_mag0,//i - pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round], - pdsch_vars[gNB_id]->layer_llr[1], - symbol,len,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,nr_slot_rx,symbol), - pdsch_vars[gNB_id]->llr128_2ndstream); - } - } - else { - nr_dlsch_16qam_64qam_llr(frame_parms, - pdsch_vars[gNB_id]->rxdataF_comp0, - rxdataF_comp_ptr,//i - pdsch_vars[gNB_id]->dl_ch_mag0, - dl_ch_mag_ptr,//i - pdsch_vars[gNB_id]->dl_ch_rho2_ext, - pdsch_vars[gNB_id]->layer_llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,nr_slot_rx,symbol), - pdsch_vars[gNB_id]->llr128); - if (rx_type==rx_IC_dual_stream) { - nr_dlsch_64qam_16qam_llr(frame_parms, - rxdataF_comp_ptr, - pdsch_vars[gNB_id]->rxdataF_comp0, - dl_ch_mag_ptr, - pdsch_vars[gNB_id]->dl_ch_mag0, - pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round], - pdsch_vars[gNB_id]->layer_llr[1], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,nr_slot_rx,symbol), - pdsch_vars[gNB_id]->llr128_2ndstream); - } - } + switch (rx_type) { + case rx_standard : + for(int l =0; l<dlsch0_harq->Nl; l++) + nr_dlsch_16qam_llr(frame_parms, + pdsch_vars[gNB_id]->rxdataF_comp0[l*frame_parms->nb_antennas_rx], + pdsch_vars[gNB_id]->layer_llr[l]+llr_offset_symbol, + pdsch_vars[gNB_id]->dl_ch_mag0[0], + symbol, + len, + first_symbol_flag, + nb_rb, + beamforming_mode); + break; + case rx_IC_single_stream ://not implemented yet + break; + case rx_IC_dual_stream ://not implemented yet + break; + case rx_SIC_dual_stream ://not implemented yet + break; } break; case 6 : - if ((rx_type==rx_standard) || (codeword_TB1 == -1)) { - nr_dlsch_64qam_llr(frame_parms, - pdsch_vars[gNB_id]->rxdataF_comp0, - (int16_t*)pllr_symbol_cw0, - pdsch_vars[gNB_id]->dl_ch_mag0, - pdsch_vars[gNB_id]->dl_ch_magb0, - symbol,len,first_symbol_flag,nb_rb, - pdsch_vars[gNB_id]->llr_offset[symbol], - beamforming_mode); - } else if (codeword_TB0 == -1){ - nr_dlsch_64qam_llr(frame_parms, - pdsch_vars[gNB_id]->rxdataF_comp0, - pllr_symbol_cw1, - pdsch_vars[gNB_id]->dl_ch_mag0, - pdsch_vars[gNB_id]->dl_ch_magb0, - symbol,len,first_symbol_flag,nb_rb, - pdsch_vars[gNB_id]->llr_offset[symbol], - beamforming_mode); - } - else if (rx_type >= rx_IC_single_stream) { - if (dlsch1_harq->Qm == 2) { - nr_dlsch_64qam_qpsk_llr(frame_parms, - pdsch_vars[gNB_id]->rxdataF_comp0, - rxdataF_comp_ptr,//i - pdsch_vars[gNB_id]->dl_ch_mag0, - pdsch_vars[gNB_id]->dl_ch_rho2_ext, - pdsch_vars[gNB_id]->layer_llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,nr_slot_rx,symbol), - pdsch_vars[gNB_id]->llr128); - if (rx_type==rx_IC_dual_stream) { - nr_dlsch_qpsk_64qam_llr(frame_parms, - rxdataF_comp_ptr, - pdsch_vars[gNB_id]->rxdataF_comp0,//i - pdsch_vars[gNB_id]->dl_ch_mag0, - pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round], - pdsch_vars[gNB_id]->layer_llr[1], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,2,nr_slot_rx,symbol), - pdsch_vars[gNB_id]->llr128_2ndstream); - } - } - else if (dlsch1_harq->Qm == 4) { - nr_dlsch_64qam_16qam_llr(frame_parms, - pdsch_vars[gNB_id]->rxdataF_comp0, - rxdataF_comp_ptr,//i - pdsch_vars[gNB_id]->dl_ch_mag0, - dl_ch_mag_ptr,//i - pdsch_vars[gNB_id]->dl_ch_rho2_ext, - pdsch_vars[gNB_id]->layer_llr[0], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,nr_slot_rx,symbol), - pdsch_vars[gNB_id]->llr128); - if (rx_type==rx_IC_dual_stream) { - nr_dlsch_16qam_64qam_llr(frame_parms, - rxdataF_comp_ptr, - pdsch_vars[gNB_id]->rxdataF_comp0,//i - dl_ch_mag_ptr, - pdsch_vars[gNB_id]->dl_ch_mag0,//i - pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round], - pdsch_vars[gNB_id]->layer_llr[1], - symbol,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,4,nr_slot_rx,symbol), - pdsch_vars[gNB_id]->llr128_2ndstream); - } - } - else { - nr_dlsch_64qam_64qam_llr(frame_parms, - pdsch_vars[gNB_id]->rxdataF_comp0, - rxdataF_comp_ptr,//i - pdsch_vars[gNB_id]->dl_ch_mag0, - dl_ch_mag_ptr,//i - pdsch_vars[gNB_id]->dl_ch_rho2_ext, - (int16_t*)pllr_symbol_layer0, - symbol,len,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,nr_slot_rx,symbol), - pdsch_vars[gNB_id]->llr_offset[symbol]); - if (rx_type==rx_IC_dual_stream) { - nr_dlsch_64qam_64qam_llr(frame_parms, - rxdataF_comp_ptr, - pdsch_vars[gNB_id]->rxdataF_comp0,//i - dl_ch_mag_ptr, - pdsch_vars[gNB_id]->dl_ch_mag0,//i - pdsch_vars[gNB_id]->dl_ch_rho_ext[harq_pid][round], - pllr_symbol_layer1, - symbol,len,first_symbol_flag,nb_rb, - adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,nr_slot_rx,symbol), - pdsch_vars[gNB_id]->llr_offset[symbol]); - } - } + switch (rx_type) { + case rx_standard : + for(int l =0; l<dlsch0_harq->Nl; l++) + nr_dlsch_64qam_llr(frame_parms, + pdsch_vars[gNB_id]->rxdataF_comp0[l*frame_parms->nb_antennas_rx], + pdsch_vars[gNB_id]->layer_llr[l]+llr_offset_symbol, + pdsch_vars[gNB_id]->dl_ch_mag0[0], + pdsch_vars[gNB_id]->dl_ch_magb0[0], + symbol, + len, + first_symbol_flag, + nb_rb, + beamforming_mode); + break; + case rx_IC_single_stream ://not implemented yet + break; + case rx_IC_dual_stream ://not implemented yet + break; + case rx_SIC_dual_stream ://not implemented yet + break; } + break; case 8: - if ((rx_type==rx_standard) || (codeword_TB1 == -1)) { - nr_dlsch_256qam_llr(frame_parms, - pdsch_vars[gNB_id]->rxdataF_comp0, - (int16_t*)pllr_symbol_cw0, - pdsch_vars[gNB_id]->dl_ch_mag0, - pdsch_vars[gNB_id]->dl_ch_magb0, - pdsch_vars[gNB_id]->dl_ch_magr0, - symbol,len,first_symbol_flag,nb_rb, - pdsch_vars[gNB_id]->llr_offset[symbol], - beamforming_mode); - } else if (codeword_TB0 == -1){ - nr_dlsch_256qam_llr(frame_parms, - pdsch_vars[gNB_id]->rxdataF_comp0, - pllr_symbol_cw1, - pdsch_vars[gNB_id]->dl_ch_mag0, - pdsch_vars[gNB_id]->dl_ch_magb0, - pdsch_vars[gNB_id]->dl_ch_magr0, - symbol,len,first_symbol_flag,nb_rb, - pdsch_vars[gNB_id]->llr_offset[symbol], - beamforming_mode); + switch (rx_type) { + case rx_standard : + for(int l =0; l<dlsch0_harq->Nl; l++) + nr_dlsch_256qam_llr(frame_parms, + pdsch_vars[gNB_id]->rxdataF_comp0[l*frame_parms->nb_antennas_rx], + pdsch_vars[gNB_id]->layer_llr[l]+llr_offset_symbol, + pdsch_vars[gNB_id]->dl_ch_mag0[0], + pdsch_vars[gNB_id]->dl_ch_magb0[0], + pdsch_vars[gNB_id]->dl_ch_magr0[0], + symbol, + len, + first_symbol_flag, + nb_rb, + beamforming_mode); + break; + case rx_IC_single_stream ://not implemented yet + break; + case rx_IC_dual_stream ://not implemented yet + break; + case rx_SIC_dual_stream ://not implemented yet + break; } break; default: @@ -3315,45 +3204,54 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars, case 2 : if (rx_type==rx_standard) { nr_dlsch_qpsk_llr(frame_parms, - pdsch_vars[gNB_id]->rxdataF_comp0, - pllr_symbol_cw0, - symbol,len,first_symbol_flag,nb_rb, + pdsch_vars[gNB_id]->rxdataF_comp0[0], + pdsch_vars[gNB_id]->layer_llr[0]+llr_offset_symbol, + symbol, + len, + first_symbol_flag, + nb_rb, beamforming_mode); } break; case 4: if (rx_type==rx_standard) { nr_dlsch_16qam_llr(frame_parms, - pdsch_vars[gNB_id]->rxdataF_comp0, - pdsch_vars[gNB_id]->llr[0], - pdsch_vars[gNB_id]->dl_ch_mag0, - symbol,len,first_symbol_flag,nb_rb, - pdsch_vars[gNB_id]->llr128, + pdsch_vars[gNB_id]->rxdataF_comp0[0], + pdsch_vars[gNB_id]->layer_llr[0]+llr_offset_symbol, + pdsch_vars[gNB_id]->dl_ch_mag0[0], + symbol, + len, + first_symbol_flag, + nb_rb, beamforming_mode); } break; case 6 : if (rx_type==rx_standard) { nr_dlsch_64qam_llr(frame_parms, - pdsch_vars[gNB_id]->rxdataF_comp0, - pllr_symbol_cw0, - pdsch_vars[gNB_id]->dl_ch_mag0, - pdsch_vars[gNB_id]->dl_ch_magb0, - symbol,len,first_symbol_flag,nb_rb, - pdsch_vars[gNB_id]->llr_offset[symbol], - beamforming_mode); + pdsch_vars[gNB_id]->rxdataF_comp0[0], + pdsch_vars[gNB_id]->layer_llr[0]+llr_offset_symbol, + pdsch_vars[gNB_id]->dl_ch_mag0[0], + pdsch_vars[gNB_id]->dl_ch_magb0[0], + symbol, + len, + first_symbol_flag, + nb_rb, + beamforming_mode); } break; case 8 : if (rx_type==rx_standard) { nr_dlsch_256qam_llr(frame_parms, - pdsch_vars[gNB_id]->rxdataF_comp0, - pllr_symbol_cw0, - pdsch_vars[gNB_id]->dl_ch_mag0, - pdsch_vars[gNB_id]->dl_ch_magb0, - pdsch_vars[gNB_id]->dl_ch_magr0, - symbol,len,first_symbol_flag,nb_rb, - pdsch_vars[gNB_id]->llr_offset[symbol], + pdsch_vars[gNB_id]->rxdataF_comp0[0], + pdsch_vars[gNB_id]->layer_llr[0]+llr_offset_symbol, + pdsch_vars[gNB_id]->dl_ch_mag0[0], + pdsch_vars[gNB_id]->dl_ch_magb0[0], + pdsch_vars[gNB_id]->dl_ch_magr0[0], + symbol, + len, + first_symbol_flag, + nb_rb, beamforming_mode); } break; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c index 68a206e7c746ec709312e4cb29bee5e7824ff4c3..a064a91d87eaee53622854dbecb986eadcd69ccb 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_llr_computation.c @@ -629,16 +629,16 @@ __m128i tmp_result4 __attribute__ ((aligned(16))); //---------------------------------------------------------------------------------------------- int nr_dlsch_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms, - int32_t **rxdataF_comp, + int32_t *rxdataF_comp, int16_t *dlsch_llr, uint8_t symbol, - uint32_t len, - uint8_t first_symbol_flag, + uint32_t len, + uint8_t first_symbol_flag, uint16_t nb_rb, uint8_t beamforming_mode) { - uint32_t *rxF = (uint32_t*)&rxdataF_comp[0][((int32_t)symbol*nb_rb*12)]; + uint32_t *rxF = (uint32_t *)&rxdataF_comp[((int32_t)symbol*nb_rb*12)]; uint32_t *llr32; int i; @@ -670,24 +670,23 @@ int nr_dlsch_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms, //---------------------------------------------------------------------------------------------- void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms, - int32_t **rxdataF_comp, + int32_t *rxdataF_comp, int16_t *dlsch_llr, - int32_t **dl_ch_mag, + int32_t *dl_ch_mag, uint8_t symbol, - uint32_t len, + uint32_t len, uint8_t first_symbol_flag, uint16_t nb_rb, - int16_t **llr32p, uint8_t beamforming_mode) { #if defined(__x86_64__) || defined(__i386__) - __m128i *rxF = (__m128i*)&rxdataF_comp[0][(symbol*nb_rb*12)]; + __m128i *rxF = (__m128i*)&rxdataF_comp[(symbol*nb_rb*12)]; __m128i *ch_mag; __m128i llr128[2]; uint32_t *llr32; #elif defined(__arm__) - int16x8_t *rxF = (int16x8_t*)&rxdataF_comp[0][(symbol*nb_rb*12)]; + int16x8_t *rxF = (int16x8_t*)&rxdataF_comp[(symbol*nb_rb*12)]; int16x8_t *ch_mag; int16x8_t xmm0; int16_t *llr16; @@ -699,30 +698,17 @@ void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms, #if defined(__x86_64__) || defined(__i386__) - if (first_symbol_flag==1) { llr32 = (uint32_t*)dlsch_llr; - } else { - llr32 = (uint32_t*)*llr32p; - } #elif defined(__arm__) - if (first_symbol_flag==1) { llr16 = (int16_t*)dlsch_llr; - } else { - llr16 = (int16_t*)*llr32p; - } #endif #if defined(__x86_64__) || defined(__i386__) - ch_mag = (__m128i*)&dl_ch_mag[0][(symbol*nb_rb*12)]; + ch_mag = (__m128i*)&dl_ch_mag[(symbol*nb_rb*12)]; #elif defined(__arm__) - ch_mag = (int16x8_t*)&dl_ch_mag[0][(symbol*nb_rb*12)]; + ch_mag = (int16x8_t*)&dl_ch_mag[(symbol*nb_rb*12)]; #endif - // update output pointer according to number of REs in this symbol (<<2 because 4 bits per RE) - if (first_symbol_flag == 1) - *llr32p = dlsch_llr + (len<<2); - else - *llr32p += (len<<2); // printf("len=%d\n", len); len_mod4 = len&3; @@ -786,47 +772,35 @@ void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms, //---------------------------------------------------------------------------------------------- void nr_dlsch_64qam_llr(NR_DL_FRAME_PARMS *frame_parms, - int32_t **rxdataF_comp, + int32_t *rxdataF_comp, int16_t *dlsch_llr, - int32_t **dl_ch_mag, - int32_t **dl_ch_magb, + int32_t *dl_ch_mag, + int32_t *dl_ch_magb, uint8_t symbol, uint32_t len, uint8_t first_symbol_flag, uint16_t nb_rb, - uint32_t llr_offset, uint8_t beamforming_mode) { #if defined(__x86_64__) || defined(__i386__) - __m128i *rxF = (__m128i*)&rxdataF_comp[0][(symbol*nb_rb*12)]; + __m128i *rxF = (__m128i*)&rxdataF_comp[(symbol*nb_rb*12)]; __m128i *ch_mag,*ch_magb; #elif defined(__arm__) - int16x8_t *rxF = (int16x8_t*)&rxdataF_comp[0][(symbol*nb_rb*12)]; + int16x8_t *rxF = (int16x8_t*)&rxdataF_comp[(symbol*nb_rb*12)]; int16x8_t *ch_mag,*ch_magb,xmm1,xmm2; #endif int i,len2; unsigned char len_mod4; - short *llr; int16_t *llr2; - int8_t *pllr_symbol; - - /* - if (first_symbol_flag==1) - llr = dlsch_llr; - else - llr = *llr_save; - */ - llr = dlsch_llr; - pllr_symbol = (int8_t*)dlsch_llr; - pllr_symbol += llr_offset; + llr2 = dlsch_llr; #if defined(__x86_64__) || defined(__i386__) - ch_mag = (__m128i*)&dl_ch_mag[0][(symbol*nb_rb*12)]; - ch_magb = (__m128i*)&dl_ch_magb[0][(symbol*nb_rb*12)]; + ch_mag = (__m128i*)&dl_ch_mag[(symbol*nb_rb*12)]; + ch_magb = (__m128i*)&dl_ch_magb[(symbol*nb_rb*12)]; #elif defined(__arm__) - ch_mag = (int16x8_t*)&dl_ch_mag[0][(symbol*nb_rb*12)]; - ch_magb = (int16x8_t*)&dl_ch_magb[0][(symbol*nb_rb*12)]; + ch_mag = (int16x8_t*)&dl_ch_mag[(symbol*nb_rb*12)]; + ch_magb = (int16x8_t*)&dl_ch_magb[(symbol*nb_rb*12)]; #endif // printf("nr_dlsch_64qam_llr: symbol %d,nb_rb %d, len %d,pbch_pss_sss_adjust %d\n",symbol,nb_rb,len,pbch_pss_sss_adjust); @@ -838,9 +812,6 @@ void nr_dlsch_64qam_llr(NR_DL_FRAME_PARMS *frame_parms, dlsch_llr, pllr_symbol);*/ - llr2 = llr; - llr += (len*6); - len_mod4 =len&3; len2=len>>2; // length in quad words (4 REs) len2+=((len_mod4==0)?0:1); @@ -1095,43 +1066,29 @@ void nr_dlsch_64qam_llr_SIC(NR_DL_FRAME_PARMS *frame_parms, //---------------------------------------------------------------------------------------------- void nr_dlsch_256qam_llr(NR_DL_FRAME_PARMS *frame_parms, - int32_t **rxdataF_comp, + int32_t *rxdataF_comp, int16_t *dlsch_llr, - int32_t **dl_ch_mag, - int32_t **dl_ch_magb, - int32_t **dl_ch_magr, + int32_t *dl_ch_mag, + int32_t *dl_ch_magb, + int32_t *dl_ch_magr, uint8_t symbol, uint32_t len, uint8_t first_symbol_flag, uint16_t nb_rb, - uint32_t llr_offset, uint8_t beamforming_mode) { - __m128i *rxF = (__m128i*)&rxdataF_comp[0][(symbol*nb_rb*12)]; + __m128i *rxF = (__m128i*)&rxdataF_comp[(symbol*nb_rb*12)]; __m128i *ch_mag,*ch_magb,*ch_magr; int i,len2; unsigned char len_mod4; - short *llr; int16_t *llr2; - int8_t *pllr_symbol; - - /* - if (first_symbol_flag==1) - llr = dlsch_llr; - else - llr = *llr_save; - */ - llr = dlsch_llr; - pllr_symbol = (int8_t*)dlsch_llr; - pllr_symbol += llr_offset; + llr2 = dlsch_llr; - ch_mag = (__m128i*)&dl_ch_mag[0][(symbol*nb_rb*12)]; - ch_magb = (__m128i*)&dl_ch_magb[0][(symbol*nb_rb*12)]; - ch_magr = (__m128i*)&dl_ch_magr[0][(symbol*nb_rb*12)]; - llr2 = llr; - llr += (len*8); + ch_mag = (__m128i*)&dl_ch_mag[(symbol*nb_rb*12)]; + ch_magb = (__m128i*)&dl_ch_magb[(symbol*nb_rb*12)]; + ch_magr = (__m128i*)&dl_ch_magr[(symbol*nb_rb*12)]; len_mod4 =len&3; len2=len>>2; // length in quad words (4 REs) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c index 0d372deedf5f94ccbeed8bf3c29a1839bd0f07a6..e7cf3c15a913a3127a1516c9a80fc583d09f62b9 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c @@ -66,7 +66,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ uint8_t Mod_id, fd_occasion, preamble_index, restricted_set, not_found; uint16_t rootSequenceIndex, prach_fmt_id, NCS, *prach_root_sequence_map, preamble_offset = 0; - uint16_t preamble_shift = 0, preamble_index0, n_shift_ra, n_shift_ra_bar, d_start=0, numshift, N_ZC, u, offset, offset2, first_nonzero_root_idx; + uint16_t preamble_shift = 0, preamble_index0, n_shift_ra, n_shift_ra_bar, d_start=INT16_MAX, numshift, N_ZC, u, offset, offset2, first_nonzero_root_idx; int16_t prach_tmp[98304*2*4] __attribute__((aligned(32))); int16_t Ncp = 0, amp, *prach, *prach2, *prachF, *Xu; @@ -218,12 +218,12 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ k *= 2; LOG_I(PHY, "PRACH [UE %d] in slot %d, placing PRACH in position %d, msg1 frequency start %d (k1 %d), preamble_offset %d, first_nonzero_root_idx %d\n", Mod_id, - slot, - k, - n_ra_prb, - nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].k1, - preamble_offset, - first_nonzero_root_idx); + slot, + k, + n_ra_prb, + nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].k1, + preamble_offset, + first_nonzero_root_idx); Xu = (int16_t*)ue->X_u[preamble_offset-first_nonzero_root_idx]; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index 1e7e10def70891889b033605743d55b403711e95..eb56c76366b1a855affd2d438bca4666b81a2349 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -471,7 +471,7 @@ int nr_dlsch_64qam_64qam_llr(NR_DL_FRAME_PARMS *frame_parms, @param beamforming_mode beamforming mode */ int32_t nr_dlsch_qpsk_llr(NR_DL_FRAME_PARMS *frame_parms, - int32_t **rxdataF_comp, + int32_t *rxdataF_comp, int16_t *dlsch_llr, uint8_t symbol, uint32_t len, @@ -505,14 +505,13 @@ int32_t nr_dlsch_qpsk_llr_SIC(NR_DL_FRAME_PARMS *frame_parms, uint32_t rb_alloc); void nr_dlsch_16qam_llr(NR_DL_FRAME_PARMS *frame_parms, - int32_t **rxdataF_comp, + int32_t *rxdataF_comp, int16_t *dlsch_llr, - int32_t **dl_ch_mag, + int32_t *dl_ch_mag, uint8_t symbol, - uint32_t len, + uint32_t len, uint8_t first_symbol_flag, uint16_t nb_rb, - int16_t **llr32p, uint8_t beamforming_mode); /** \brief This function generates log-likelihood ratios (decoder input) for single-stream 16QAM received waveforms @@ -553,28 +552,26 @@ void dlsch_64qam_llr_SIC(NR_DL_FRAME_PARMS *frame_parms, uint32_t rb_alloc); void nr_dlsch_64qam_llr(NR_DL_FRAME_PARMS *frame_parms, - int32_t **rxdataF_comp, + int32_t *rxdataF_comp, int16_t *dlsch_llr, - int32_t **dl_ch_mag, - int32_t **dl_ch_magb, + int32_t *dl_ch_mag, + int32_t *dl_ch_magb, uint8_t symbol, - uint32_t len, + uint32_t len, uint8_t first_symbol_flag, uint16_t nb_rb, - uint32_t llr_offset, uint8_t beamforming_mode); void nr_dlsch_256qam_llr(NR_DL_FRAME_PARMS *frame_parms, - int32_t **rxdataF_comp, + int32_t *rxdataF_comp, int16_t *dlsch_llr, - int32_t **dl_ch_mag, - int32_t **dl_ch_magb, - int32_t **dl_ch_magr, + int32_t *dl_ch_mag, + int32_t *dl_ch_magb, + int32_t *dl_ch_magr, uint8_t symbol, uint32_t len, uint8_t first_symbol_flag, uint16_t nb_rb, - uint32_t llr_offset, uint8_t beamforming_mode); /** \fn dlsch_siso(NR_DL_FRAME_PARMS *frame_parms, @@ -807,7 +804,7 @@ void nr_dlsch_channel_compensation(int32_t **rxdataF_ext, NR_DL_FRAME_PARMS *frame_parms, uint8_t nb_aatx, uint8_t symbol, - uint8_t start_symbol, + int length, uint8_t first_symbol_flag, uint8_t mod_order, uint16_t nb_rb, @@ -891,13 +888,15 @@ void nr_dlsch_channel_level_median(int **dl_ch_estimates_ext, int start_point); void nr_dlsch_detection_mrc(int **rxdataF_comp, - int ***rho, - int **dl_ch_mag, - int **dl_ch_magb, - short n_tx, - short n_rx, - unsigned char symbol, - unsigned short nb_rb); + int ***rho, + int **dl_ch_mag, + int **dl_ch_magb, + int **dl_ch_magr, + short n_tx, + short n_rx, + unsigned char symbol, + unsigned short nb_rb, + int length); void nr_dlsch_detection_mrc_core(int **rxdataF_comp, int **rxdataF_comp_i, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index 8f3d1987bcf1a587fdbb449731c59ea70c7cd579..5733ef6eb3c3595481bdc9757a5877140e70e970 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -40,6 +40,7 @@ #include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "LAYER2/NR_MAC_gNB/mac_proto.h" +#include <openair2/UTIL/OPT/opt.h> //#define DEBUG_ULSCH_CODING @@ -256,7 +257,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, Ilbrm = 0; Tbslbrm = 950984; //max tbs Coderate = 0.0; - + trace_NRpdu(DIRECTION_UPLINK, harq_process->a, harq_process->pusch_pdu.pusch_data.tb_size, 0, WS_C_RNTI, 0, 0, 0,0, 0); /////////// ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index fae6b5b2e79c4c3570d27420d414fc469b66d40b..bab801e0e36c3aad81b9309e050354b839effb06 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -114,7 +114,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, NR_DL_FRAME_PARMS *frame_parms = &UE->frame_parms; NR_UE_PUSCH *pusch_ue = UE->pusch_vars[thread_id][gNB_id]; - // ptrs_UplinkConfig_t *ptrs_Uplink_Config = &UE->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig; uint8_t num_of_codewords = 1; // tmp assumption int Nid_cell = 0; diff --git a/openair1/PHY/TOOLS/calibration_test.c b/openair1/PHY/TOOLS/calibration_test.c index 982ca9d254cb47caf105f82a5b2d864d4feaa95b..53baf83d41dbaab0834f88219300ce6fabfe4c43 100644 --- a/openair1/PHY/TOOLS/calibration_test.c +++ b/openair1/PHY/TOOLS/calibration_test.c @@ -10,12 +10,17 @@ unsigned int mmapped_dma=0; int single_thread_flag; uint32_t timing_advance; int8_t threequarter_fs; -int usrp_tx_thread; uint64_t downlink_frequency[MAX_NUM_CCs][4]; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; int opp_enabled; static double snr_dB=20; THREAD_STRUCT thread_struct; +uint32_t target_ul_mcs = 9; +uint32_t target_dl_mcs = 9; +uint64_t dlsch_slot_bitmap = (1<<1); +uint64_t ulsch_slot_bitmap = (1<<8); +uint32_t target_ul_bw = 50; +uint32_t target_dl_bw = 50; #include <executables/nr-softmodem.h> int read_recplayconfig(recplay_conf_t **recplay_conf, recplay_state_t **recplay_state) {return 0;} @@ -302,6 +307,9 @@ int main(int argc, char **argv) { void ** samplesRx = (void **)malloc16(antennas* sizeof(struct complex16 *) ); void ** samplesTx = (void **)malloc16(antennas* sizeof(struct complex16 *) ); + + int fd=open(getenv("rftestInputFile"),O_RDONLY); + AssertFatal(fd>=0,"%s",strerror(errno)); for (int i=0; i<antennas; i++) { samplesRx[i] = (int32_t *)malloc16_clear( DFT*sizeof(struct complex16) ); @@ -313,14 +321,16 @@ int main(int argc, char **argv) { rfdevice.trx_start_func(&rfdevice); while(!oai_exit) { + for (int i=0; i<antennas; i++) + read(fd, samplesTx[i], DFT*sizeof(struct complex16)); int readBlockSize = rfdevice.trx_read_func(&rfdevice, ×tamp, - samplesTx, + samplesRx, DFT, antennas); int txs = rfdevice.trx_write_func(&rfdevice, timestamp+TxAdvanceInDFTSize*DFT, - samplesRx, + samplesTx, DFT, antennas, 0); diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index e3c0737838005c222b833a0d4b6e8d8aa3f56633..0625c6b05022c86a959818b797ebdb0db8b8a73f 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -963,25 +963,9 @@ typedef struct { //#if defined(UPGRADE_RAT_NR) #if 1 - SystemInformationBlockType1_nr_t systemInformationBlockType1_nr; - - CellGroupConfig_t cell_group_config; - PDSCH_ServingCellConfig_t PDSCH_ServingCellConfig; - PDSCH_Config_t PDSCH_Config; - PUCCH_ConfigCommon_nr_t pucch_config_common_nr[NUMBER_OF_CONNECTED_gNB_MAX]; PUCCH_Config_t pucch_config_dedicated_nr[NUMBER_OF_CONNECTED_gNB_MAX]; - - PUSCH_Config_t pusch_config; - SRS_NR srs; - - crossCarrierSchedulingConfig_t crossCarrierSchedulingConfig; - supplementaryUplink_t supplementaryUplink; - dmrs_DownlinkConfig_t dmrs_DownlinkConfig; - csi_MeasConfig_t csi_MeasConfig; - PUSCH_ServingCellConfig_t PUSCH_ServingCellConfig; - #endif uint8_t ncs_cell[20][7]; diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index d1d69ecabe8c9682c4fd453af587a4ebcfe40b4c..d333732d1fdbadb64e0a491e88177c493277e855 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -93,18 +93,18 @@ #define NR_MAX_CSET_DURATION 3 #define NR_MAX_NB_RBG 18 -#define NR_MAX_NB_LAYERS 8 // SU-MIMO (3GPP TS 38.211 V15.4.0 section 7.3.1.3) +#define NR_MAX_NB_LAYERS 2 // 8 // SU-MIMO (3GPP TS 38.211 V15.4.0 section 7.3.1.3) #define NR_MAX_NB_CODEWORDS 2 #define NR_MAX_NB_HARQ_PROCESSES 16 -#define NR_MAX_PDSCH_ENCODED_LENGTH NR_MAX_NB_RB*NR_SYMBOLS_PER_SLOT*NR_NB_SC_PER_RB*8*NR_MAX_NB_LAYERS // 8 is the maximum modulation order (it was 950984 before !!) +#define NR_MAX_PDSCH_ENCODED_LENGTH (NR_MAX_NB_RB*NR_SYMBOLS_PER_SLOT*NR_NB_SC_PER_RB*8*NR_MAX_NB_LAYERS) // 8 is the maximum modulation order (it was 950984 before !!) #define NR_MAX_PUSCH_ENCODED_LENGTH NR_MAX_PDSCH_ENCODED_LENGTH #define NR_MAX_PDSCH_TBS 3824 #define NR_MAX_SIB_LENGTH 2976 // 3GPP TS 38.331 section 5.2.1 - The physical layer imposes a limit to the maximum size a SIB can take. The maximum SIB1 or SI message size is 2976 bits. -#define MAX_NUM_NR_DLSCH_SEGMENTS 34 +#define MAX_NUM_NR_DLSCH_SEGMENTS (NR_MAX_NB_LAYERS*34) #define MAX_NR_DLSCH_PAYLOAD_BYTES (MAX_NUM_NR_DLSCH_SEGMENTS*1056) -#define MAX_NUM_NR_ULSCH_SEGMENTS MAX_NUM_NR_DLSCH_SEGMENTS +#define MAX_NUM_NR_ULSCH_SEGMENTS 34 #define MAX_NR_ULSCH_PAYLOAD_BYTES (MAX_NUM_NR_ULSCH_SEGMENTS*1056) #define MAX_NUM_NR_CHANNEL_BITS (14*273*12*8) // 14 symbols, 273 RB diff --git a/openair1/PHY/impl_defs_nr.h b/openair1/PHY/impl_defs_nr.h index a74c3675a445a65da95b4d5287e4ca5df23fe6b7..93dbf513e85e0c1a944df3e3de4d8a1bbc5ed1f0 100644 --- a/openair1/PHY/impl_defs_nr.h +++ b/openair1/PHY/impl_defs_nr.h @@ -339,124 +339,22 @@ typedef struct { * ************************************************************************/ -/* FFS TODO_NR partial structure that should be complete */ - -typedef enum { - semiStatic = 0, - dynamic = 1 -} pdsch_HARQ_ACK_Codebook_t; - - -////////////////////////////////////////////////////////////////////////////////################################ #define MAX_NR_RATE_MATCH_PATTERNS 4 #define MAX_NR_ZP_CSI_RS_RESOURCES 32 #define MAX_NR_OF_DL_ALLOCATIONS 16 #define MAX_NR_OF_UL_ALLOCATIONS (16) -typedef enum{ - dl_resourceAllocationType0 = 1, - dl_resourceAllocationType1 = 2, - dl_dynamicSwitch = 3 -} dl_resourceAllocation_t; -typedef enum{ - dl_rgb_config1 = 1, - dl_rgb_config2 = 2 -} dl_rgb_Size_t; -typedef enum { - st_n4 = 1, - st_wideband = 2 -} static_bundleSize_t; -typedef enum { - dy_1_n4 = 1, - dy_1_wideband = 2, - dy_1_n2_wideband = 3, - dy_1_n4_wideband = 4 -} bundleSizeSet1_t; -typedef enum { - dy_2_n4 = 1, - dy_2_wideband = 2, -} bundleSizeSet2_t; -typedef struct{ - bundleSizeSet1_t bundleSizeSet1; - bundleSizeSet2_t bundleSizeSet2; -} dynamic_bundleSize_t; -typedef struct { - static_bundleSize_t staticBundling; - dynamic_bundleSize_t dynamicBundlig; -} prb_bundleType_t; typedef enum { - nb_code_n1 = 1, - nb_code_n2 = 2 -} maxNrofCodeWordsScheduledByDCI_t; -typedef struct{ -// to be defined FIXME!!! -}rateMatchPattern_t; -typedef struct{ -// to be defined FIXME!!! -}zp_CSI_RS_Resource_t; - -typedef struct{ - int k0; - int mappingType; - int startSymbolAndLength; - -}PDSCH_TimeDomainResourceAllocation_t; -typedef struct { -/* - * resourceAllocation - */ - dl_resourceAllocation_t dl_resourceAllocation; -/* - * corresponds to I, where I the number of entries in the higher layer parameter pdsch-AllocationList - */ - uint8_t n_pdsh_alloc_list; -/* - * rateMatchPatternToAddModList - */ - rateMatchPattern_t rateMatchPatternToAddModList[MAX_NR_RATE_MATCH_PATTERNS]; -/* - * rateMatchPatternToReleaseList - */ - uint8_t rateMatchPatternToReleaseList[MAX_NR_RATE_MATCH_PATTERNS]; - /* - * n_rateMatchPatterns indicates the number of rateMatchPatterns defined currently - */ - uint8_t n_rateMatchPatterns; - /* - * zp-CSI-RS-ResourceToAddModList - */ - zp_CSI_RS_Resource_t zp_CSI_RS_Resource[MAX_NR_ZP_CSI_RS_RESOURCES]; - /* - * zp-CSI-RS-ResourceToReleaseList - */ - uint8_t zp_CSI_RS_ResourceId[MAX_NR_ZP_CSI_RS_RESOURCES]; - /* - * n_zp-CSI-RS-Resource - */ - uint8_t n_zp_CSI_RS_ResourceId; -/* - * rgb_Size - */ - dl_rgb_Size_t dl_rgbSize; -/* - * prb-BundlingType - */ - prb_bundleType_t prbBundleType; -/* - * pdsch-HARQ-ACK-Codebook: this is part of the IE PhysicalCellGroupConfig which is used to configure cell-group specific L1 parameters (TS 38.331) - */ - pdsch_HARQ_ACK_Codebook_t pdsch_HARQ_ACK_Codebook; - ////////////////////////////////////////////////////////////////////////////////################################ - -/* - Maximum number of code words that a single DCI may schedule. This changes the number of MCS/RV/NDI bits in the DCI message from 1 to 2. -*/ - maxNrofCodeWordsScheduledByDCI_t maxNrofCodeWordsScheduledByDCI; - - - PDSCH_TimeDomainResourceAllocation_t *pdsch_TimeDomainResourceAllocation[MAX_NR_OF_DL_ALLOCATIONS]; + typeA = 0, + typeB = 1 +} mappingType_t; -} PDSCH_Config_t; +typedef enum { + pdsch_dmrs_pos0 = 0, + pdsch_dmrs_pos1 = 1, + pdsch_dmrs_pos2 = 2, + pdsch_dmrs_pos3 = 3, +} pdsch_dmrs_AdditionalPosition_t; /*********************************************************************** * @@ -466,128 +364,20 @@ typedef struct { * ************************************************************************/ - -typedef enum { - enable_tpc_accumulation = 0, /* by default it is enable */ - disable_tpc_accumulation = 1 -} tpc_Accumulation_t; - -typedef enum { - typeA = 0, - typeB = 1 -} mappingType_t; - -typedef struct { - tpc_Accumulation_t tpc_Accumulation; -} PUSCH_PowerControl_t; - -typedef struct { - - uint8_t k2; - mappingType_t mappingType; - uint8_t startSymbolAndLength; -} PUSCH_TimeDomainResourceAllocation_t; -////////////////////////////////////////////////////////////////////////////////################################ -typedef enum{ - maxCodeBlockGroupsPerTransportBlock_n2 = 2, - maxCodeBlockGroupsPerTransportBlock_n4 = 4, - maxCodeBlockGroupsPerTransportBlock_n6 = 6, - maxCodeBlockGroupsPerTransportBlock_n8 = 8 -} maxCodeBlockGroupsPerTransportBlock_t; -typedef struct{ // The IE PUSCH-ServingCellConfig is used to configure UE specific PUSCH parameters that are common across the UE's BWPs of one serving cell - maxCodeBlockGroupsPerTransportBlock_t maxCodeBlockGroupsPerTransportBlock; -} PUSCH_ServingCellConfig_t; -typedef struct{ // CSI-MeasConfig IE is used to configure CSI-RS (reference signals) - uint8_t reportTriggerSize; -} csi_MeasConfig_t; -typedef enum { - pdsch_dmrs_type1 = 0, - pdsch_dmrs_type2 = 1 -} pdsch_dmrs_type_t; typedef enum { pusch_dmrs_type1 = 0, pusch_dmrs_type2 = 1 } pusch_dmrs_type_t; -typedef enum { - pdsch_dmrs_pos0 = 0, - pdsch_dmrs_pos1 = 1, - pdsch_dmrs_pos3 = 3, -} pdsch_dmrs_AdditionalPosition_t; typedef enum { pusch_dmrs_pos0 = 0, pusch_dmrs_pos1 = 1, pusch_dmrs_pos2 = 2, pusch_dmrs_pos3 = 3, } pusch_dmrs_AdditionalPosition_t; -typedef enum { - offset00 = 0, - offset01 = 1, - offset10 = 2, - offset11 = 3, -} ptrs_resource_elementoffset_t; -typedef enum { - pdsch_len1 = 1, - pdsch_len2 = 2 -} pdsch_maxLength_t; typedef enum { pusch_len1 = 1, pusch_len2 = 2 } pusch_maxLength_t; -typedef struct { - uint8_t ptrs_mcs1; - uint8_t ptrs_mcs2; - uint8_t ptrs_mcs3; -} ptrs_time_density_t; -typedef struct { - uint16_t n_rb0; - uint16_t n_rb1; -} ptrs_frequency_density_t; -typedef struct { // The IE PTRS-UplinkConfig is used to configure uplink Phase-Tracking-Reference-Signals (PTRS) - uint8_t num_ptrs_ports; - ptrs_resource_elementoffset_t resourceElementOffset; - ptrs_time_density_t timeDensity; - ptrs_frequency_density_t frequencyDensity; - uint32_t ul_ptrs_power; -} ptrs_UplinkConfig_t; -typedef struct { // The IE DMRS-DownlinkConfig is used to configure downlink demodulation reference signals for PDSCH - pdsch_dmrs_type_t pdsch_dmrs_type; - pdsch_dmrs_AdditionalPosition_t pdsch_dmrs_AdditionalPosition; - pdsch_maxLength_t pdsch_maxLength; - uint16_t scramblingID0; - uint16_t scramblingID1; -} dmrs_DownlinkConfig_t; -typedef struct { // The IE DMRS-UplinkConfig is used to configure uplink demodulation reference signals for PUSCH - pusch_dmrs_type_t pusch_dmrs_type; - pusch_dmrs_AdditionalPosition_t pusch_dmrs_AdditionalPosition; - pusch_maxLength_t pusch_maxLength; - ptrs_UplinkConfig_t ptrs_UplinkConfig; - uint16_t scramblingID0; - uint16_t scramblingID1; -} dmrs_UplinkConfig_t; -typedef struct { -/* - * Serving cell ID of a PSCell. The PCell of the Master Cell Group uses ID = 0 - */ - uint8_t servCellIndex; -}servCellIndex_t; -typedef struct{ - uint8_t cif_presence; -}own_t; -typedef struct{ - servCellIndex_t scheduling_cell_id; - uint8_t cif_InSchedulingCell; -}other_t; -typedef struct{ - own_t own; - other_t other; -}schedulingCellInfo_t; -typedef struct{ - schedulingCellInfo_t schedulingCellInfo; -} crossCarrierSchedulingConfig_t; -typedef struct{ - // this variable will be filled with '1' if SUL is supported and '0' if SUL is not supported - uint8_t supplementaryUplink; -}supplementaryUplink_t; typedef enum { txConfig_codebook = 1, @@ -628,57 +418,6 @@ typedef struct { betaOffset_type_t betaOffset_type; betaOffset_t betaOffset; } uci_onPusch_t; -typedef struct { -/* - * txConfig - */ - txConfig_t txConfig; -/* - * frequencyHopping - */ - frequencyHopping_t frequencyHopping; -/* - * frequencyHoppingOffsetLists - */ - uint16_t frequencyHoppingOffsetLists[4]; - // n_frequencyHoppingOffsetLists contains the number of offsets listed. We can list up to 4 offsets - uint8_t n_frequencyHoppingOffsetLists; -/* - * resourceAllocation - */ - ul_resourceAllocation_t ul_resourceAllocation; -/* - * DMRS-Uplinkconfig - */ - dmrs_UplinkConfig_t dmrs_UplinkConfig; -/* - * rgb_Size - */ - ul_rgb_Size_t ul_rgbSize; -/* - * corresponds to I, where I the number of entries in the higher layer parameter pusch-AllocationList - */ - uint8_t n_push_alloc_list; -/* - * transformPrecoder - */ -transformPrecoder_t transformPrecoder; -/* - * codebookSubset - */ -codebookSubset_t codebookSubset; -/* - * maxRank - */ -uint8_t maxRank; -/* - * uci_onPusch - */ -uci_onPusch_t uci_onPusch; -////////////////////////////////////////////////////////////////////////////////################################ - PUSCH_PowerControl_t pusch_PowerControl; - PUSCH_TimeDomainResourceAllocation_t *pusch_TimeDomainResourceAllocation[MAX_NR_OF_UL_ALLOCATIONS]; -} PUSCH_Config_t; /*********************************************************************** * @@ -897,150 +636,6 @@ typedef struct { PUCCH_PowerControl_t pucch_PowerControl; } PUCCH_Config_t; -/*********************************************************************** -* -* FUNCTIONALITY : PhysicalCellGroupConfig -* -* DESCRIPTION : Physical cell group configuration -* -************************************************************************/ - -typedef uint16_t RNTI_value_t; - -typedef struct { -/* - -- Enables spatial bundling of HARQ ACKs. It is configured per cell group (i.e. for all the cells within the cell group) for PUCCH - -- reporting of HARQ-ACK. It is only applicable when more than 4 layers are possible to schedule. - -- Corresponds to L1 parameter 'HARQ-ACK-spatial-bundling' (see 38.213, section FFS_Section) - -- Absence indicates that spatial bundling is disabled. -*/ - bool harq_ACK_SpatialBundlingPUCCH; -/* - -- Enables spatial bundling of HARQ ACKs. It is configured per cell group (i.e. for all the cells within the cell group) for PUSCH - -- reporting of HARQ-ACK. It is only applicable when more than 4 layers are possible to schedule. - -- Corresponds to L1 parameter 'HARQ-ACK-spatial-bundling' (see 38.213, section FFS_Section) - -- Absence indicates that spatial bundling is disabled. -*/ - bool harq_ACK_SpatialBundlingPUSCH; -/* - -- The maximum transmit power to be used by the UE in this NR cell group. -*/ - uint8_t p_NR; -/* - -- The PDSCH HARQ-ACK codebook is either semi-static of dynamic. This is applicable to both CA and none CA operation. - -- Corresponds to L1 parameter 'HARQ-ACK-codebook' (see 38.213, section FFS_Section) -*/ - pdsch_HARQ_ACK_Codebook_t pdsch_HARQ_ACK_Codebook; -/* - -- RNTI used for SRS TPC commands on DCI. Corresponds to L1 parameter 'TPC-SRS-RNTI' (see 38.213, section 10) -*/ - RNTI_value_t tpc_SRS_RNTI; -/* - -- RNTI used for PUCCH TPC commands on DCI. Corresponds to L1 parameter 'TPC-PUCCH-RNTI' (see 38.213, section 10). -*/ - RNTI_value_t tpc_PUCCH_RNTI; -/* - -- RNTI used for PUSCH TPC commands on DCI. Corresponds to L1 parameter 'TPC-PUSCH-RNTI' (see 38.213, section 10) -*/ - RNTI_value_t tpc_PUSCH_RNTI; -} PhysicalCellGroupConfig_t; - -/*********************************************************************** -* -* FUNCTIONALITY : CellGroupConfig -* -* DESCRIPTION : Cell Group configuration -* -************************************************************************/ - -/* FFS TODO_NR partial structure that should be complete */ - -typedef struct { -/* - cellGroupId CellGroupId, - - -- Logical Channel configuration and association with radio bearers: - rlc-BearerToAddModList SEQUENCE (SIZE(1..maxLC-ID)) OF RLC-Bearer-Config OPTIONAL, -- Need N - rlc-BearerToReleaseList SEQUENCE (SIZE(1..maxLC-ID)) OF LogicalChannelIdentity OPTIONAL, -- Need N - - -- Parameters applicable for the entire cell group: - mac-CellGroupConfig MAC-CellGroupConfig OPTIONAL, -- Need M -*/ - PhysicalCellGroupConfig_t physicalCellGroupConfig; -/* - -- Serving Cell specific parameters (SpCell and SCells) - spCellConfig SpCellConfig OPTIONAL, -- Need M - sCellToAddModList SEQUENCE (SIZE (1..maxNrofSCells)) OF SCellConfig OPTIONAL, -- Need N - -- List of seconary serving cells to be released (not applicable for SpCells) - sCellToReleaseList SEQUENCE (SIZE (1..maxNrofSCells)) OF SCellIndex OPTIONAL, -- Need N - ... - */ -} CellGroupConfig_t; - -/*********************************************************************** -* -* FUNCTIONALITY : PDSCH_ServingCellConfig -* -* DESCRIPTION : pdsch serving cell configuration -* -************************************************************************/ - -/* FFS TODO_NR partial structure that should be complete */ - -typedef int PDSCH_CodeBlockGroupTransmission_t; /* dummy struct which should be change by correct structure */ - -typedef enum { - xOh6 = 0, - xOh12 = 1, - xOh18 = 2 -} xOverhead_t; - -typedef enum { - n2_dl_harq = 2, - n4_dl_harq = 4, - n6_dl_harq = 6, - n10_dl_harq = 10, - n12_dl_harq = 12, - n16_dl_harq = 16 -} nrofHARQ_ProcessesForPDSCH_t; -typedef enum{ - maxCodeBlockGroupsPerTransportBlock_dl_n2 = 2, - maxCodeBlockGroupsPerTransportBlock_dl_n4 = 4, - maxCodeBlockGroupsPerTransportBlock_dl_n6 = 6, - maxCodeBlockGroupsPerTransportBlock_dl_n8 = 8 -} maxCodeBlockGroupsPerTransportBlock_dl_t; - -typedef struct { -/* - -- Enables and configures code-block-group (CBG) based transmission (see 38.213, section 9.1.1) -*/ - PDSCH_CodeBlockGroupTransmission_t *codeBlockGroupTransmission; -/* - -- Accounts for overhead from CSI-RS, CORESET, etc. If the field is absent, the UE applies value xOh0. - -- Corresponds to L1 parameter 'Xoh-PDSCH' (see 38.214, section 5.1.3.2) -*/ - xOverhead_t xOverhead; -/* - -- The number of HARQ processes to be used on the PDSCH of a serving cell. n2 corresponds to 2 HARQ processes, n4 to 4 HARQ processes - -- and so on. If the field is absent, the UE uses 8 HARQ processes. - -- Corresponds to L1 parameter 'number-HARQ-process-PDSCH' (see 38.214, section REF) -*/ - nrofHARQ_ProcessesForPDSCH_t nrofHARQ_ProcessesForPDSCH; -/* - -- The ID of the serving cell (of the same cell group) to use for PUCCH. - -- If the field is absent, the UE sends the HARQ feedback on the PUCCH of the SpCell of this cell group. -*/ - uint8_t pucch_Cell; -/* - * maxCodeBlockGroupsPerTransportBlock_dl_t - */ - maxCodeBlockGroupsPerTransportBlock_dl_t maxCodeBlockGroupsPerTransportBlock_dl; -/* - * codeBlockGroupFlushIndicator (boolean) - */ - uint8_t codeBlockGroupFlushIndicator; -} PDSCH_ServingCellConfig_t; - /*********************************************************************** * * FUNCTIONALITY : Scheduling Request Configuration (SR) diff --git a/openair1/SCHED_NR/nr_prach_procedures.c b/openair1/SCHED_NR/nr_prach_procedures.c index c95d3dc937b4b02647563f1d994514adc90ffa88..dfc5376ee7813d2aa6136ecc3bc25e0fd64bea41 100644 --- a/openair1/SCHED_NR/nr_prach_procedures.c +++ b/openair1/SCHED_NR/nr_prach_procedures.c @@ -114,22 +114,24 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot) { &max_preamble_delay[0] ); free_nr_prach_entry(gNB,prach_id); - LOG_D(PHY,"[RAPROC] Frame %d, slot %d, occasion %d (prachStartSymbol %d) : Most likely preamble %d, energy %d dB delay %d (prach_energy counter %d)\n", + LOG_D(PHY,"[RAPROC] Frame %d, slot %d, occasion %d (prachStartSymbol %d) : Most likely preamble %d, energy %d.%d dB delay %d (prach_energy counter %d)\n", frame,slot,prach_oc,prachStartSymbol, max_preamble[0], max_preamble_energy[0]/10, + max_preamble_energy[0]%10, max_preamble_delay[0], gNB->prach_energy_counter); if ((gNB->prach_energy_counter == 100) && (max_preamble_energy[0] > gNB->measurements.prach_I0+gNB->prach_thres)) { - LOG_I(PHY,"[gNB %d][RAPROC] Frame %d, slot %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d start symbol %u freq index %u\n", + LOG_I(PHY,"[gNB %d][RAPROC] Frame %d, slot %d Initiating RA procedure with preamble %d, energy %d.%d dB (I0 %d, thres %d), delay %d start symbol %u freq index %u\n", gNB->Mod_id, frame, slot, max_preamble[0], max_preamble_energy[0]/10, max_preamble_energy[0]%10, + gNB->measurements.prach_I0,gNB->prach_thres, max_preamble_delay[0], prachStartSymbol, prach_pdu->num_ra); diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index c8042ecec35682290a85b2577a45eb4c0a35b2ef..827e986f1b20c9e3bded717c95dc4811811ff523 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -197,18 +197,17 @@ void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+j , 1); start_meas(&ru->txdataF_copy_stats); - if (ru->num_gNB == 1){ - gNB = ru->gNB_list[0]; - cfg = &gNB->gNB_config; + AssertFatal(ru->num_gNB==1,"num_gNB>1, help\n"); + gNB = ru->gNB_list[0]; + cfg = &gNB->gNB_config; - for(i=0; i<ru->nb_tx; ++i){ - memcpy((void*)&ru->common.txdataF[i][j*fp->ofdm_symbol_size], - (void*)&gNB->common_vars.txdataF[i][j*fp->ofdm_symbol_size + txdataF_offset], - fp->ofdm_symbol_size*sizeof(int32_t)); + for(i=0; i<ru->nb_tx; ++i){ + memcpy((void*)&ru->common.txdataF[i][j*fp->ofdm_symbol_size], + (void*)&gNB->common_vars.txdataF[i][j*fp->ofdm_symbol_size + txdataF_offset], + fp->ofdm_symbol_size*sizeof(int32_t)); - } + } - }//num_gNB == 1 stop_meas(&ru->txdataF_copy_stats); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+j , 0); @@ -303,19 +302,26 @@ static void *nr_feptx_thread(void *param) { ////////////precoding//////////// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->index+1 , 1); - start_meas(&ru->precoding_stats); - - for(i=0; i<ru->nb_log_antennas; ++i) { - memcpy((void*) &ru->common.beam_id[i][slot*fp->symbols_per_slot+l], - (void*) &ru->gNB_list[0]->common_vars.beam_id[i][slot*fp->symbols_per_slot+l], - (fp->symbols_per_slot>>1)*sizeof(uint8_t)); + if (aa==0 && l==0) start_meas(&ru->precoding_stats); + + if (ru->do_precoding == 1) { + for(i=0; i<ru->nb_log_antennas; ++i) { + memcpy((void*) &ru->common.beam_id[i][slot*fp->symbols_per_slot+l], + (void*) &ru->gNB_list[0]->common_vars.beam_id[i][slot*fp->symbols_per_slot+l], + (fp->symbols_per_slot>>1)*sizeof(uint8_t)); + } } - if (ru->nb_tx == 1 && ru->nb_log_antennas == 1) { - memcpy((void*)&ru->common.txdataF_BF[0][l*fp->ofdm_symbol_size], - (void*)&ru->gNB_list[0]->common_vars.txdataF[0][txdataF_offset + l*fp->ofdm_symbol_size], - (fp->samples_per_slot_wCP>>1)*sizeof(int32_t)); + memcpy((void*)&ru->common.txdataF_BF[0][l*fp->ofdm_symbol_size], + (void*)&ru->gNB_list[0]->common_vars.txdataF[0][txdataF_offset + l*fp->ofdm_symbol_size], + (fp->samples_per_slot_wCP>>1)*sizeof(int32_t)); + } + else if (ru->do_precoding == 0) { + int gNB_tx = ru->gNB_list[0]->frame_parms.nb_antennas_tx; + memcpy((void*)&ru->common.txdataF_BF[aa][l*fp->ofdm_symbol_size], + (void*)&ru->gNB_list[0]->common_vars.txdataF[aa%gNB_tx][txdataF_offset + l*fp->ofdm_symbol_size], + (fp->samples_per_slot_wCP>>1)*sizeof(int32_t)); } else { bw = ru->beam_weights[0]; @@ -331,13 +337,13 @@ static void *nr_feptx_thread(void *param) { txdataF_offset);//here } } - stop_meas(&ru->precoding_stats); + if (aa==0 && l==0) stop_meas(&ru->precoding_stats); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+feptx->index+1 , 0); ////////////FEPTX//////////// - start_meas(&ru->ofdm_mod_stats); + if (aa==0 && l==0) start_meas(&ru->ofdm_mod_stats); nr_feptx0(ru,slot,start,fp->symbols_per_slot>>1,aa); - stop_meas(&ru->ofdm_mod_stats); + if (aa==0 && l==0) stop_meas(&ru->ofdm_mod_stats); if (release_thread(&feptx->mutex_feptx,&feptx->instance_cnt_feptx,"NR feptx thread")<0) break; diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 717487c101539e9ef70814fe053e51060c4aa5c4..550d4c8e31d18bc14d8fcac687f4421097d96c65 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -176,7 +176,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, ul_pdcch_pdu_id>=0 ? &gNB->ul_pdcch_pdu[ul_pdcch_pdu_id].pdcch_pdu.pdcch_pdu : NULL, gNB->nr_gold_pdcch_dmrs[slot], &gNB->common_vars.txdataF[0][txdataF_offset], - AMP, *fp); + AMP, fp); // free up entry in pdcch tables if (pdcch_pdu_id>=0) gNB->pdcch_pdu[pdcch_pdu_id].frame = -1; @@ -686,7 +686,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { gNB->pusch_vars[ULSCH_id]->ulsch_power_tot = gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot; nr_fill_indication(gNB,frame_rx, slot_rx, ULSCH_id, harq_pid, 1); gNB->pusch_vars[ULSCH_id]->DTX=1; - stats->DTX++; + if (stats) stats->DTX++; return 1; } else gNB->pusch_vars[ULSCH_id]->DTX=0; diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index c276de847d1c1e677c56f64f863b3233e0935608..99edbf9a40d0f7907cd531e886734b08284d313c 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -80,31 +80,30 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ } else { + fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu = &dl_config->dl_config_list[i].dlsch_config_pdu.dlsch_config_rel15; + uint8_t current_harq_pid = dlsch_config_pdu->harq_process_nbr; + if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_DLSCH){ dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch[thread_id][0][0]; } else if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH){ dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch_ra[0]; dlsch0->rnti_type = _RA_RNTI_; - dlsch0->harq_processes[dlsch0->current_harq_pid]->status = ACTIVE; + dlsch0->harq_processes[current_harq_pid]->status = ACTIVE; } else if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH){ dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch_SI[0]; dlsch0->rnti_type = _SI_RNTI_; - dlsch0->harq_processes[dlsch0->current_harq_pid]->status = ACTIVE; + dlsch0->harq_processes[current_harq_pid]->status = ACTIVE; } - fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu = &dl_config->dl_config_list[i].dlsch_config_pdu.dlsch_config_rel15; - uint8_t current_harq_pid = dlsch_config_pdu->harq_process_nbr; - NR_DL_UE_HARQ_t *dlsch0_harq; - dlsch0->current_harq_pid = current_harq_pid; dlsch0->active = 1; dlsch0->rnti = dl_config->dl_config_list[i].dlsch_config_pdu.rnti; - dlsch0_harq = dlsch0->harq_processes[current_harq_pid]; LOG_D(PHY,"current_harq_pid = %d\n", current_harq_pid); + NR_DL_UE_HARQ_t *dlsch0_harq = dlsch0->harq_processes[current_harq_pid]; if (dlsch0_harq){ dlsch0_harq->BWPStart = dlsch_config_pdu->BWPStart; @@ -121,7 +120,14 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ dlsch0->g_pucch = dlsch_config_pdu->accumulated_delta_PUCCH; dlsch0_harq->harq_ack.pucch_resource_indicator = dlsch_config_pdu->pucch_resource_id; dlsch0_harq->harq_ack.slot_for_feedback_ack = (slot+dlsch_config_pdu->pdsch_to_harq_feedback_time_ind)%frame_parms.slots_per_frame; - dlsch0_harq->Nl=1; + + //get nrOfLayers from DCI info + uint8_t Nl = 0; + for (i = 0; i < 4; i++) { + if (dlsch_config_pdu->dmrs_ports[i] >= i) Nl += 1; + } + dlsch0_harq->Nl = Nl; + dlsch0_harq->mcs_table=dlsch_config_pdu->mcs_table; dlsch0_harq->harq_ack.rx_status = downlink_harq_process(dlsch0_harq, dlsch0->current_harq_pid, dlsch_config_pdu->ndi, dlsch0->rnti_type); if (dlsch0_harq->status != ACTIVE) { diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index e3d4c54f5aaa809c8de5985bf87131c8b3e38ba8..18ef2f66f46f5e261a9601cf00d691df77f9896e 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -288,7 +288,7 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, void nr_ue_measurement_procedures(uint16_t l, PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - uint8_t eNB_id, + uint8_t gNB_id, uint16_t slot){ NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; @@ -308,7 +308,7 @@ void nr_ue_measurement_procedures(uint16_t l, #if T_TRACER if(slot == 0) - T(T_UE_PHY_MEAS, T_INT(eNB_id), T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(nr_slot_rx), + T(T_UE_PHY_MEAS, T_INT(gNB_id), T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(nr_slot_rx), T_INT((int)(10*log10(ue->measurements.rsrp[0])-ue->rx_total_gain_dB)), T_INT((int)ue->measurements.rx_rssi_dBm[0]), T_INT((int)(ue->measurements.rx_power_avg_dB[0] - ue->measurements.n0_power_avg_dB)), @@ -327,8 +327,8 @@ void nr_ue_measurement_procedures(uint16_t l, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_IN); - //printf("start adjust gain power avg db %d\n", ue->measurements.rx_power_avg_dB[eNB_id]); - phy_adjust_gain_nr (ue,ue->measurements.rx_power_avg_dB[eNB_id],eNB_id); + //printf("start adjust gain power avg db %d\n", ue->measurements.rx_power_avg_dB[gNB_id]); + phy_adjust_gain_nr (ue,ue->measurements.rx_power_avg_dB[gNB_id],gNB_id); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_OUT); @@ -738,12 +738,12 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, } #endif // NR_PDCCH_SCHED -int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_id, PDSCH_t pdsch, NR_UE_DLSCH_t *dlsch0, NR_UE_DLSCH_t *dlsch1) { +int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int gNB_id, PDSCH_t pdsch, NR_UE_DLSCH_t *dlsch0, NR_UE_DLSCH_t *dlsch1) { int frame_rx = proc->frame_rx; int nr_slot_rx = proc->nr_slot_rx; int m; - int i_mod,eNB_id_i,dual_stream_UE; + int i_mod,gNB_id_i,dual_stream_UE; int first_symbol_flag=0; if (!dlsch0) @@ -761,14 +761,14 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_ uint16_t s1 = dlsch0_harq->nb_symbols; bool is_SI = dlsch0->rnti_type == _SI_RNTI_; - LOG_D(PHY,"[UE %d] PDSCH type %d active in nr_slot_rx %d, harq_pid %d (%d), rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d, DMRS mask %x\n",ue->Mod_id,pdsch,nr_slot_rx,harq_pid,dlsch0->harq_processes[harq_pid]->status,pdsch_start_rb,pdsch_nb_rb,s0,s1,dlsch0->harq_processes[harq_pid]->dlDmrsSymbPos); + LOG_D(PHY,"[UE %d] PDSCH type %d active in nr_slot_rx %d, harq_pid %d (%d), rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d, DMRS mask %x\n",ue->Mod_id,pdsch,nr_slot_rx,harq_pid,dlsch0_harq->status,pdsch_start_rb,pdsch_nb_rb,s0,s1,dlsch0_harq->dlDmrsSymbPos); for (m = s0; m < (s0 +s1); m++) { - if (((1<<m)&dlsch0->harq_processes[harq_pid]->dlDmrsSymbPos) > 0) { - for (uint8_t aatx=0; aatx<dlsch0->harq_processes[harq_pid]->Nl; aatx++) {//for MIMO Config: it shall loop over no_layers + if (dlsch0_harq->dlDmrsSymbPos & (1 << m)) { + for (uint8_t aatx=0; aatx<dlsch0_harq->Nl; aatx++) {//for MIMO Config: it shall loop over no_layers nr_pdsch_channel_estimation(ue, proc, - 0 /*eNB_id*/, + gNB_id, is_SI, nr_slot_rx, aatx /*p*/, @@ -783,7 +783,7 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_ char filename[100]; for (uint8_t aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) { sprintf(filename,"PDSCH_CHANNEL_frame%d_slot%d_sym%d_port%d_rx%d.m", nr_frame_rx, nr_slot_rx, m, aatx,aarx); - int **dl_ch_estimates = ue->pdsch_vars[proc->thread_id][eNB_id]->dl_ch_estimates; + int **dl_ch_estimates = ue->pdsch_vars[proc->thread_id][gNB_id]->dl_ch_estimates; LOG_M(filename,"channel_F",&dl_ch_estimates[aatx*ue->frame_parms.nb_antennas_rx+aarx][ue->frame_parms.ofdm_symbol_size*m],ue->frame_parms.ofdm_symbol_size, 1, 1); } #endif @@ -796,7 +796,7 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_ uint16_t first_symbol_with_data = s0; uint32_t dmrs_data_re; - if (ue->dmrs_DownlinkConfig.pdsch_dmrs_type == pdsch_dmrs_type1) + if (dlsch0_harq->dmrsConfigType == NFAPI_NR_DMRS_TYPE1) dmrs_data_re = 12 - 6 * dlsch0_harq->n_dmrs_cdm_groups; else dmrs_data_re = 12 - 4 * dlsch0_harq->n_dmrs_cdm_groups; @@ -808,7 +808,7 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_ for (m = s0; m < (s1 + s0); m++) { dual_stream_UE = 0; - eNB_id_i = eNB_id+1; + gNB_id_i = gNB_id+1; i_mod = 0; if (( m==first_symbol_with_data ) && (m<4)) first_symbol_flag = 1; @@ -827,15 +827,15 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_ if (nr_rx_pdsch(ue, proc, pdsch, - eNB_id, - eNB_id_i, + gNB_id, + gNB_id_i, frame_rx, nr_slot_rx, m, first_symbol_flag, dual_stream_UE, i_mod, - dlsch0->current_harq_pid) < 0) + harq_pid) < 0) return -1; } else AssertFatal(1==0,"Not RA_PDSCH, SI_PDSCH or PDSCH\n"); @@ -858,7 +858,7 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - int eNB_id, + int gNB_id, PDSCH_t pdsch, NR_UE_DLSCH_t *dlsch0, NR_UE_DLSCH_t *dlsch1, @@ -878,7 +878,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, fapi_nr_rx_indication_t rx_ind; uint16_t number_pdus = 1; // params for UL time alignment procedure - NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &ue->ul_time_alignment[eNB_id]; + NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &ue->ul_time_alignment[gNB_id]; uint8_t is_cw0_active = dlsch0->harq_processes[harq_pid]->status; uint16_t nb_symb_sch = dlsch0->harq_processes[harq_pid]->nb_symbols; @@ -915,7 +915,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, case RA_PDSCH: case P_PDSCH: case PDSCH: - pdsch_vars = ue->pdsch_vars[proc->thread_id][eNB_id]; + pdsch_vars = ue->pdsch_vars[proc->thread_id][gNB_id]; break; case PMCH: case PDSCH1: @@ -933,8 +933,8 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, *dlsch_errors=0; if (pdsch == RA_PDSCH) { - if (ue->prach_resources[eNB_id]!=NULL) - dlsch0->rnti = ue->prach_resources[eNB_id]->ra_RNTI; + if (ue->prach_resources[gNB_id]!=NULL) + dlsch0->rnti = ue->prach_resources[gNB_id]->ra_RNTI; else { LOG_E(PHY,"[UE %d] Frame %d, nr_slot_rx %d: FATAL, prach_resources is NULL\n", ue->Mod_id, frame_rx, nr_slot_rx); //mac_xface->macphy_exit("prach_resources is NULL"); @@ -975,7 +975,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> Nl %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Nl); LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> G %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->harq_processes[harq_pid]->G); LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> Kmimo %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch0->Kmimo); - LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> Pdcch Sym %d \n", frame_rx, nr_slot_rx, harq_pid, ue->pdcch_vars[proc->thread_id][eNB_id]->num_pdcch_symbols); + LOG_I(PHY,"start ldpc decode for CW 0 for AbsSubframe %d.%d / %d --> Pdcch Sym %d \n", frame_rx, nr_slot_rx, harq_pid, ue->pdcch_vars[proc->thread_id][gNB_id]->num_pdcch_symbols); #endif #if UE_TIMING_TRACE @@ -986,7 +986,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, { ret = nr_dlsch_decoding_mthread(ue, proc, - eNB_id, + gNB_id, pdsch_vars->llr[0], &ue->frame_parms, dlsch0, @@ -1003,7 +1003,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, { ret = nr_dlsch_decoding(ue, proc, - eNB_id, + gNB_id, pdsch_vars->llr[0], &ue->frame_parms, dlsch0, @@ -1061,7 +1061,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> Nl %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->harq_processes[harq_pid]->Nl); LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> G %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->harq_processes[harq_pid]->G); LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> Kmimo %d \n", frame_rx, nr_slot_rx, harq_pid, dlsch1->Kmimo); - LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> Pdcch Sym %d \n", frame_rx, nr_slot_rx, harq_pid, ue->pdcch_vars[proc->thread_id][eNB_id]->num_pdcch_symbols); + LOG_I(PHY,"start ldpc decode for CW 1 for AbsSubframe %d.%d / %d --> Pdcch Sym %d \n", frame_rx, nr_slot_rx, harq_pid, ue->pdcch_vars[proc->thread_id][gNB_id]->num_pdcch_symbols); #endif #if UE_TIMING_TRACE @@ -1072,7 +1072,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, { ret1 = nr_dlsch_decoding_mthread(ue, proc, - eNB_id, + gNB_id, pdsch_vars->llr[1], &ue->frame_parms, dlsch1, @@ -1089,7 +1089,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, { ret1 = nr_dlsch_decoding(ue, proc, - eNB_id, + gNB_id, pdsch_vars->llr[1], &ue->frame_parms, dlsch1, @@ -1131,18 +1131,18 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, switch (pdsch) { case RA_PDSCH: - nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, eNB_id); - nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_RAR, eNB_id, ue, dlsch0, number_pdus); + nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, gNB_id); + nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_RAR, gNB_id, ue, dlsch0, number_pdus); - ue->UE_mode[eNB_id] = RA_RESPONSE; + ue->UE_mode[gNB_id] = RA_RESPONSE; break; case PDSCH: - nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, eNB_id); - nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_DLSCH, eNB_id, ue, dlsch0, number_pdus); + nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, gNB_id); + nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_DLSCH, gNB_id, ue, dlsch0, number_pdus); break; case SI_PDSCH: - nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, eNB_id); - nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SIB, eNB_id, ue, dlsch0, number_pdus); + nr_fill_dl_indication(&dl_indication, NULL, &rx_ind, proc, ue, gNB_id); + nr_fill_rx_indication(&rx_ind, FAPI_NR_RX_PDU_TYPE_SIB, gNB_id, ue, dlsch0, number_pdus); break; default: break; @@ -1156,7 +1156,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, } } - if (ue->mac_enabled == 1) { + if (ue->mac_enabled == 1) { // TODO: move this from PHY to MAC layer! /* Time Alignment procedure // - UE processing capability 1 @@ -1177,11 +1177,60 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, const int Ta_max = 3846; // Max value of 12 bits TA Command const double N_TA_max = Ta_max * bw_scaling * tc_factor; + NR_UE_MAC_INST_t *mac = get_mac_inst(0); + + NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = NULL; + if (mac->ULbwp[0] && + mac->ULbwp[0]->bwp_Dedicated && + mac->ULbwp[0]->bwp_Dedicated->pusch_Config && + mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup && + mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList) { + pusch_TimeDomainAllocationList = mac->ULbwp[0]->bwp_Dedicated->pusch_Config->choice.setup->pusch_TimeDomainAllocationList->choice.setup; + } + else if (mac->ULbwp[0] && + mac->ULbwp[0]->bwp_Common && + mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon && + mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup && + mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) { + pusch_TimeDomainAllocationList = mac->ULbwp[0]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; + } + else if (mac->scc_SIB && + mac->scc_SIB->uplinkConfigCommon && + mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon && + mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup && + mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList) { + pusch_TimeDomainAllocationList = mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; + } + long mapping_type_ul = pusch_TimeDomainAllocationList ? pusch_TimeDomainAllocationList->list.array[0]->mappingType : NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeA; + + NR_PDSCH_Config_t *pdsch_Config = (mac->DLbwp[0] && mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup) ? mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup : NULL; + NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList = NULL; + if (mac->DLbwp[0] && mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList) + pdsch_TimeDomainAllocationList = pdsch_Config->pdsch_TimeDomainAllocationList->choice.setup; + else if (mac->DLbwp[0] && mac->DLbwp[0]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList) + pdsch_TimeDomainAllocationList = mac->DLbwp[0]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; + else if (mac->scc_SIB && mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.pdsch_ConfigCommon->choice.setup) + pdsch_TimeDomainAllocationList = mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; + long mapping_type_dl = pdsch_TimeDomainAllocationList ? pdsch_TimeDomainAllocationList->list.array[0]->mappingType : NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA; + + NR_DMRS_DownlinkConfig_t *NR_DMRS_dlconfig = NULL; + if (pdsch_Config) { + if (mapping_type_dl == NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA) + NR_DMRS_dlconfig = (NR_DMRS_DownlinkConfig_t *)pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup; + else + NR_DMRS_dlconfig = (NR_DMRS_DownlinkConfig_t *)pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup; + } + + pdsch_dmrs_AdditionalPosition_t add_pos_dl = pdsch_dmrs_pos2; + if (NR_DMRS_dlconfig && NR_DMRS_dlconfig->dmrs_AdditionalPosition) + add_pos_dl = *NR_DMRS_dlconfig->dmrs_AdditionalPosition; + /* PDSCH decoding time N_1 for processing capability 1 */ int N_1; - if (ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition == pdsch_dmrs_pos0) + + if (add_pos_dl == pdsch_dmrs_pos0) N_1 = pdsch_N_1_capability_1[numerology][1]; - else if (ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition == pdsch_dmrs_pos1 || ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition == 2) // TODO set to pdsch_dmrs_pos2 when available + else if (add_pos_dl == pdsch_dmrs_pos1 || add_pos_dl == pdsch_dmrs_pos2) N_1 = pdsch_N_1_capability_1[numerology][2]; else N_1 = pdsch_N_1_capability_1[numerology][3]; @@ -1192,8 +1241,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, /* d_1_1 depending on the number of PDSCH symbols allocated */ const int d = 0; // TODO number of overlapping symbols of the scheduling PDCCH and the scheduled PDSCH int d_1_1 = 0; - mappingType_t mapping_type_dl = ue->PDSCH_Config.pdsch_TimeDomainResourceAllocation[0]->mappingType; - if (mapping_type_dl == typeA) + if (mapping_type_dl == NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA) if (nb_symb_sch + start_symbol < 7) d_1_1 = 7 - (nb_symb_sch + start_symbol); else @@ -1208,8 +1256,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, /* d_2_1 */ int d_2_1; - mappingType_t mapping_type_ul = ue->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType; - if (mapping_type_ul == typeB && start_symbol != 0) + if (mapping_type_ul == NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB && start_symbol != 0) d_2_1 = 0; else d_2_1 = 1; @@ -1433,9 +1480,9 @@ void *UE_thread_slot1_dl_processing(void *arg) { #endif // start slave thread for Pdsch Procedure (slot1) // do procedures for C-RNTI - uint8_t eNB_id = 0; + uint8_t gNB_id = 0; - if (ue->dlsch[proc->thread_id][eNB_id][0]->active == 1) { + if (ue->dlsch[proc->thread_id][gNB_id][0]->active == 1) { //wait until first ofdm symbol is processed //wait = 0; //while(proc->first_symbol_available == 0) @@ -1448,9 +1495,9 @@ void *UE_thread_slot1_dl_processing(void *arg) { //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); ue_pdsch_procedures(ue, proc, - eNB_id, + gNB_id, PDSCH, - ue->dlsch[proc->thread_id][eNB_id][0], + ue->dlsch[proc->thread_id][gNB_id][0], NULL, (ue->frame_parms.symbols_per_slot>>1), ue->frame_parms.symbols_per_slot-1, @@ -1460,12 +1507,12 @@ void *UE_thread_slot1_dl_processing(void *arg) { } // do procedures for SI-RNTI - if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) { + if ((ue->dlsch_SI[gNB_id]) && (ue->dlsch_SI[gNB_id]->active == 1)) { ue_pdsch_procedures(ue, proc, - eNB_id, + gNB_id, SI_PDSCH, - ue->dlsch_SI[eNB_id], + ue->dlsch_SI[gNB_id], NULL, (ue->frame_parms.symbols_per_slot>>1), ue->frame_parms.symbols_per_slot-1, @@ -1473,24 +1520,24 @@ void *UE_thread_slot1_dl_processing(void *arg) { } // do procedures for P-RNTI - if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) { + if ((ue->dlsch_p[gNB_id]) && (ue->dlsch_p[gNB_id]->active == 1)) { ue_pdsch_procedures(ue, proc, - eNB_id, + gNB_id, P_PDSCH, - ue->dlsch_p[eNB_id], + ue->dlsch_p[gNB_id], NULL, (ue->frame_parms.symbols_per_slot>>1), ue->frame_parms.symbols_per_slot-1, abstraction_flag); } // do procedures for RA-RNTI - if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1) && (UE_mode != PUSCH)) { + if ((ue->dlsch_ra[gNB_id]) && (ue->dlsch_ra[gNB_id]->active == 1) && (UE_mode != PUSCH)) { ue_pdsch_procedures(ue, proc, - eNB_id, + gNB_id, RA_PDSCH, - ue->dlsch_ra[eNB_id], + ue->dlsch_ra[gNB_id], NULL, (ue->frame_parms.symbols_per_slot>>1), ue->frame_parms.symbols_per_slot-1, @@ -1650,7 +1697,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, #if UE_TIMING_TRACE start_meas(&ue->dlsch_channel_estimation_stats); #endif - nr_pbch_channel_estimation(ue,proc,0,nr_slot_rx,(ue->symbol_offset+i)%(fp->symbols_per_slot),i-1,(fp->ssb_index)&7,fp->half_frame_bit); + nr_pbch_channel_estimation(ue,proc,gNB_id,nr_slot_rx,(ue->symbol_offset+i)%(fp->symbols_per_slot),i-1,(fp->ssb_index)&7,fp->half_frame_bit); #if UE_TIMING_TRACE stop_meas(&ue->dlsch_channel_estimation_stats); #endif @@ -1710,7 +1757,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, if (coreset_nb_rb > 0) nr_pdcch_channel_estimation(ue, proc, - 0, + gNB_id, nr_slot_rx, l, fp->first_carrier_offset+(pdcch_vars->pdcch_config[n_ss].BWPStart + coreset_start_rb)*12, diff --git a/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c b/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c index f43f4d98c99f9c33bd8504b3acd11face872df20..fadfba6bce576d71d1665b930a14095f7da63741 100644 --- a/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c +++ b/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c @@ -158,13 +158,14 @@ int16_t get_pucch_tx_power_ue(PHY_VARS_NR_UE *ue, } } - int k2; - if (power_config->twoPUCCH_PC_AdjustmentStates > 1) { LOG_E(PHY,"PUCCH power control adjustment states with 2 states not yet implemented : at line %d in function %s of file %s \n", LINE_FILE , __func__, __FILE__); return (PUCCH_POWER_DEFAULT); } +#if 0 + int k2; + /* response to a detection by the UE of a DCI format 1_0 or DCI format 1_1 */ //int K_PUCCH = 0; if (O_ACK != 0) { @@ -201,6 +202,7 @@ int16_t get_pucch_tx_power_ue(PHY_VARS_NR_UE *ue, } //K_PUCCH = N_SYMB_SLOT * k2; /* the product of a number of symbols per slot and the minimum of the values provided by higher layer parameter k2 */ } +#endif int contributor = (10 * log10((double)(pow(2,(ue->frame_parms.numerology_index)) * nb_of_prbs))); diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c index 1c0e4e22a1c640d98daff3c1e675c9ec5300a75a..21672fde2f9b69962243932ae03209c77118d01c 100644 --- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c +++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c @@ -549,7 +549,7 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ int occ_length = 0; int occ_Index = 0; int BWPsize = 0; - int BWPstart = 0; + int BWPstart = INT_MAX; NR_UE_HARQ_STATUS_t *harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[dl_harq_pid]->harq_ack; @@ -620,7 +620,9 @@ bool pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, uint8_t gNB_id, UE_nr_rxtx_proc_ mac->ULbwp[bwp_id]->bwp_Dedicated && mac->ULbwp[bwp_id]->bwp_Dedicated->pucch_Config && mac->ULbwp[bwp_id]->bwp_Dedicated->pucch_Config->choice.setup) - pucch_Config = mac->ULbwp[bwp_id]->bwp_Dedicated->pucch_Config->choice.setup; + pucch_Config = mac->ULbwp[bwp_id]->bwp_Dedicated->pucch_Config->choice.setup; + BWPsize = NRRIV2BW(mac->ULbwp[bwp_id]->bwp_Common->genericParameters.locationAndBandwidth,MAX_BWP_SIZE); + BWPstart = NRRIV2PRBOFFSET(mac->ULbwp[bwp_id]->bwp_Common->genericParameters.locationAndBandwidth,MAX_BWP_SIZE); else if (bwp_id==0 && mac->cg && mac->cg->spCellConfig && diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 848b6d4e7507f1afcf25ea625f27672960bcef2a..fb779be09f866feb037943397fa247ce20085a97 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -237,12 +237,12 @@ int oai_nfapi_ul_tti_req(nfapi_nr_ul_tti_request_t *ul_tti_req){ return(0); } // needed for some functions openair0_config_t openair0_cfg[MAX_CARDS]; void update_ptrs_config(NR_CellGroupConfig_t *secondaryCellGroup, uint16_t *rbSize, uint8_t *mcsIndex,int8_t *ptrs_arg); -void update_dmrs_config(NR_CellGroupConfig_t *scg,PHY_VARS_NR_UE *ue, int8_t* dmrs_arg); +void update_dmrs_config(NR_CellGroupConfig_t *scg, int8_t* dmrs_arg); extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration -/* specific dlsim DL preprocessor: uses rbStart/rbSize/mcs from command line of +/* specific dlsim DL preprocessor: uses rbStart/rbSize/mcs/nrOfLayers from command line of dlsim, does not search for CCE/PUCCH occasion but simply sets to 0 */ -int g_mcsIndex = -1, g_mcsTableIdx = 0, g_rbStart = -1, g_rbSize = -1; +int g_mcsIndex = -1, g_mcsTableIdx = 0, g_rbStart = -1, g_rbSize = -1, g_nrOfLayers = 1; void nr_dlsim_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t slot) { @@ -278,6 +278,7 @@ void nr_dlsim_preprocessor(module_id_t module_id, * configuration */ ps->mcsTableIdx = g_mcsTableIdx; + sched_pdsch->nrOfLayers = g_nrOfLayers; sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx); sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx); sched_pdsch->tb_size = nr_compute_tbs(sched_pdsch->Qm, @@ -287,7 +288,7 @@ void nr_dlsim_preprocessor(module_id_t module_id, ps->N_PRB_DMRS * ps->N_DMRS_SLOT, 0 /* N_PRB_oh, 0 for initialBWP */, 0 /* tb_scaling */, - 1 /* nrOfLayers */) + sched_pdsch->nrOfLayers) >> 3; /* the simulator assumes the HARQ PID is equal to the slot number */ @@ -355,7 +356,7 @@ int main(int argc, char **argv) // char fname[40], vname[40]; int trial, n_trials = 1, n_errors = 0, n_false_positive = 0; //int n_errors2, n_alamouti; - uint8_t transmission_mode = 1,n_tx=1,n_rx=1; + uint8_t n_tx=1,n_rx=1; uint8_t round; uint8_t num_rounds = 4; @@ -397,7 +398,7 @@ int main(int argc, char **argv) int8_t enable_ptrs = 0; int8_t modify_dmrs = 0; - int8_t dmrs_arg[2] = {-1,-1};// Invalid values + int8_t dmrs_arg[3] = {-1,-1,-1};// Invalid values /* L_PTRS = ptrs_arg[0], K_PTRS = ptrs_arg[1] */ int8_t ptrs_arg[2] = {-1,-1};// Invalid values @@ -463,6 +464,10 @@ int main(int argc, char **argv) channel_model=ETU; break; + case 'R': + channel_model=Rayleigh1; + break; + default: printf("Unsupported channel model!\n"); exit(-1); @@ -512,12 +517,11 @@ int main(int argc, char **argv) break; */ case 'x': - transmission_mode=atoi(optarg); + g_nrOfLayers=atoi(optarg); - if ((transmission_mode!=1) && - (transmission_mode!=2) && - (transmission_mode!=6)) { - printf("Unsupported transmission mode %d\n",transmission_mode); + if ((g_nrOfLayers!=1) && + (g_nrOfLayers!=2)) { + printf("Unsupported nr Of Layers %d\n",g_nrOfLayers); exit(-1); } @@ -634,7 +638,7 @@ int main(int argc, char **argv) printf("-s Starting SNR, runs from SNR0 to SNR0 + 5 dB. If n_frames is 1 then just SNR is simulated\n"); printf("-S Ending SNR, runs from SNR0 to SNR1\n"); printf("-t Delay spread for multipath channel\n"); - printf("-g [A,B,C,D,E,F,G] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models (ignores delay spread and Ricean factor)\n"); + printf("-g [A,B,C,D,E,F,G,R] Use 3GPP SCM (A,B,C,D) or 36-101 (E-EPA,F-EVA,G-ETU) models or R for MIMO model (ignores delay spread and Ricean factor)\n"); printf("-y Number of TX antennas used in gNB\n"); printf("-z Number of RX antennas used in UE\n"); //printf("-i Relative strength of first intefering gNB (in dB) - cell_id mod 3 = 1\n"); @@ -655,7 +659,7 @@ int main(int argc, char **argv) printf("-q Use 2nd MCS table (256 QAM table) for PDSCH\n"); printf("-t Acceptable effective throughput (in percentage)\n"); printf("-T Enable PTRS, arguments list L_PTRS{0,1,2} K_PTRS{2,4}, e.g. -T 2 0 2 \n"); - printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:2}, e.g. -U 2 0 2 \n"); + printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:2} DMRS ConfType{1:2}, e.g. -U 3 0 2 1 \n"); printf("-P Print DLSCH performances\n"); printf("-w Write txdata to binary file (one frame)\n"); printf("-d number of dlsch threads, 0: no dlsch parallelization\n"); @@ -760,7 +764,7 @@ int main(int argc, char **argv) fix_scd(scd); /* -U option modify DMRS */ if(modify_dmrs) { - update_dmrs_config(secondaryCellGroup, NULL,dmrs_arg); + update_dmrs_config(secondaryCellGroup, dmrs_arg); } /* -T option enable PTRS */ if(enable_ptrs) { @@ -894,9 +898,6 @@ int main(int argc, char **argv) exit(-1); } - if(modify_dmrs) { - update_dmrs_config( NULL,UE,dmrs_arg); - } init_nr_ue_transport(UE,0); nr_gold_pbch(UE); @@ -1138,6 +1139,11 @@ int main(int argc, char **argv) frame_length_complex_samples, 0); + double H_awgn_mimo[4][4] ={{1.0, 0.5, 0.25, 0.125},//rx 0 + {0.5, 1.0, 0.5, 0.25}, //rx 1 + {0.25, 0.5, 1.0, 0.5}, //rx 2 + {0.125, 0.25, 0.5, 1.0}};//rx 3 + for (i=frame_parms->get_samples_slot_timestamp(slot,frame_parms,0); i<frame_parms->get_samples_slot_timestamp(slot+1,frame_parms,0); i++) { @@ -1148,9 +1154,9 @@ int main(int argc, char **argv) // sum up signals from different Tx antennas r_re[aa_rx][i] = 0; r_im[aa_rx][i] = 0; - for (aa=0; aa<n_tx; aa++) { - r_re[aa_rx][i] += s_re[aa][i]; - r_im[aa_rx][i] += s_im[aa][i]; + for (aa=0; aa<n_tx; aa++) { + r_re[aa_rx][i] += s_re[aa][i]*H_awgn_mimo[aa_rx][aa]; + r_im[aa_rx][i] += s_im[aa][i]*H_awgn_mimo[aa_rx][aa]; } } // Add Gaussian noise @@ -1417,10 +1423,12 @@ void update_ptrs_config(NR_CellGroupConfig_t *secondaryCellGroup, uint16_t *rbSi rrc_config_dl_ptrs_params(bwp, ptrsFreqDenst, ptrsTimeDenst, &epre_Ratio, &reOffset); } -void update_dmrs_config(NR_CellGroupConfig_t *scg,PHY_VARS_NR_UE *ue, int8_t* dmrs_arg) +void update_dmrs_config(NR_CellGroupConfig_t *scg, int8_t* dmrs_arg) { int8_t mapping_type = typeA;//default value int8_t add_pos = pdsch_dmrs_pos0;//default value + int8_t dmrs_config_type = NFAPI_NR_DMRS_TYPE1;//default value + if(dmrs_arg[0] == 0) { mapping_type = typeA; } @@ -1437,60 +1445,68 @@ void update_dmrs_config(NR_CellGroupConfig_t *scg,PHY_VARS_NR_UE *ue, int8_t* dm AssertFatal(1==0,"Incorrect Additional Position, valid options 0-pos1, 1-pos1, 2-pos2, 3-pos3\n"); } - if(scg != NULL) { - NR_BWP_Downlink_t *bwp = scg->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[0]; - - AssertFatal((bwp->bwp_Dedicated->pdsch_Config != NULL && bwp->bwp_Dedicated->pdsch_Config->choice.setup != NULL), "Base RRC reconfig structures are not allocated.\n"); - - if (bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA == NULL) { - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA)); - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->present= NR_SetupRelease_DMRS_DownlinkConfig_PR_setup; - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup)); - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type=NULL;//calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type)); - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->maxLength=NULL; - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->scramblingID0=NULL; - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->scramblingID1=NULL; - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS=NULL; - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NULL; - printf("DLSIM: Allocated Mapping TypeA in RRC reconfig message\n"); - } else if (bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB == NULL) { - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB)); - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->present= NR_SetupRelease_DMRS_DownlinkConfig_PR_setup; - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup)); - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_Type=NULL;//calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type)); - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->maxLength=NULL; - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->scramblingID0=NULL; - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->scramblingID1=NULL; - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->phaseTrackingRS=NULL; - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_AdditionalPosition = NULL; - printf("DLSIM: Allocated Mapping TypeB in RRC reconfig message\n"); - } + /* DMRS Conf Type 1 or 2 */ + if(dmrs_arg[2] == 1) { + dmrs_config_type = NFAPI_NR_DMRS_TYPE1; + } else if(dmrs_arg[2] == 2) { + dmrs_config_type = NFAPI_NR_DMRS_TYPE2; + } - struct NR_SetupRelease_DMRS_DownlinkConfig *dmrs_MappingtypeA = bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA; - struct NR_SetupRelease_DMRS_DownlinkConfig *dmrs_MappingtypeB = bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB; + NR_BWP_Downlink_t *bwp = scg->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[0]; + + AssertFatal((bwp->bwp_Dedicated->pdsch_Config != NULL && bwp->bwp_Dedicated->pdsch_Config->choice.setup != NULL), "Base RRC reconfig structures are not allocated.\n"); + + if(mapping_type == typeA) { + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA)); + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->present= NR_SetupRelease_DMRS_DownlinkConfig_PR_setup; + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup)); + if (dmrs_config_type == NFAPI_NR_DMRS_TYPE2) + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type)); + else + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type = NULL; + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->maxLength=NULL; + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->scramblingID0=NULL; + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->scramblingID1=NULL; + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->phaseTrackingRS=NULL; + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NULL; + printf("DLSIM: Allocated Mapping TypeA in RRC reconfig message\n"); + } + if(mapping_type == typeB) { + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB)); + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->present= NR_SetupRelease_DMRS_DownlinkConfig_PR_setup; + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup)); + if (dmrs_config_type == NFAPI_NR_DMRS_TYPE2) + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_Type = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_Type)); + else + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_Type = NULL; + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->maxLength=NULL; + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->scramblingID0=NULL; + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->scramblingID1=NULL; + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->phaseTrackingRS=NULL; + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB->choice.setup->dmrs_AdditionalPosition = NULL; + printf("DLSIM: Allocated Mapping TypeB in RRC reconfig message\n"); + } - NR_DMRS_DownlinkConfig_t *dmrs_config = (mapping_type == typeA) ? dmrs_MappingtypeA->choice.setup : dmrs_MappingtypeB->choice.setup; + struct NR_SetupRelease_DMRS_DownlinkConfig *dmrs_MappingtypeA = bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA; + struct NR_SetupRelease_DMRS_DownlinkConfig *dmrs_MappingtypeB = bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeB; - if (add_pos != 2) { // pos0,pos1,pos3 - if (dmrs_config->dmrs_AdditionalPosition == NULL) { - dmrs_config->dmrs_AdditionalPosition = calloc(1,sizeof(*dmrs_MappingtypeA->choice.setup->dmrs_AdditionalPosition)); - } - *dmrs_config->dmrs_AdditionalPosition = add_pos; - } else { // if NULL, Value pos2 - free(dmrs_config->dmrs_AdditionalPosition); - dmrs_config->dmrs_AdditionalPosition = NULL; - } - for (int i=0;i<bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count;i++) { - bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->mappingType = mapping_type; + NR_DMRS_DownlinkConfig_t *dmrs_config = (mapping_type == typeA) ? dmrs_MappingtypeA->choice.setup : dmrs_MappingtypeB->choice.setup; + + if (add_pos != 2) { // pos0,pos1,pos3 + if (dmrs_config->dmrs_AdditionalPosition == NULL) { + dmrs_config->dmrs_AdditionalPosition = calloc(1,sizeof(*dmrs_MappingtypeA->choice.setup->dmrs_AdditionalPosition)); } + *dmrs_config->dmrs_AdditionalPosition = add_pos; + } else { // if NULL, Value pos2 + free(dmrs_config->dmrs_AdditionalPosition); + dmrs_config->dmrs_AdditionalPosition = NULL; } - if(ue != NULL) { - for (int i=0;i<MAX_NR_OF_DL_ALLOCATIONS;i++) { - ue->PDSCH_Config.pdsch_TimeDomainResourceAllocation[i]->mappingType = mapping_type; - } - ue->dmrs_DownlinkConfig.pdsch_dmrs_AdditionalPosition = add_pos; + + for (int i=0;i<bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count;i++) { + bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->mappingType = mapping_type; } - printf("[DLSIM] DMRS Config is modified with Mapping Type %d, Additional Positions %d \n", dmrs_arg[0], dmrs_arg[1] ); + + printf("[DLSIM] DMRS Config is modified with Mapping Type %d, Additional Positions %d Config. Type %d \n", mapping_type, add_pos, dmrs_config_type); } diff --git a/openair1/SIMULATION/TOOLS/multipath_tv_channel.c b/openair1/SIMULATION/TOOLS/multipath_tv_channel.c index c68ce737580b6ec7ae36763e6138adebbb3f82ce..ece1f81335f4af9393b4a4df37cf08b10918d618 100644 --- a/openair1/SIMULATION/TOOLS/multipath_tv_channel.c +++ b/openair1/SIMULATION/TOOLS/multipath_tv_channel.c @@ -40,9 +40,9 @@ void multipath_tv_channel(channel_desc_t *desc, uint8_t keep_channel) { - double complex **tx,**rx,***H_t,*rx_temp;//, *tv_H_t; + double complex **tx,**rx,***H_t; double path_loss = pow(10,desc->path_loss_dB/20); - int i,j,k,dd; + int i,j,dd; dd = abs(desc->channel_offset); #ifdef DEBUG_CH printf("[TV CHANNEL] keep = %d : path_loss = %g (%f), nb_rx %d, nb_tx %d, dd %d, len %d max_doppler %g\n",keep_channel,path_loss,desc->path_loss_dB,desc->nb_rx,desc->nb_tx,dd,desc->channel_length, @@ -51,8 +51,6 @@ void multipath_tv_channel(channel_desc_t *desc, tx = (double complex **)malloc(desc->nb_tx*sizeof(double complex *)); rx = (double complex **)malloc(desc->nb_rx*sizeof(double complex *)); H_t= (double complex ***) malloc(desc->nb_tx*desc->nb_rx*sizeof(double complex **)); - // tv_H_t = (double complex *) malloc(length*sizeof(double complex)); - rx_temp= (double complex *) calloc(length,sizeof(double complex)); for(i=0; i<desc->nb_tx; i++) { tx[i] = (double complex *)calloc(length,sizeof(double complex)); @@ -84,11 +82,7 @@ void multipath_tv_channel(channel_desc_t *desc, for(i=0; i<desc->nb_rx; i++) { for(j=0; j<desc->nb_tx; j++) { - tv_conv(H_t[i+(j*desc->nb_rx)],tx[j],rx_temp,length,desc->nb_taps,dd); - - for(k=0; k<length; k++) { - rx[i][k] += rx_temp[k]; - } + tv_conv(H_t[i+(j*desc->nb_rx)],tx[j],rx[i],length,desc->nb_taps,dd); } } @@ -99,10 +93,6 @@ void multipath_tv_channel(channel_desc_t *desc, } } - /* for(k=0;k<length;k++) { - tv_H_t[k] = H_t[0][k][0]; - }*/ - for(i=0; i<desc->nb_tx; i++) { free(tx[i]); } @@ -124,7 +114,6 @@ void multipath_tv_channel(channel_desc_t *desc, } free(H_t); - free(rx_temp); } //TODO: make phi_rad a parameter of this function @@ -177,7 +166,7 @@ void tv_channel(channel_desc_t *desc,double complex ***H,uint32_t length){ H[i+(j*desc->nb_rx)][k][l] += sqrt(desc->amps[k])*alpha[p]*cexp(I*(2*pi*w_Hz[i+(j*desc->nb_rx)][k][p]*l*(1/(desc->sampling_rate*1e6))+phi_rad[i+(j*desc->nb_rx)][k][p])); } } - //printf("H[tx%d][rx%d][k%d] = %f+j%f \n",j,i,k,creal(H[i+(j*desc->nb_rx)][k][0]),cimag(H[i+(j*desc->nb_rx)][k][0])); + //printf("H[tx%d][rx%d][k%d][l%d] = %f+j%f \n",j,i,k,0,creal(H[i+(j*desc->nb_rx)][k][0]),cimag(H[i+(j*desc->nb_rx)][k][0])); } } } @@ -201,14 +190,12 @@ void tv_channel(channel_desc_t *desc,double complex ***H,uint32_t length){ } // time varying convolution -void tv_conv(double complex **h, double complex *x, double complex *y, uint32_t nb_samples, uint8_t nb_taps, int dd){ - - int i,j; - - for(i=0; i<((int)nb_samples-dd); i++) { - for(j=0; j<nb_taps; j++) { - if(i>j) - y[i+dd] += creal(h[j][i])*creal(x[i-j])-cimag(h[j][i])*cimag(x[i-j]) + I*(creal(h[j][i])*cimag(x[i-j])+cimag(h[j][i])*creal(x[i-j])); +void tv_conv(double complex **h, double complex *x, double complex *y, uint32_t nb_samples, uint8_t nb_taps, int dd) +{ + for(int i = 0; i < ((int)nb_samples-dd); i++) { + for(int j = 0; j < nb_taps; j++) { + if(i >= j) + y[i+dd] += h[j][i] * x[i-j]; } } } diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h index d425b9e7d7a895eb8696db1b51b7ddfb8f2c47e0..23b33dd8b13ab1f8249942f2e304c5e800d72dd4 100644 --- a/openair2/COMMON/platform_types.h +++ b/openair2/COMMON/platform_types.h @@ -195,21 +195,13 @@ typedef uint8_t mme_code_t; typedef uint32_t m_tmsi_t; //Random UE identity length = 40 bits -#if ! defined(NOT_A_RANDOM_UE_IDENTITY) #define NOT_A_RANDOM_UE_IDENTITY (uint64_t)0xFFFFFFFF -#endif -#if ! defined(NOT_A_RNTI) #define NOT_A_RNTI (rnti_t)0 -#endif -#if ! defined(M_RNTI) #define M_RNTI (rnti_t)0xFFFD -#endif -#if ! defined(P_RNTI) #define P_RNTI (rnti_t)0xFFFE -#endif -#if ! defined(SI_RNTI) #define SI_RNTI (rnti_t)0xFFFF -#endif +#define CBA_RNTI (rnti_t)0xfff4 +#define OAI_C_RNTI (rnti_t)0x1234 typedef enum config_action_e { CONFIG_ACTION_NULL = 0, CONFIG_ACTION_ADD = 1, diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index 64c42eaf0eb8cc7bb7187ea85dcc310493229bd9..220ef60b3ddd3c66c36ea65dd6bc172dd4ee76df 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -405,6 +405,7 @@ typedef struct NRRrcConfigurationReq_s { uint16_t mcc[PLMN_LIST_MAX_SIZE]; uint16_t mnc[PLMN_LIST_MAX_SIZE]; uint8_t mnc_digit_length[PLMN_LIST_MAX_SIZE]; + uint8_t num_plmn; NR_ServingCellConfigCommon_t *scc; NR_ServingCellConfig_t *scd; int ssb_SubcarrierOffset; diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h index f26863414cbc26709c1c54300fc065cfc7274629..79e66881b5c00ddd43a9fae3814bd3b5735a8f69 100644 --- a/openair2/ENB_APP/enb_paramdef.h +++ b/openair2/ENB_APP/enb_paramdef.h @@ -98,6 +98,7 @@ typedef enum { #define CONFIG_STRING_RU_BF_WEIGHTS_LIST "bf_weights" #define CONFIG_STRING_RU_IF_FREQUENCY "if_freq" #define CONFIG_STRING_RU_IF_FREQ_OFFSET "if_offset" +#define CONFIG_STRING_RU_DO_PRECODING "do_precoding" #define RU_LOCAL_IF_NAME_IDX 0 #define RU_LOCAL_ADDRESS_IDX 1 @@ -127,7 +128,7 @@ typedef enum { #define RU_BF_WEIGHTS_LIST_IDX 25 #define RU_IF_FREQUENCY 26 #define RU_IF_FREQ_OFFSET 27 - +#define RU_DO_PRECODING 28 /*-----------------------------------------------------------------------------------------------------------------------------------------*/ /* RU configuration parameters */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ @@ -160,7 +161,8 @@ typedef enum { {CONFIG_STRING_RU_OTA_SYNC_ENABLE, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \ {CONFIG_STRING_RU_BF_WEIGHTS_LIST, NULL, 0, iptr:NULL, defintarrayval:DEFBFW, TYPE_INTARRAY, 0}, \ {CONFIG_STRING_RU_IF_FREQUENCY, NULL, 0, u64ptr:NULL, defuintval:0, TYPE_UINT64, 0}, \ - {CONFIG_STRING_RU_IF_FREQ_OFFSET, NULL, 0, iptr:NULL, defintval:0, TYPE_INT, 0}, \ + {CONFIG_STRING_RU_IF_FREQ_OFFSET, NULL, 0, iptr:NULL, defintval:0, TYPE_INT, 0}, \ + {CONFIG_STRING_RU_DO_PRECODING, NULL, 0, iptr:NULL, defintval:0, TYPE_INT, 0}, \ } /*---------------------------------------------------------------------------------------------------------------------------------------*/ diff --git a/openair2/F1AP/dummy_enb.c b/openair2/F1AP/dummy_enb.c index ee98b9ec4687b3bef354773b40207e111cc25ef6..fe6dfb6a06af9f3130cc418a4136ac6f1e487fc6 100644 --- a/openair2/F1AP/dummy_enb.c +++ b/openair2/F1AP/dummy_enb.c @@ -20,42 +20,15 @@ */ #include "COMMON/platform_types.h" -#include "COMMON/platform_constants.h" #include "common/ran_context.h" - #include "common/utils/LOG/log.h" -#include "common/utils/LOG/vcd_signal_dumper.h" - #include "NR_BCCH-BCH-Message.h" #include "NR_ServingCellConfigCommon.h" - -#include "LAYER2/NR_MAC_gNB/mac_proto.h" -#include "SCHED_NR/phy_frame_config_nr.h" - #include "NR_MIB.h" -#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h" -#include "../../../../nfapi/oai_integration/vendor_ext.h" -/* Softmodem params */ -#include "executables/softmodem-common.h" - -int rrc_mac_config_req_gNB(module_id_t Mod_idP, - int ssb_SubcarrierOffset, - int pdsch_AntennaPorts, - int pusch_AntennaPorts, - NR_ServingCellConfigCommon_t *scc, - int add_ue, - uint32_t rnti, - NR_CellGroupConfig_t *CellGroup){ -abort(); -return 0; -} -rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP, - const NR_SRB_ToAddModList_t * const srb2add_listP, - const NR_DRB_ToAddModList_t * const drb2add_listP, - const NR_DRB_ToReleaseList_t * const drb2release_listP, - const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP, - struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list){ +void apply_macrlc_config(gNB_RRC_INST *rrc, + rrc_gNB_ue_context_t *const ue_context_pP, + const protocol_ctxt_t *const ctxt_pP ) { abort(); -return 0; } + diff --git a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c index 03cfcc73298f89361b4198de52c1e1d476765eba..8a5b9785b50f50c95beea62d6f93cbd540db0724 100644 --- a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c @@ -38,13 +38,6 @@ #include "common/ran_context.h" #include "openair3/UTILS/conversions.h" -// undefine C_RNTI from -// openair1/PHY/LTE_TRANSPORT/transport_common.h which -// replaces in ie->value.choice.C_RNTI, causing -// a compile error -#undef C_RNTI - - // Bing Kai: create CU and DU context, and put all the information there. uint64_t du_ue_f1ap_id = 0; uint32_t f1ap_assoc_id = 0; diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index 317f0058b26323696f0462f6fa7c66832b181ce3..da723ba5a38f8612efb899afb1b2532a8be0d0f3 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -39,8 +39,10 @@ #include "rrc_extern.h" #include "rrc_eNB_UE_context.h" +#include "openair2/RRC/NR/rrc_gNB_UE_context.h" #include "rrc_eNB_S1AP.h" #include "rrc_eNB_GTPV1U.h" +#include "openair2/RRC/NR/rrc_gNB_NGAP.h" extern f1ap_setup_req_t *f1ap_du_data_from_du; extern f1ap_cudu_inst_t f1ap_cu_inst[MAX_eNB]; @@ -1029,35 +1031,55 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, // F1AP_CriticalityDiagnostics_IE_List } - struct rrc_eNB_ue_context_s *ue_context_p = - rrc_eNB_get_ue_context(RC.rrc[instance], rnti); protocol_ctxt_t ctxt; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, instance, ENB_FLAG_YES, rnti, 0, 0, instance); - if (ue_context_p) { - /* The following is normally done in the function rrc_rx_tx() */ - rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_CPLT(instance, - ue_context_p->ue_context.eNB_ue_s1ap_id); - - rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(instance, ue_context_p); - // erase data of GTP tunnels in UE context - for (int e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) { - ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0; - memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab], - 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab])); - ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0; - } + if (RC.nrrrc[instance]->node_type == ngran_gNB_CU) { + struct rrc_gNB_ue_context_s *ue_context_p = + rrc_gNB_get_ue_context(RC.nrrrc[instance], rnti); - struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = - rrc_eNB_S1AP_get_ue_ids(RC.rrc[instance], 0, - ue_context_p->ue_context.eNB_ue_s1ap_id); - if (rrc_ue_s1ap_ids) - rrc_eNB_S1AP_remove_ue_ids(RC.rrc[instance], rrc_ue_s1ap_ids); + if (ue_context_p) { + MessageDef *msg = itti_alloc_new_message(TASK_CU_F1, 0, NGAP_UE_CONTEXT_RELEASE_COMPLETE); + NGAP_UE_CONTEXT_RELEASE_COMPLETE(msg).gNB_ue_ngap_id = ue_context_p->ue_context.gNB_ue_ngap_id; + itti_send_msg_to_task(TASK_NGAP, instance, msg); + + rrc_gNB_remove_ue_context(&ctxt, RC.nrrrc[instance], ue_context_p); + } else { + LOG_E(F1AP, "could not find ue_context of UE RNTI %x\n", rnti); + } +#ifdef ITTI_SIM + return 0; +#endif - /* trigger UE release in RRC */ - rrc_eNB_remove_ue_context(&ctxt, RC.rrc[instance], ue_context_p); } else { - LOG_E(F1AP, "could not find ue_context of UE RNTI %x\n", rnti); + struct rrc_eNB_ue_context_s *ue_context_p = + rrc_eNB_get_ue_context(RC.rrc[instance], rnti); + + if (ue_context_p) { + /* The following is normally done in the function rrc_rx_tx() */ + rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_CPLT(instance, + ue_context_p->ue_context.eNB_ue_s1ap_id); + + rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(instance, ue_context_p); + // erase data of GTP tunnels in UE context + for (int e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) { + ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0; + memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab], + 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab])); + ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0; + } + + struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = + rrc_eNB_S1AP_get_ue_ids(RC.rrc[instance], 0, + ue_context_p->ue_context.eNB_ue_s1ap_id); + if (rrc_ue_s1ap_ids) + rrc_eNB_S1AP_remove_ue_ids(RC.rrc[instance], rrc_ue_s1ap_ids); + + /* trigger UE release in RRC */ + rrc_eNB_remove_ue_context(&ctxt, RC.rrc[instance], ue_context_p); + } else { + LOG_E(F1AP, "could not find ue_context of UE RNTI %x\n", rnti); + } } pdcp_remove_UE(&ctxt); diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index 07df0b4a78748e375394e4f1ac5018cdbf114350..0c8f566fd669fc2e30a189b352cf5e7bc7c8230c 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -56,13 +56,6 @@ #include "intertask_interface.h" #include "LAYER2/NR_MAC_gNB/mac_proto.h" -// undefine C_RNTI from -// openair1/PHY/LTE_TRANSPORT/transport_common.h which -// replaces in ie->value.choice.C_RNTI, causing -// a compile error - -#undef C_RNTI - extern f1ap_setup_req_t *f1ap_du_data; extern RAN_CONTEXT_t RC; extern f1ap_cudu_inst_t f1ap_du_inst[MAX_eNB]; @@ -990,135 +983,6 @@ int DU_send_UL_NR_RRC_MESSAGE_TRANSFER(instance_t instance, msg->rrc_container_length); ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - if (msg->srb_id == 1 || msg->srb_id == 2) { - struct rrc_gNB_ue_context_s* ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[instance], rnti); - - - NR_UL_DCCH_Message_t* ul_dcch_msg=NULL; - asn_dec_rval_t dec_rval; - dec_rval = uper_decode(NULL, - &asn_DEF_NR_UL_DCCH_Message, - (void**)&ul_dcch_msg, - &ie->value.choice.RRCContainer.buf[1], // buf[0] includes the pdcp header - msg->rrc_container_length, 0, 0); - - if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { - LOG_E(F1AP, " Failed to decode UL-DCCH (%zu bytes)\n",dec_rval.consumed); - /* for rfsim, because UE send RRCSetupRequest in SRB1 */ - // NR_UL_CCCH_Message_t *ul_ccch_msg; - // dec_rval = uper_decode(NULL, - // &asn_DEF_NR_UL_CCCH_Message, - // (void**)&ul_ccch_msg, - // &ie->value.choice.RRCContainer.buf[1], // buf[0] includes the pdcp header - // msg->rrc_container_length, 0, 0); - // if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { - // LOG_E(F1AP, " Failed to decode UL-CCCH (%zu bytes)\n",dec_rval.consumed); - // } else { - // LOG_I(F1AP, "decode UL-CCCH success \n"); - // LOG_I(F1AP, "Received message: present %d and c1 present %d\n", - // ul_ccch_msg->message.present, ul_ccch_msg->message.choice.c1->present); - - // if (ul_ccch_msg->message.present == NR_UL_CCCH_MessageType_PR_c1) { - // if (ul_ccch_msg->message.choice.c1->present == NR_UL_CCCH_MessageType__c1_PR_rrcSetupRequest) { - // LOG_I(F1AP, "[MSG] RRC Setup Request\n"); - - // } - // } - // } - } - else - LOG_I(F1AP, "Received message: present %d and c1 present %d\n", - ul_dcch_msg->message.present, ul_dcch_msg->message.choice.c1->present); - - if (ul_dcch_msg->message.present == NR_UL_DCCH_MessageType_PR_c1) { - - switch (ul_dcch_msg->message.choice.c1->present) { - case NR_UL_DCCH_MessageType__c1_PR_NOTHING: /* No components present */ - break; - - case NR_UL_DCCH_MessageType__c1_PR_measurementReport: - break; - - case NR_UL_DCCH_MessageType__c1_PR_rrcReconfigurationComplete: - LOG_I(F1AP, "[MSG] RRC UL rrcReconfigurationComplete\n"); - - /* CDRX: activated when RRC Connection Reconfiguration Complete is received */ -#if(0) - int UE_id_mac = find_nr_UE_id(instance, rnti); - - if (UE_id_mac == -1) { - LOG_E(F1AP, "Can't find UE_id(MAC) of UE rnti %x\n", rnti); - break; - } - - UE_sched_ctrl_t *UE_scheduling_control = &(RC.nrmac[instance]->UE_info.UE_sched_ctrl[UE_id_mac]); - - if (UE_scheduling_control->cdrx_waiting_ack == TRUE) { - UE_scheduling_control->cdrx_waiting_ack = FALSE; - UE_scheduling_control->cdrx_configured = TRUE; // Set to TRUE when RRC Connection Reconfiguration Complete is received - LOG_I(F1AP, "CDRX configuration activated after RRC Connection Reconfiguration Complete reception\n"); - } - /* End of CDRX processing */ -#endif - break; - - case NR_UL_DCCH_MessageType__c1_PR_rrcSetupComplete: - LOG_I(F1AP, "[MSG] RRC UL rrcSetupComplete \n"); - - if(!ue_context_p){ - LOG_E(F1AP, "Did not find the UE context associated with UE RNTOI %x, ue_context_p is NULL\n", rnti); - - } else { - LOG_I(F1AP, "Processing RRCSetupComplete UE %x\n", rnti); - ue_context_p->ue_context.StatusRrc = NR_RRC_CONNECTED; - } - break; - - case NR_UL_DCCH_MessageType__c1_PR_rrcReestablishmentComplete: - LOG_I(F1AP, "[MSG] RRC ReestablishmentComplete \n"); - break; - - case NR_UL_DCCH_MessageType__c1_PR_rrcResumeComplete: - LOG_I(F1AP, "[MSG] RRC ResumeComplete \n"); - break; - - case NR_UL_DCCH_MessageType__c1_PR_securityModeComplete: - LOG_I(F1AP, "[MSG] RRC securityModeComplete \n"); - break; - - case NR_UL_DCCH_MessageType__c1_PR_securityModeFailure: - LOG_I(F1AP, "[MSG] RRC securityModeFailure \n"); - break; - - case NR_UL_DCCH_MessageType__c1_PR_ulInformationTransfer: - LOG_I(F1AP, "[MSG] RRC UL Information Transfer \n"); - break; - - case NR_UL_DCCH_MessageType__c1_PR_locationMeasurementIndication: - break; - - case NR_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation: - LOG_I(F1AP, "[MSG] RRC ueCapabilityInformation \n"); - break; - - case NR_UL_DCCH_MessageType__c1_PR_ueAssistanceInformation: - break; - - case NR_UL_DCCH_MessageType__c1_PR_failureInformation: - break; - - case NR_UL_DCCH_MessageType__c1_PR_scgFailureInformation: - break; - - case NR_UL_DCCH_MessageType__c1_PR_scgFailureInformationEUTRA: - break; - - default: - LOG_E(NR_RRC, "Unknown UL DCCH message type, present %d \n", ul_dcch_msg->message.choice.c1->present); - break; - } - } - } /* encode */ if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { LOG_E(F1AP, "Failed to encode F1 UL RRC MESSAGE TRANSFER \n"); @@ -1252,6 +1116,7 @@ int DU_handle_DL_NR_RRC_MESSAGE_TRANSFER(instance_t instance, RC.nrrrc[ctxt.module_id], ctxt.rnti); + gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; if (srb_id == 0) { NR_DL_CCCH_Message_t* dl_ccch_msg=NULL; asn_dec_rval_t dec_rval; @@ -1295,47 +1160,17 @@ int DU_handle_DL_NR_RRC_MESSAGE_TRANSFER(instance_t instance, rrcSetup_ies->masterCellGroup.size,0,0); AssertFatal(dec_rval.code == RC_OK, "could not decode masterCellGroup\n"); - // configure MAC - gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; - rrc_mac_config_req_gNB(ctxt.module_id, - rrc->carrier.ssb_SubcarrierOffset, - rrc->carrier.pdsch_AntennaPorts, - rrc->carrier.pusch_AntennaPorts, - NULL, - 0, - ue_context_p->ue_context.rnti, - ue_context_p->ue_context.masterCellGroup - ); - - // rrc_rlc_config_asn1_req - nr_rrc_rlc_config_asn1_req(&ctxt, - ue_context_p->ue_context.SRB_configList, - NULL, - NULL, - NULL, - NULL, - NULL); - - // This should be somewhere in the f1ap_cudu_ue_inst_t - /*int macrlc_instance = 0; - - rnti_t rnti = f1ap_get_rnti_by_du_id(&f1ap_du_inst[0], du_ue_f1ap_id); - struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[macrlc_instance],rnti); - */ - gNB_RRC_UE_t *ue_p = &ue_context_p->ue_context; - AssertFatal(ue_p->Srb0.Active == 1,"SRB0 is not active\n"); + apply_macrlc_config(rrc,ue_context_p,&ctxt); - memcpy((void*)ue_p->Srb0.Tx_buffer.Payload, - (void*)ie->value.choice.RRCContainer.buf, - rrc_dl_sdu_len); // ie->value.choice.RRCContainer.size + gNB_RRC_UE_t *ue_p = &ue_context_p->ue_context; + AssertFatal(ue_p->Srb0.Active == 1,"SRB0 is not active\n"); - ue_p->Srb0.Tx_buffer.payload_size = rrc_dl_sdu_len; + memcpy((void*)ue_p->Srb0.Tx_buffer.Payload, + (void*)ie->value.choice.RRCContainer.buf, + rrc_dl_sdu_len); // ie->value.choice.RRCContainer.size - // NR_MAC_CellGroupConfig_t *mac_CellGroupConfig = NULL; - // if (cellGroupConfig->mac_CellGroupConfig) - // mac_CellGroupConfig = cellGroupConfig->mac_CellGroupConfig; + ue_p->Srb0.Tx_buffer.payload_size = rrc_dl_sdu_len; - // rrc_mac_config_req_gNB break; } // case diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index b79e9feb588077dd800c2d7791a39ebbbaa6e456..131dbce8efad12aa46f060c12ee2f51b4ba62e8a 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -38,13 +38,8 @@ #include "rrc_extern.h" #include "rrc_eNB_UE_context.h" - -// undefine C_RNTI from -// openair1/PHY/LTE_TRANSPORT/transport_common.h which -// replaces in ie->value.choice.C_RNTI, causing -// a compile error - -#undef C_RNTI +#include "openair2/RRC/NR/rrc_gNB_UE_context.h" +#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h" extern f1ap_setup_req_t *f1ap_du_data; extern f1ap_cudu_inst_t f1ap_du_inst[MAX_eNB]; @@ -664,11 +659,21 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, rnti, ctxt.rnti); int UE_out_of_sync = 0; - for (int n = 0; n < MAX_MOBILES_PER_ENB; ++n) { - if (RC.mac[instance]->UE_info.active[n] == TRUE - && rnti == UE_RNTI(instance, n)) { - UE_out_of_sync = RC.mac[instance]->UE_info.UE_sched_ctrl[n].ul_out_of_sync; - break; + if (RC.nrrrc[instance]->node_type == ngran_gNB_DU) { + for (int n = 0; n < MAX_MOBILES_PER_GNB; ++n) { + if (RC.nrmac[instance]->UE_info.active[n] == TRUE + && rnti == RC.nrmac[instance]->UE_info.rnti[n]) { + UE_out_of_sync = 0; + break; + } + } + } else { + for (int n = 0; n < MAX_MOBILES_PER_ENB; ++n) { + if (RC.mac[instance]->UE_info.active[n] == TRUE + && rnti == UE_RNTI(instance, n)) { + UE_out_of_sync = RC.mac[instance]->UE_info.UE_sched_ctrl[n].ul_out_of_sync; + break; + } } } @@ -718,6 +723,15 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, } } + if (RC.nrrrc[instance]->node_type == ngran_gNB_DU) { + // struct rrc_gNB_ue_context_s *ue_context_p; + + f1ap_ue_context_release_cplt_t cplt; + cplt.rnti = ctxt.rnti; + DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance, &cplt); + return 0; + } + struct rrc_eNB_ue_context_s *ue_context_p; ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt.module_id], ctxt.rnti); diff --git a/openair2/GNB_APP/L1_nr_paramdef.h b/openair2/GNB_APP/L1_nr_paramdef.h index fd22e9273023542aa0376c551078dee85f10be80..fc2bca19d5e25718e1c464e17da62565d353b541 100644 --- a/openair2/GNB_APP/L1_nr_paramdef.h +++ b/openair2/GNB_APP/L1_nr_paramdef.h @@ -66,7 +66,7 @@ {CONFIG_STRING_L1_REMOTE_N_PORTD, NULL, 0, uptr:NULL, defintval:50031, TYPE_UINT, 0}, \ {CONFIG_STRING_L1_PUSCH_PROC_THREADS, NULL, 0, uptr:NULL, defintval:1, TYPE_UINT, 0}, \ {CONFIG_STRING_L1_PUCCH0_DTX_THRESHOLD, NULL, 0, uptr:NULL, defintval:100, TYPE_UINT, 0}, \ -{CONFIG_STRING_L1_PRACH_DTX_THRESHOLD, NULL, 0, uptr:NULL, defintval:200, TYPE_UINT, 0}, \ +{CONFIG_STRING_L1_PRACH_DTX_THRESHOLD, NULL, 0, uptr:NULL, defintval:150, TYPE_UINT, 0}, \ {CONFIG_STRING_L1_PUSCH_DTX_THRESHOLD, NULL, 0, uptr:NULL, defintval:50, TYPE_UINT, 0} \ } #define L1_CC_IDX 0 diff --git a/openair2/GNB_APP/gnb_app.c b/openair2/GNB_APP/gnb_app.c index 66302d056bdd75cbdd757e3cb11deb8485cad6b1..b1dc59f2e27bb816df2dd6c053955a2a9952e115 100644 --- a/openair2/GNB_APP/gnb_app.c +++ b/openair2/GNB_APP/gnb_app.c @@ -50,6 +50,7 @@ #include "f1ap_cu_task.h" #include "f1ap_du_task.h" #include "nfapi/oai_integration/vendor_ext.h" +#include <openair2/LAYER2/nr_pdcp/nr_pdcp.h> extern unsigned char NB_gNB_INST; extern RAN_CONTEXT_t RC; diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 2a75e5955ee8095700893c23eb12bf6e25ade2b1..6604feca967f1ea9f584f61697cd05e658667273 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -1051,7 +1051,7 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { AssertFatal(0, "The number of PLMN IDs must be in [1,6], but is %d\n", PLMNParamList.numelt); - RRC_CONFIGURATION_REQ(msg_p).num_plmn = PLMNParamList.numelt; + NRRRC_CONFIGURATION_REQ(msg_p).num_plmn = PLMNParamList.numelt; for (int l = 0; l < PLMNParamList.numelt; ++l) { diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 93c6c1dbc7e5e0238177a4833d7f82b3fd903769..494f3a83eb2a2ee227ef26451f1913a13dc539f6 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -2502,7 +2502,7 @@ uint8_t get_L_ptrs(uint8_t mcs1, uint8_t mcs2, uint8_t mcs3, uint8_t I_mcs, uint * * NAME : get_K_ptrs * -* PARAMETERS : ptrs_UplinkConfig PTRS uplink configuration +* PARAMETERS : nrb0, nrb1 PTRS uplink configuration * N_RB number of RBs scheduled for PUSCH * * RETURN : the parameter K_ptrs diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index a6adb47c0a1374650d26f7fd2fd6cb05b9278ef1..d12e5b6f0a8d7d71e60eb8a5d2e9486462f55f8d 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -169,4 +169,9 @@ uint8_t get_transformPrecoding(const NR_BWP_UplinkCommon_t *initialUplinkBWP, int rnti_type, uint8_t configuredGrant); +void nr_mac_gNB_rrc_ul_failure(const module_id_t Mod_instP, + const int CC_idP, + const frame_t frameP, + const sub_frame_t subframeP, + const rnti_t rntiP) ; #endif diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 9e1f9debcd4fd17230680390259de079ca10f564..e7348511bbd8de3e5dc3bfaa626c1bb4515e8990 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -900,7 +900,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr dlsch_config_pdu_1_1->number_symbols, dlsch_config_pdu_1_1->start_symbol, mappingtype); - dlsch_config_pdu_1_1->dmrsConfigType = mac->DLbwp[dl_bwp_id]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1; + dlsch_config_pdu_1_1->dmrsConfigType = mac->DLbwp[dl_bwp_id]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? NFAPI_NR_DMRS_TYPE1 : NFAPI_NR_DMRS_TYPE2; /* TODO: fix number of DM-RS CDM groups without data according to subclause 5.1.6.2 of 3GPP TS 38.214, using tables 7.3.1.2.2-1, 7.3.1.2.2-2, 7.3.1.2.2-3, 7.3.1.2.2-4 of 3GPP TS 38.212 */ dlsch_config_pdu_1_1->n_dmrs_cdm_groups = 1; @@ -997,7 +997,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr dlsch_config_pdu_1_1->dmrs_ports[3] = table_7_3_2_3_3_2_oneCodeword[dci->antenna_ports.val][4]; dlsch_config_pdu_1_1->n_front_load_symb = table_7_3_2_3_3_2_oneCodeword[dci->antenna_ports.val][5]; } - if (n_codewords == 1) { + if (n_codewords == 2) { dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][0]; dlsch_config_pdu_1_1->dmrs_ports[0] = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][1]; dlsch_config_pdu_1_1->dmrs_ports[1] = table_7_3_2_3_3_2_twoCodeword[dci->antenna_ports.val][2]; @@ -1019,7 +1019,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr dlsch_config_pdu_1_1->dmrs_ports[2] = table_7_3_2_3_3_3_oneCodeword[dci->antenna_ports.val][3]; dlsch_config_pdu_1_1->dmrs_ports[3] = table_7_3_2_3_3_3_oneCodeword[dci->antenna_ports.val][4]; } - if (n_codewords == 1) { + if (n_codewords == 2) { dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_3_twoCodeword[dci->antenna_ports.val][0]; dlsch_config_pdu_1_1->dmrs_ports[0] = table_7_3_2_3_3_3_twoCodeword[dci->antenna_ports.val][1]; dlsch_config_pdu_1_1->dmrs_ports[1] = table_7_3_2_3_3_3_twoCodeword[dci->antenna_ports.val][2]; @@ -1039,7 +1039,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr dlsch_config_pdu_1_1->dmrs_ports[3] = table_7_3_2_3_3_4_oneCodeword[dci->antenna_ports.val][4]; dlsch_config_pdu_1_1->n_front_load_symb = table_7_3_2_3_3_4_oneCodeword[dci->antenna_ports.val][5]; } - if (n_codewords == 1) { + if (n_codewords == 2) { dlsch_config_pdu_1_1->n_dmrs_cdm_groups = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports.val][0]; dlsch_config_pdu_1_1->dmrs_ports[0] = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports.val][1]; dlsch_config_pdu_1_1->dmrs_ports[1] = table_7_3_2_3_3_4_twoCodeword[dci->antenna_ports.val][2]; @@ -2170,22 +2170,19 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload, uint16_t buflen) { NR_MAC_SUBHEADER_FIXED *mac_pdu_ptr = (NR_MAC_SUBHEADER_FIXED *) pdu; - unsigned char last_size = 0, i, mac_header_control_elements[16], *ce_ptr, bsr = 0; - int mac_ce_size; - uint16_t offset = 0; LOG_D(MAC, "[UE] Generating ULSCH PDU : num_sdus %d\n", num_sdus); #ifdef DEBUG_HEADER_PARSING - for (i = 0; i < num_sdus; i++) + for (int i = 0; i < num_sdus; i++) LOG_D(MAC, "[UE] MAC subPDU %d (lcid %d length %d bytes \n", i, sdu_lcids[i], sdu_lengths[i]); #endif // Generating UL MAC subPDUs including MAC SDU and subheader - for (i = 0; i < num_sdus; i++) { + for (int i = 0; i < num_sdus; i++) { LOG_D(MAC, "[UE] Generating UL MAC subPDUs for SDU with lenght %d ( num_sdus %d )\n", sdu_lengths[i], num_sdus); if (sdu_lcids[i] != UL_SCH_LCID_CCCH){ @@ -2194,23 +2191,21 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload, ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->F = 0; ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->LCID = sdu_lcids[i]; ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->L = (unsigned char) sdu_lengths[i]; - last_size = 2; + mac_pdu_ptr += sizeof(NR_MAC_SUBHEADER_SHORT); } else { ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->R = 0; ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->F = 1; ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->LCID = sdu_lcids[i]; ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->L1 = ((unsigned short) sdu_lengths[i] >> 8) & 0x7f; ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->L2 = (unsigned short) sdu_lengths[i] & 0xff; - last_size = 3; + mac_pdu_ptr += sizeof(NR_MAC_SUBHEADER_LONG); } } else { // UL CCCH SDU - ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->R = 0; - ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->LCID = sdu_lcids[i]; - last_size = 1; + mac_pdu_ptr->R = 0; + mac_pdu_ptr->LCID = sdu_lcids[i]; + mac_pdu_ptr ++; } - mac_pdu_ptr += last_size; - // cycle through SDUs, compute each relevant and place ulsch_buffer in memcpy((void *) mac_pdu_ptr, (void *) sdus_payload, sdu_lengths[i]); sdus_payload += sdu_lengths[i]; @@ -2219,8 +2214,6 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload, // Generating UL MAC subPDUs including MAC CEs (MAC CE and subheader) - ce_ptr = &mac_header_control_elements[0]; - if (power_headroom) { // MAC CE fixed subheader mac_pdu_ptr->R = 0; @@ -2228,17 +2221,11 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload, mac_pdu_ptr++; // PHR MAC CE (1 octet) - ((NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr)->PH = power_headroom; - ((NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr)->R1 = 0; - ((NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr)->PCMAX = 0; // todo - ((NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr)->R2 = 0; - - mac_ce_size = sizeof(NR_SINGLE_ENTRY_PHR_MAC_CE); - - // Copying bytes for PHR MAC CEs to the mac pdu pointer - memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size); - ce_ptr += mac_ce_size; - mac_pdu_ptr += (unsigned char) mac_ce_size; + ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_pdu_ptr)->PH = power_headroom; + ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_pdu_ptr)->R1 = 0; + ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_pdu_ptr)->PCMAX = 0; // todo + ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_pdu_ptr)->R2 = 0; + mac_pdu_ptr += sizeof(NR_SINGLE_ENTRY_PHR_MAC_CE); } if (crnti) { @@ -2248,13 +2235,8 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload, mac_pdu_ptr++; // C-RNTI MAC CE (2 octets) - * (uint16_t *) ce_ptr = crnti; - mac_ce_size = sizeof(uint16_t); - - // Copying bytes for CRNTI MAC CE to the mac pdu pointer - memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size); - ce_ptr += mac_ce_size; - mac_pdu_ptr += (unsigned char) mac_ce_size; + * (uint16_t *) mac_pdu_ptr = crnti; + mac_pdu_ptr += sizeof(uint16_t); } if (truncated_bsr) { @@ -2264,11 +2246,9 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload, mac_pdu_ptr++; // Short truncated BSR MAC CE (1 octet) - ((NR_BSR_SHORT_TRUNCATED *) ce_ptr)-> Buffer_size = truncated_bsr; - ((NR_BSR_SHORT_TRUNCATED *) ce_ptr)-> LcgID = 0; // todo - mac_ce_size = sizeof(NR_BSR_SHORT_TRUNCATED); - - bsr = 1 ; + ((NR_BSR_SHORT_TRUNCATED *) mac_pdu_ptr)-> Buffer_size = truncated_bsr; + ((NR_BSR_SHORT_TRUNCATED *) mac_pdu_ptr)-> LcgID = 0; // todo + mac_pdu_ptr+= sizeof(NR_BSR_SHORT_TRUNCATED); } else if (short_bsr) { // MAC CE fixed subheader mac_pdu_ptr->R = 0; @@ -2276,11 +2256,9 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload, mac_pdu_ptr++; // Short truncated BSR MAC CE (1 octet) - ((NR_BSR_SHORT *) ce_ptr)->Buffer_size = short_bsr; - ((NR_BSR_SHORT *) ce_ptr)->LcgID = 0; // todo - mac_ce_size = sizeof(NR_BSR_SHORT); - - bsr = 1 ; + ((NR_BSR_SHORT *) mac_pdu_ptr)->Buffer_size = short_bsr; + ((NR_BSR_SHORT *) mac_pdu_ptr)->LcgID = 0; // todo + mac_pdu_ptr+= sizeof(NR_BSR_SHORT); } else if (long_bsr) { // MAC CE variable subheader // todo ch 6.1.3.1. TS 38.321 @@ -2296,36 +2274,21 @@ uint16_t nr_generate_ulsch_pdu(uint8_t *sdus_payload, // ((NR_BSR_LONG *) ce_ptr)->LCGID0 = 0; // mac_ce_size = sizeof(NR_BSR_LONG); // size is variable } - - if (bsr){ - // Copying bytes for BSR MAC CE to the mac pdu pointer - memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size); - ce_ptr += mac_ce_size; - mac_pdu_ptr += (unsigned char) mac_ce_size; - } - - // compute offset before adding padding (if necessary) - offset = ((unsigned char *) mac_pdu_ptr - pdu); - uint16_t padding_bytes = 0; +// compute offset before adding padding (if necessary) + int padding_bytes = 0; if(buflen > 0) // If the buflen is provided - padding_bytes = buflen - offset; + padding_bytes = buflen + pdu - (unsigned char *) mac_pdu_ptr; + + AssertFatal(padding_bytes>=0,""); // Compute final offset for padding - if (post_padding > 0 || padding_bytes>0) { + if (post_padding || padding_bytes>0) { ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->R = 0; ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->LCID = UL_SCH_LCID_PADDING; mac_pdu_ptr++; - } else { - // no MAC subPDU with padding - } - - // compute final offset - offset = ((unsigned char *) mac_pdu_ptr - pdu); - - //printf("Offset %d \n", ((unsigned char *) mac_pdu_ptr - pdu)); - - return offset; + } + return (uint8_t *)mac_pdu_ptr-pdu; } ///////////////////////////////////// diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 9ce3acd08fc49ef6a3da6eebe0b91050fe2095a9..e38d8069d420c45c9d0718709792ea0a515ff1cc 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -2017,7 +2017,9 @@ nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, ENB_FLAG_NO, MBMS_FLAG_NO, lcid, - buflen_remain, + buflen_remain-MAX_RLC_SDU_SUBHEADER_SIZE, + //Fixme: Laurent I removed MAX_RLC_SDU_SUBHEADER_SIZE because else we get out the buffer silently + // the interface with nr_generate_ulsch_pdu() looks over complex and not CPU optimized (char *)&ulsch_sdus[sdu_length_total],0, 0); @@ -2037,8 +2039,7 @@ nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, /* Get updated BO after multiplexing this PDU */ lcid_buffer_occupancy_new = mac_rlc_get_buffer_occupancy_ind(module_idP,mac->crnti,eNB_index,frameP, subframe, ENB_FLAG_NO, lcid); - buflen_remain = - buflen - (total_rlc_pdu_header_len + sdu_length_total + MAX_RLC_SDU_SUBHEADER_SIZE); + buflen_remain = buflen - (total_rlc_pdu_header_len + sdu_length_total + MAX_RLC_SDU_SUBHEADER_SIZE); } } } diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 87cc7851ff2261186c6e76261812b999883ebf89..94288530373b0ac80bf4f18b9166192a8ec0daf8 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -489,12 +489,12 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, /* FIXME: it seems there is a problem with slot 0/10/slots right after UL: * we just get retransmissions. Thus, do not schedule such slots in DL */ if (slot % nr_slots_period != 0) - RC.nrmac[Mod_idP]->dlsch_slot_bitmap[slot / 64] |= ((slot % nr_slots_period) < nr_dlmix_slots) << (slot % 64); - RC.nrmac[Mod_idP]->ulsch_slot_bitmap[slot / 64] |= ((slot % nr_slots_period) >= nr_ulstart_slot) << (slot % 64); + RC.nrmac[Mod_idP]->dlsch_slot_bitmap[slot / 64] |= (uint64_t)((slot % nr_slots_period) < nr_dlmix_slots) << (slot % 64); + RC.nrmac[Mod_idP]->ulsch_slot_bitmap[slot / 64] |= (uint64_t)((slot % nr_slots_period) >= nr_ulstart_slot) << (slot % 64); LOG_D(NR_MAC, "slot %d DL %d UL %d\n", slot, - (RC.nrmac[Mod_idP]->dlsch_slot_bitmap[slot / 64] & (1 << (slot % 64))) != 0, - (RC.nrmac[Mod_idP]->ulsch_slot_bitmap[slot / 64] & (1 << (slot % 64))) != 0); + (RC.nrmac[Mod_idP]->dlsch_slot_bitmap[slot / 64] & ((uint64_t)1 << (slot % 64))) != 0, + (RC.nrmac[Mod_idP]->ulsch_slot_bitmap[slot / 64] & ((uint64_t)1 << (slot % 64))) != 0); } if (get_softmodem_params()->phy_test) { diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 52b4c5c1739119fd99983c84a35fa494f1b373fc..1d0215bb2aff8b3f64d0d66a17d58258c7f87aaf 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -55,33 +55,58 @@ #include "nfapi/oai_integration/vendor_ext.h" #include "executables/nr-softmodem.h" +#include <errno.h> +#include <string.h> + 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_info.mac_stats,0,MAX_MOBILES_PER_GNB*sizeof(NR_mac_stats_t)); } - +#define MACSTATSSTRLEN 16384 void dump_mac_stats(gNB_MAC_INST *gNB) { NR_UE_info_t *UE_info = &gNB->UE_info; int num = 1; + FILE *fd=fopen("nrMAC_stats.log","w"); + AssertFatal(fd!=NULL,"Cannot open nrMAC_stats.log, error %s\n",strerror(errno)); + char output[MACSTATSSTRLEN]; + memset(output,0,MACSTATSSTRLEN); + int stroff=0; for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) { + stroff = sprintf(output,"UE ID %d RNTI %04x (%d/%d)\n", UE_id, UE_info->rnti[UE_id], num++, UE_info->num_UEs); LOG_I(NR_MAC, "UE ID %d RNTI %04x (%d/%d) PH %d dB PCMAX %d dBm\n", - UE_id, - UE_info->rnti[UE_id], - num++, - UE_info->num_UEs, - UE_info->UE_sched_ctrl[UE_id].ph, - UE_info->UE_sched_ctrl[UE_id].pcmax); + UE_id, + UE_info->rnti[UE_id], + num++, + UE_info->num_UEs, + UE_info->UE_sched_ctrl[UE_id].ph, + UE_info->UE_sched_ctrl[UE_id].pcmax); NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id]; const int avg_rsrp = stats->num_rsrp_meas > 0 ? stats->cumul_rsrp / stats->num_rsrp_meas : 0; - LOG_I(NR_MAC, "UE %d: dlsch_rounds %d/%d/%d/%d, dlsch_errors %d, average RSRP %d (%d meas)\n", + stroff+=sprintf(output+stroff,"UE %d: dlsch_rounds %d/%d/%d/%d, dlsch_errors %d, average RSRP %d (%d meas)\n", UE_id, stats->dlsch_rounds[0], stats->dlsch_rounds[1], stats->dlsch_rounds[2], stats->dlsch_rounds[3], stats->dlsch_errors, avg_rsrp, stats->num_rsrp_meas); + LOG_I(NR_MAC, "UE %d: dlsch_rounds %d/%d/%d/%d, dlsch_errors %d, average RSRP %d (%d meas)\n", + UE_id, + stats->dlsch_rounds[0], stats->dlsch_rounds[1], + stats->dlsch_rounds[2], stats->dlsch_rounds[3], stats->dlsch_errors, + avg_rsrp, stats->num_rsrp_meas); stats->num_rsrp_meas = 0; stats->cumul_rsrp = 0 ; + stroff+=sprintf(output+stroff,"UE %d: dlsch_total_bytes %d\n", UE_id, stats->dlsch_total_bytes); + stroff+=sprintf(output+stroff,"UE %d: ulsch_rounds %d/%d/%d/%d, ulsch_DTX %d, ulsch_errors %d\n", + UE_id, + stats->ulsch_rounds[0], stats->ulsch_rounds[1], + stats->ulsch_rounds[2], stats->ulsch_rounds[3], + stats->ulsch_DTX, + stats->ulsch_errors); + stroff+=sprintf(output+stroff, + "UE %d: ulsch_total_bytes_scheduled %d, ulsch_total_bytes_received %d\n", + UE_id, + stats->ulsch_total_bytes_scheduled, stats->ulsch_total_bytes_rx); LOG_I(NR_MAC, "UE %d: dlsch_total_bytes %d\n", UE_id, stats->dlsch_total_bytes); LOG_I(NR_MAC, "UE %d: ulsch_rounds %d/%d/%d/%d, ulsch_DTX %d, ulsch_errors %d\n", UE_id, @@ -95,12 +120,16 @@ void dump_mac_stats(gNB_MAC_INST *gNB) stats->ulsch_total_bytes_scheduled, stats->ulsch_total_bytes_rx); for (int lc_id = 0; lc_id < 63; lc_id++) { if (stats->lc_bytes_tx[lc_id] > 0) + stroff+=sprintf(output+stroff, "UE %d: LCID %d: %d bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]); LOG_D(NR_MAC, "UE %d: LCID %d: %d bytes TX\n", UE_id, lc_id, stats->lc_bytes_tx[lc_id]); if (stats->lc_bytes_rx[lc_id] > 0) + stroff+=sprintf(output+stroff, "UE %d: LCID %d: %d bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]); LOG_D(NR_MAC, "UE %d: LCID %d: %d bytes RX\n", UE_id, lc_id, stats->lc_bytes_rx[lc_id]); } } print_meas(&gNB->eNB_scheduler, "DL & UL scheduling timing stats", NULL, NULL); + if (stroff>0) fprintf(fd,"%s",output); + fclose(fd); } void clear_nr_nfapi_information(gNB_MAC_INST * gNB, @@ -311,7 +340,7 @@ void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subfram bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot) { - if (slot>64) return false; //quickfix for FR2 where there are more than 64 slots (bitmap to be removed) + if (slot>=64) return false; //quickfix for FR2 where there are more than 64 slots (bitmap to be removed) return (bitmap >> slot) & 0x01; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index d881847990fb9517a5373f9572463d6214d700c0..8158e5fcca2b3c70b967db2c740a88dc9a3d5a2e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -215,7 +215,7 @@ void find_SSB_and_RO_available(module_id_t module_idP) { } cc->total_prach_occasions_per_config_period = total_RA_occasions; - for(int i=1; (1 << (i-1)) < max_association_period; i++) { + for(int i=1; (1 << (i-1)) <= max_association_period; i++) { cc->max_association_period = (1 <<(i-1)); total_RA_occasions = total_RA_occasions * cc->max_association_period; if(total_RA_occasions >= (int) (num_active_ssb/num_ssb_per_RO)) { @@ -697,28 +697,34 @@ void nr_get_Msg3alloc(module_id_t module_id, int mu = ubwp ? ubwp->bwp_Common->genericParameters.subcarrierSpacing : scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing; - int StartSymbolIndex, NrOfSymbols, startSymbolAndLength, temp_slot; + int StartSymbolIndex = 0; + int NrOfSymbols = 0; + int startSymbolAndLength = 0; + int temp_slot = 0; ra->Msg3_tda_id = 16; // initialization to a value above limit NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList= ubwp ? ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList: scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; + uint8_t k2 = 0; for (int i=0; i<pusch_TimeDomainAllocationList->list.count; i++) { startSymbolAndLength = pusch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength; SLIV2SL(startSymbolAndLength, &StartSymbolIndex, &NrOfSymbols); // we want to transmit in the uplink symbols of mixed slot if (NrOfSymbols == scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols) { - ra->Msg3_tda_id = i; - break; + k2 = *pusch_TimeDomainAllocationList->list.array[i]->k2; + temp_slot = current_slot + k2 + DELTA[mu]; // msg3 slot according to 8.3 in 38.213 + ra->Msg3_slot = temp_slot%nr_slots_per_frame[mu]; + if (is_xlsch_in_slot(RC.nrmac[module_id]->ulsch_slot_bitmap[ra->Msg3_slot / 64], ra->Msg3_slot)) { + ra->Msg3_tda_id = i; + break; + } } } - AssertFatal(ra->Msg3_tda_id<16,"Unable to find Msg3 time domain allocation in list\n"); - uint8_t k2 = *pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->k2; + AssertFatal(ra->Msg3_tda_id<16,"Unable to find Msg3 time domain allocation in list\n"); - temp_slot = current_slot + k2 + DELTA[mu]; // msg3 slot according to 8.3 in 38.213 - ra->Msg3_slot = temp_slot%nr_slots_per_frame[mu]; if (nr_slots_per_frame[mu]>temp_slot) ra->Msg3_frame = current_frame; else diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 8b12742fccef1ad5fc66c4f71ad2d5602ee04433..fbd08f18c48297f04f2e54f2ca4e2aa1de161b81 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -157,10 +157,14 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) dl_req = &dl_tti_request->dl_tti_request_body; // get MIB every 8 frames - if((slotP == 0) && (frameP & 7) == 0) { + if(((slotP == 0) && (frameP & 7) == 0) || + gNB->first_MIB) { mib_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, MIBCH, 0, 1, &cc->MIB_pdu.payload[0]); + // flag to avoid sending an empty MIB in the first frames of execution since gNB doesn't get at the beginning in frame 0 slot 0 + gNB->first_MIB = false; + LOG_D(MAC, "[gNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes\n", module_idP, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 47614ed8c0743810d4b7eaa9699fdc38c3a2a4d4..93d2e959ddf4857935edd61e98b407aa25fc724e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -551,7 +551,7 @@ bool allocate_dl_retransmission(module_id_t module_id, } float thr_ue[MAX_MOBILES_PER_GNB]; -uint32_t pf_tbs[3][28]; // pre-computed, approximate TBS values for PF coefficient +uint32_t pf_tbs[3][29]; // pre-computed, approximate TBS values for PF coefficient void pf_dl(module_id_t module_id, frame_t frame, @@ -573,6 +573,7 @@ void pf_dl(module_id_t module_id, for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { if (UE_info->Msg4_ACKed[UE_id] != true) continue; NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + if (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0) continue; NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static; /* get the PID of a HARQ process awaiting retrnasmission, or -1 otherwise */ @@ -602,6 +603,7 @@ void pf_dl(module_id_t module_id, /* Calculate coeff */ sched_pdsch->mcs = 9; + sched_pdsch->nrOfLayers = 1; uint32_t tbs = pf_tbs[ps->mcsTableIdx][sched_pdsch->mcs]; coeff_ue[UE_id] = (float) tbs / thr_ue[UE_id]; LOG_D(NR_MAC,"b %d, thr_ue[%d] %f, tbs %d, coeff_ue[%d] %f\n", @@ -690,8 +692,7 @@ void pf_dl(module_id_t module_id, sched_pdsch->pucch_allocation = alloc; uint32_t TBS = 0; uint16_t rbSize; - const int oh = 2 + (sched_ctrl->num_total_bytes >= 256) - + 2 * (frame == (sched_ctrl->ta_frame + 10) % 1024); + const int oh = 3 + 2 * (frame == (sched_ctrl->ta_frame + 10) % 1024); nr_find_nb_rb(sched_pdsch->Qm, sched_pdsch->R, ps->nrOfSymbols, @@ -820,7 +821,7 @@ void nr_schedule_ue_spec(module_id_t module_id, const rnti_t rnti = UE_info->rnti[UE_id]; /* POST processing */ - const int nrOfLayers = 1; + const uint8_t nrOfLayers = sched_pdsch->nrOfLayers; const uint16_t R = sched_pdsch->R; const uint8_t Qm = sched_pdsch->Qm; const uint32_t TBS = sched_pdsch->tb_size; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 1dda52b56719cd6e0237da0ddd9068ecd423dcbb..50a0b241b66080cab7a4b49099dd53eb55499a64 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -146,7 +146,7 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, int startSymbolAndLength=0; int StartSymbolIndex=-1,NrOfSymbols=14; int StartSymbolIndex_tmp,NrOfSymbols_tmp; - int mappingtype_tmp, mappingtype; + int mappingtype_tmp, mappingtype=0; for (int i=0; i<scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count; @@ -262,6 +262,7 @@ void nr_schedule_css_dlsch_phytest(module_id_t module_idP, extern int getNrOfSymbols(NR_BWP_Downlink_t *bwp, int tda); extern uint8_t getN_PRB_DMRS(NR_BWP_Downlink_t *bwp, int numDmrsCdmGrpsNoData); uint32_t target_dl_mcs = 9; +uint32_t target_dl_Nl = 1; uint32_t target_dl_bw = 50; uint64_t dlsch_slot_bitmap = (1<<1); /* schedules whole bandwidth for first user, all the time */ @@ -286,6 +287,8 @@ void nr_preprocessor_phytest(module_id_t module_id, target_dl_bw = (bwpSize < target_dl_bw) ?bwpSize : target_dl_bw; int rbStart = 0; int rbSize = 0; + if (target_dl_bw>bwpSize) + target_dl_bw = bwpSize; uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map; /* loop ensures that we allocate exactly target_dl_bw, or return */ while (true) { @@ -372,6 +375,7 @@ void nr_preprocessor_phytest(module_id_t module_id, nr_set_pdsch_semi_static( scc, UE_info->CellGroup[UE_id], sched_ctrl->active_bwp, tda, num_dmrs_cdm_grps_no_data, ps); + sched_pdsch->nrOfLayers = target_dl_Nl; sched_pdsch->mcs = target_dl_mcs; sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx); sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx); @@ -382,7 +386,7 @@ void nr_preprocessor_phytest(module_id_t module_id, ps->N_PRB_DMRS * ps->N_DMRS_SLOT, 0 /* N_PRB_oh, 0 for initialBWP */, 0 /* tb_scaling */, - 1 /* nrOfLayers */) + sched_pdsch->nrOfLayers) >> 3; /* get the PID of a HARQ process awaiting retransmission, or -1 otherwise */ @@ -391,6 +395,8 @@ void nr_preprocessor_phytest(module_id_t module_id, /* mark the corresponding RBs as used */ for (int rb = 0; rb < sched_pdsch->rbSize; rb++) vrb_map[rb + sched_pdsch->rbStart] = 1; + + if ((frame&127) == 0) LOG_D(MAC,"phytest: %d.%d DL mcs %d, DL rbStart %d, DL rbSize %d\n", frame, slot, sched_pdsch->mcs, rbStart,rbSize); } uint32_t target_ul_mcs = 9; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 83e96c9bb945408a4c3d8c06e7e9699216ad4bb0..04ac9ea1f1b0b32eac1ebd4cc902a4b068107013 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -600,7 +600,7 @@ void nr_configure_css_dci_initial(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu, } void config_uldci(const NR_BWP_Uplink_t *ubwp, - const NR_ServingCellConfigCommon_t *scc, + const NR_ServingCellConfigCommon_t *scc, const nfapi_nr_pusch_pdu_t *pusch_pdu, dci_pdu_rel15_t *dci_pdu_rel15, int dci_format, @@ -611,6 +611,7 @@ void config_uldci(const NR_BWP_Uplink_t *ubwp, const int bw = NRRIV2BW(ubwp ? ubwp->bwp_Common->genericParameters.locationAndBandwidth : scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + dci_pdu_rel15->frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pusch_pdu->rb_size, pusch_pdu->rb_start, bw); dci_pdu_rel15->time_domain_assignment.val = time_domain_assignment; @@ -673,6 +674,7 @@ int nr_get_default_pucch_res(int pucch_ResourceCommon) { return(default_pucch_csset[pucch_ResourceCommon]); } + void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, NR_SearchSpace_t *ss, NR_ControlResourceSet_t *coreset, @@ -739,15 +741,15 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, // This function configures pucch pdu fapi structure void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, - NR_ServingCellConfigCommon_t *scc, - NR_CellGroupConfig_t *CellGroup, - NR_BWP_Uplink_t *bwp, + NR_ServingCellConfigCommon_t *scc, + NR_CellGroupConfig_t *CellGroup, + NR_BWP_Uplink_t *bwp, uint16_t rnti, uint8_t pucch_resource, uint16_t O_csi, uint16_t O_ack, uint8_t O_sr, - int r_pucch) { + int r_pucch) { NR_PUCCH_Config_t *pucch_Config; NR_PUCCH_Resource_t *pucchres; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 3effe300abef5731eddc2198dc4b630e74f55aa8..17c7bb92eba7a683ea431f627a91c3a984809dd0 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -144,7 +144,7 @@ void calculate_preferred_ul_tda(module_id_t module_id, const NR_BWP_Uplink_t *ub if ((symb_pucch & symb_tda_mi) == 0 && (symb_ulMixed & symb_tda_mi) == symb_tda_mi) { tdaMi = 1; } else { - LOG_E(MAC, + LOG_E(NR_MAC, "TDA index 1 UL overlaps with PUCCH or is not entirely in mixed slot (symb_pucch %x symb_ulMixed %x symb_tda_mi %x), won't schedule UL mixed slot\n", symb_pucch, symb_ulMixed, @@ -168,7 +168,7 @@ void calculate_preferred_ul_tda(module_id_t module_id, const NR_BWP_Uplink_t *ub } if (k2 < tdd->nrofUplinkSlots) - LOG_W(MAC, + LOG_W(NR_MAC, "k2 %d < tdd->nrofUplinkSlots %ld: not all UL slots can be scheduled\n", k2, tdd->nrofUplinkSlots); @@ -192,6 +192,10 @@ void nr_process_mac_pdu(module_id_t module_idP, NR_UE_info_t *UE_info = &RC.nrmac[module_idP]->UE_info; NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + + if ( pduP[0] != UL_SCH_LCID_PADDING ) + trace_NRpdu(DIRECTION_UPLINK, pduP, mac_pdu_len ,UE_id, WS_C_RNTI, UE_info->rnti[UE_id], frameP, 0, 0, 0); + // For both DL/UL-SCH // Except: // - UL/DL-SCH: fixed-size MAC CE(known by LCID) @@ -327,7 +331,7 @@ void nr_process_mac_pdu(module_id_t module_idP, sched_ctrl->ph = PH - 32 + (PH - 54); /* 38.133 Table10.1.18.1-1 */ sched_ctrl->pcmax = PCMAX - 29; - LOG_D(MAC, "SINGLE ENTRY PHR R1 %d PH %d (%d dB) R2 %d PCMAX %d (%d dBm)\n", + LOG_D(NR_MAC, "SINGLE ENTRY PHR R1 %d PH %d (%d dB) R2 %d PCMAX %d (%d dBm)\n", phr->R1, PH, sched_ctrl->ph, phr->R2, PCMAX, sched_ctrl->pcmax); break; @@ -371,7 +375,7 @@ void nr_process_mac_pdu(module_id_t module_idP, mac_sdu_len = (uint16_t)((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->L; mac_subheader_len = 2; } - LOG_D(NR_MAC, "[UE %d] Frame %d : ULSCH -> UL-DCCH %d (gNB %d, %d bytes), rnti: %d \n", module_idP, frameP, rx_lcid, module_idP, mac_sdu_len, *UE_info->rnti); + LOG_D(NR_MAC, "[UE %d] Frame %d : ULSCH -> UL-DCCH %d (gNB %d, %d bytes), rnti: %d \n", module_idP, frameP, rx_lcid, module_idP, mac_sdu_len, UE_info->rnti[UE_id]); mac_rlc_data_ind(module_idP, UE_info->rnti[UE_id], module_idP, @@ -664,6 +668,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, if (UE_info->UE_sched_ctrl[UE_id].pusch_consecutive_dtx_cnt >= pusch_failure_thres) { LOG_D(NR_MAC,"Detected UL Failure on PUSCH, stopping scheduling\n"); UE_info->UE_sched_ctrl[UE_id].ul_failure = 1; + nr_mac_gNB_rrc_ul_failure(gnb_mod_idP,CC_idP,frameP,slotP,rntiP); } } } else if(sduP) { @@ -812,7 +817,7 @@ bool nr_UE_is_to_be_scheduled(module_id_t mod_id, int CC_id, int UE_id, frame_t * (3) or we did not schedule it in more than 10 frames */ const bool has_data = sched_ctrl->estimated_ul_buffer > sched_ctrl->sched_ul_bytes; const bool high_inactivity = diff >= nrmac->ulsch_max_slots_inactivity; - LOG_D(MAC, + LOG_D(NR_MAC, "%4d.%2d UL inactivity %d slots has_data %d SR %d\n", frame, slot, @@ -842,29 +847,20 @@ bool allocate_ul_retransmission(module_id_t module_id, NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info; NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; NR_sched_pusch_t *retInfo = &sched_ctrl->ul_harq_processes[harq_pid].sched_pusch; - NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; - - // frame/slot in sched_pusch has been set previously. In the following, we - // overwrite the information in the retransmission information before storing - // as the new scheduling instruction - retInfo->frame = sched_ctrl->sched_pusch.frame; - retInfo->slot = sched_ctrl->sched_pusch.slot; - - // Get previous PUSCH filed info - sched_ctrl->sched_pusch = *retInfo; NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ? &sched_ctrl->active_ubwp->bwp_Common->genericParameters : &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters; int rbStart = sched_ctrl->active_ubwp ? NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE) : 0; const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); const uint8_t num_dmrs_cdm_grps_no_data = sched_ctrl->active_bwp ? 1 : 2; - const int tda = sched_ctrl->active_ubwp ? RC.nrmac[module_id]->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 1; + const int tda = sched_ctrl->active_ubwp ? RC.nrmac[module_id]->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 0; + LOG_D(NR_MAC,"retInfo->time_domain_allocation = %d, tda = %d\n", retInfo->time_domain_allocation, tda); if (tda == retInfo->time_domain_allocation) { /* Check the resource is enough for retransmission */ while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++; - if (rbStart + retInfo->rbSize >= bwpSize) { - LOG_D(MAC, "cannot allocate retransmission of UE %d/RNTI %04x: no resources\n", UE_id, UE_info->rnti[UE_id]); + if (rbStart + retInfo->rbSize > bwpSize) { + LOG_W(NR_MAC, "cannot allocate retransmission of UE %d/RNTI %04x: no resources (rbStart %d, retInfo->rbSize %d, bwpSize %d\n", UE_id, UE_info->rnti[UE_id], rbStart, retInfo->rbSize, bwpSize); return false; } /* check whether we need to switch the TDA allocation since tha last @@ -876,7 +872,7 @@ bool allocate_ul_retransmission(module_id_t module_id, || ps->dci_format != dci_format || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data) nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, dci_format, tda, num_dmrs_cdm_grps_no_data, ps); - LOG_D(MAC, "%s(): retransmission keeping TDA %d and TBS %d\n", __func__, tda, retInfo->tb_size); + LOG_D(NR_MAC, "%s(): retransmission keeping TDA %d and TBS %d\n", __func__, tda, retInfo->tb_size); } else { /* the retransmission will use a different time domain allocation, check * that we have enough resources */ @@ -900,10 +896,10 @@ bool allocate_ul_retransmission(module_id_t module_id, &new_tbs, &new_rbSize); if (!success || new_tbs != retInfo->tb_size) { - LOG_D(MAC, "%s(): new TBsize %d of new TDA does not match old TBS %d\n", __func__, new_tbs, retInfo->tb_size); + LOG_D(NR_MAC, "%s(): new TBsize %d of new TDA does not match old TBS %d\n", __func__, new_tbs, retInfo->tb_size); return false; /* the maximum TBsize we might have is smaller than what we need */ } - LOG_D(MAC, "%s(): retransmission with TDA %d->%d and TBS %d -> %d\n", __func__, retInfo->time_domain_allocation, tda, retInfo->tb_size, new_tbs); + LOG_D(NR_MAC, "%s(): retransmission with TDA %d->%d and TBS %d -> %d\n", __func__, retInfo->time_domain_allocation, tda, retInfo->tb_size, new_tbs); /* we can allocate it. Overwrite the time_domain_allocation, the number * of RBs, and the new TB size. The rest is done below */ retInfo->tb_size = new_tbs; @@ -915,11 +911,20 @@ bool allocate_ul_retransmission(module_id_t module_id, /* Find free CCE */ bool freeCCE = find_free_CCE(module_id, slot, UE_id); if (!freeCCE) { - LOG_D(MAC, "%4d.%2d no free CCE for retransmission UL DCI UE %04x\n", frame, slot, UE_info->rnti[UE_id]); + LOG_D(NR_MAC, "%4d.%2d no free CCE for retransmission UL DCI UE %04x\n", frame, slot, UE_info->rnti[UE_id]); return false; } - LOG_D(MAC, + /* frame/slot in sched_pusch has been set previously. In the following, we + * overwrite the information in the retransmission information before storing + * as the new scheduling instruction */ + retInfo->frame = sched_ctrl->sched_pusch.frame; + retInfo->slot = sched_ctrl->sched_pusch.slot; + /* Get previous PSUCH field info */ + sched_ctrl->sched_pusch = *retInfo; + NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; + + LOG_D(NR_MAC, "%4d.%2d Allocate UL retransmission UE %d/RNTI %04x sched %4d.%2d (%d RBs)\n", frame, slot, @@ -952,7 +957,7 @@ void update_ul_ue_R_Qm(NR_sched_pusch_t *sched_pusch, const NR_pusch_semi_static } float ul_thr_ue[MAX_MOBILES_PER_GNB]; -uint32_t ul_pf_tbs[3][28]; // pre-computed, approximate TBS values for PF coefficient +uint32_t ul_pf_tbs[3][29]; // pre-computed, approximate TBS values for PF coefficient void pf_ul(module_id_t module_id, frame_t frame, sub_frame_t slot, @@ -995,7 +1000,7 @@ void pf_ul(module_id_t module_id, bool r = allocate_ul_retransmission( module_id, frame, slot, rballoc_mask, &n_rb_sched, UE_id, sched_pusch->ul_harq_pid); if (!r) { - LOG_D(MAC, "%4d.%2d UL retransmission UE RNTI %04x can NOT be allocated\n", frame, slot, UE_info->rnti[UE_id]); + LOG_D(NR_MAC, "%4d.%2d UL retransmission UE RNTI %04x can NOT be allocated\n", frame, slot, UE_info->rnti[UE_id]); continue; } /* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */ @@ -1026,7 +1031,7 @@ void pf_ul(module_id_t module_id, if (max_num_ue < 0) return; - LOG_D(NR_MAC,"Looking for min_rb %d RBs, starting at %d\n", min_rb,rbStart); + LOG_D(NR_MAC,"Looking for min_rb %d RBs, starting at %d\n", min_rb, rbStart); while (rbStart < bwpSize && !rballoc_mask[rbStart]) rbStart++; if (rbStart + min_rb >= bwpSize) { LOG_W(NR_MAC, "cannot allocate continuous UL data for UE %d/RNTI %04x: no resources (rbStart %d, min_rb %d, bwpSize %d\n", @@ -1041,7 +1046,7 @@ void pf_ul(module_id_t module_id, const uint8_t num_dmrs_cdm_grps_no_data = sched_ctrl->active_ubwp ? 1 : 2; const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats; const int dci_format = sched_ctrl->active_ubwp ? (f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0) : NR_UL_DCI_FORMAT_0_0; - const int tda = sched_ctrl->active_ubwp ? nrmac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 1; + const int tda = sched_ctrl->active_ubwp ? nrmac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 0; if (ps->time_domain_allocation != tda || ps->dci_format != dci_format || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data) @@ -1137,7 +1142,7 @@ void pf_ul(module_id_t module_id, const uint8_t num_dmrs_cdm_grps_no_data = sched_ctrl->active_ubwp ? 1 : 2; const long f = sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats; const int dci_format = sched_ctrl->active_ubwp ? (f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0) : NR_UL_DCI_FORMAT_0_0; - const int tda = sched_ctrl->active_ubwp ? nrmac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 1; + const int tda = sched_ctrl->active_ubwp ? nrmac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 0; if (ps->time_domain_allocation != tda || ps->dci_format != dci_format || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data) @@ -1158,7 +1163,7 @@ void pf_ul(module_id_t module_id, &rbSize); sched_pusch->rbSize = rbSize; sched_pusch->tb_size = TBS; - LOG_D(MAC,"rbSize %d, TBS %d, est buf %d, sched_ul %d, B %d\n", + LOG_D(NR_MAC,"rbSize %d, TBS %d, est buf %d, sched_ul %d, B %d\n", rbSize, sched_pusch->tb_size, sched_ctrl->estimated_ul_buffer, sched_ctrl->sched_ul_bytes, B); /* Mark the corresponding RBs as used */ @@ -1187,15 +1192,23 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t * schedule now (slot + k2 is not UL slot) */ int UE_id = UE_info->list.head; NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; - const int tda = sched_ctrl->active_ubwp ? nr_mac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 1; + const int tda = sched_ctrl->active_ubwp ? nr_mac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 0; if (tda < 0) return false; int K2 = get_K2(scc, sched_ctrl->active_ubwp, tda, mu); const int sched_frame = frame + (slot + K2 >= nr_slots_per_frame[mu]); const int sched_slot = (slot + K2) % nr_slots_per_frame[mu]; + if (!is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[sched_slot / 64], sched_slot)) return false; + bool is_mixed_slot = is_xlsch_in_slot(nr_mac->dlsch_slot_bitmap[sched_slot / 64], sched_slot) && + is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[sched_slot / 64], sched_slot); + + // FIXME: Avoid mixed slots for initialUplinkBWP + if (sched_ctrl->active_ubwp==NULL && is_mixed_slot) + return false; + sched_ctrl->sched_pusch.slot = sched_slot; sched_ctrl->sched_pusch.frame = sched_frame; for (UE_id = UE_info->list.next[UE_id]; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) { @@ -1575,7 +1588,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) n_ubwp = CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count; config_uldci(sched_ctrl->active_ubwp, - scc, + scc, pusch_pdu, &uldci_payload, ps->dci_format, diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index 9974c08a18a94275dcda1bc52ecc9e80467b9a96..117c18ae8da3784749948cc18daed5f6a5ca028f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -81,6 +81,8 @@ void mac_top_init_gNB(void) RC.nrmac[i]->ul_handle = 0; + RC.nrmac[i]->first_MIB = true; + if (get_softmodem_params()->phy_test) { RC.nrmac[i]->pre_processor_dl = nr_preprocessor_phytest; RC.nrmac[i]->pre_processor_ul = nr_ul_preprocessor_phytest; diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 1f9cfff1e8354e0e571fc1f1a5834bc520d1989e..ec98e61060e5b6655ee5ccf50b80454adf93bb37 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -383,6 +383,7 @@ typedef struct NR_sched_pdsch { uint8_t mcs; /// TBS-related info + uint8_t nrOfLayers; uint16_t R; uint8_t Qm; uint32_t tb_size; @@ -747,6 +748,7 @@ typedef struct gNB_MAC_INST_s { NR_UE_sched_ctrl_t *sched_ctrlCommon; NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config[64]; + bool first_MIB; } gNB_MAC_INST; #endif /*__LAYER2_NR_MAC_GNB_H__ */ diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index 1624c395efc3abc04d4a9604f8ffaf64314c109b..60788826017a44ba2ff0609d04a87c9bb1ebe256 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -445,7 +445,8 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity, int rb_id; int i; - if(IS_SOFTMODEM_NOS1){ + if(IS_SOFTMODEM_NOS1 || UE_NAS_USE_TUN){ + LOG_D(PDCP, "IP packet received, to be sent to TUN interface"); len = write(nas_sock_fd[0], buf, size); if (len != size) { LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); @@ -534,7 +535,7 @@ static void deliver_sdu_srb(void *_ue, nr_pdcp_entity_t *entity, int srb_id; int i; - for (i = 0; i < 2; i++) { + for (i = 0; i < sizeofArray(ue->srb) ; i++) { if (entity == ue->srb[i]) { srb_id = i+1; goto srb_found; @@ -577,7 +578,7 @@ static void deliver_pdu_srb(void *_ue, nr_pdcp_entity_t *entity, int i; mem_block_t *memblock; - for (i = 0; i < 2; i++) { + for (i = 0; i < sizeofArray(ue->srb) ; i++) { if (entity == ue->srb[i]) { srb_id = i+1; goto srb_found; @@ -896,13 +897,14 @@ boolean_t nr_rrc_pdcp_config_asn1_req( //ctxt_pP->configured != 2 || //srb2add_list == NULL || //drb2add_list != NULL || - drb2release_list != NULL || + //drb2release_list != NULL || //security_modeP != 255 || //kRRCenc != NULL || //kRRCint != NULL || //kUPenc != NULL || pmch_InfoList_r9 != NULL /*|| defaultDRB != NULL */) { + LOG_I(PDCP,"Releasing DRBs, oops\n"); TODO; } @@ -926,6 +928,10 @@ boolean_t nr_rrc_pdcp_config_asn1_req( /* todo */ } + if (drb2release_list != NULL) { + // TODO + } + free(kRRCenc); free(kRRCint); free(kUPenc); @@ -1189,6 +1195,7 @@ static boolean_t pdcp_data_req_drb( if (rb == NULL) { LOG_E(PDCP, "%s:%d:%s: no DRB found (rnti %d, rb_id %ld)\n", __FILE__, __LINE__, __FUNCTION__, rnti, rb_id); + nr_pdcp_manager_unlock(nr_pdcp_ue_manager); return 0; } diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h index 3329f856b7fb04a1f710b7ee95bc4276130547fa..742e0e84be8c67f0e1a109a95e32879f2884ce9d 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h @@ -28,7 +28,7 @@ typedef void nr_pdcp_ue_manager_t; typedef struct nr_pdcp_ue_t { int rnti; - nr_pdcp_entity_t *srb[2]; + nr_pdcp_entity_t *srb[3]; nr_pdcp_entity_t *drb[5]; } nr_pdcp_ue_t; diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c index 000c764e8f1c31b8752aa35d33fa3a67722f2cc2..08f5b11c23197f47587d5f8801cd8c875dd211df 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c @@ -1529,7 +1529,7 @@ static int tx_list_size(nr_rlc_entity_am_t *entity, { int ret = 0; - while (l != NULL) { + while (l != NULL && ret < maxsize) { ret += compute_pdu_header_size(entity, l) + l->size; l = l->next; } diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c index 4ef952667dc84be0c6de1b219c5cf5f37833558e..f967c3c5432a9832768ea4ceb22a0083eecbc0ff 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c @@ -497,7 +497,7 @@ static int tx_list_size(nr_rlc_entity_um_t *entity, { int ret = 0; - while (l != NULL) { + while (l != NULL && ret < maxsize) { ret += compute_pdu_header_size(entity, l) + l->size; l = l->next; } diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 2a6bcf74aee97651a84b781483eb11269dd420f4..fb657bf5a8889042f0611f1c441bf706b764d4bc 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -38,7 +38,6 @@ #include "common/ran_context.h" #include "NR_UL-CCCH-Message.h" -#undef C_RNTI // C_RNTI is used in F1AP generated code, prevent preprocessor replace #include "openair2/F1AP/f1ap_du_rrc_message_transfer.h" #include "openair2/LAYER2/PROTO_AGENT/proto_agent.h" @@ -47,6 +46,8 @@ extern RAN_CONTEXT_t RC; #include <stdint.h> +#include <executables/softmodem-common.h> + static nr_rlc_ue_manager_t *nr_rlc_ue_manager; /* TODO: handle time a bit more properly */ @@ -324,7 +325,8 @@ rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind( * reports '> 81338368' (table 6.1.3.1-2). Passing 100000000 is thus * more than enough. */ - buf_stat = rb->buffer_status(rb, 100000000); + // Fixme : Laurent reduced size for CPU saving + buf_stat = rb->buffer_status(rb, 10000000); ret = buf_stat.status_size + buf_stat.retx_size + buf_stat.tx_size; @@ -426,7 +428,7 @@ static void deliver_sdu(void *_ue, nr_rlc_entity_t *entity, char *buf, int size) int is_enb; /* is it SRB? */ - for (i = 0; i < 2; i++) { + for (i = 0; i < sizeofArray(ue->srb); i++) { if (entity == ue->srb[i]) { is_srb = 1; rb_id = i+1; @@ -435,7 +437,7 @@ static void deliver_sdu(void *_ue, nr_rlc_entity_t *entity, char *buf, int size) } /* maybe DRB? */ - for (i = 0; i < 5; i++) { + for (i = 0; i < sizeofArray(ue->drb) ; i++) { if (entity == ue->drb[i]) { is_srb = 0; rb_id = i+1; @@ -918,7 +920,7 @@ rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt if (drb2release_listP != NULL) { LOG_E(RLC, "%s:%d:%s: TODO\n", __FILE__, __LINE__, __FUNCTION__); - exit(1); + //exit(1); } if (srb2add_listP != NULL) { diff --git a/openair2/RRC/LTE/L2_interface.c b/openair2/RRC/LTE/L2_interface.c index 921c1f3bcb84c1bc7a75ec903d6f39da4c368c54..0b767b8ad6efa203c3317cb8c876a35bb7adf803 100644 --- a/openair2/RRC/LTE/L2_interface.c +++ b/openair2/RRC/LTE/L2_interface.c @@ -49,8 +49,6 @@ #include "intertask_interface.h" #include "flexran_agent_extern.h" -#undef C_RNTI // C_RNTI is used in F1AP generated code, prevent preprocessor replace -//#include "f1ap_du_rrc_message_transfer.h" #include "openair2/F1AP/f1ap_du_rrc_message_transfer.h" extern RAN_CONTEXT_t RC; diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c index 1f4af2a98eff5b81d3598d89868f424a3db1ab07..8a6e16499947323d1928a78f474d9e8e2cdacf21 100644 --- a/openair2/RRC/NR/L2_nr_interface.c +++ b/openair2/RRC/NR/L2_nr_interface.c @@ -44,7 +44,9 @@ #include "NR_MIB.h" #include "NR_BCCH-BCH-Message.h" #include "rrc_gNB_UE_context.h" -#include "openair2/RRC/NR/MESSAGES/asn1_msg.h" +#include <openair2/RRC/NR/MESSAGES/asn1_msg.h> +#include <openair2/F1AP/f1ap_du_rrc_message_transfer.h> + extern RAN_CONTEXT_t RC; @@ -361,4 +363,23 @@ int8_t nr_mac_rrc_data_ind(const module_id_t module_idP, } return 0; -} \ No newline at end of file +} + +void nr_mac_gNB_rrc_ul_failure(const module_id_t Mod_instP, + const int CC_idP, + const frame_t frameP, + const sub_frame_t subframeP, + const rnti_t rntiP) { + struct rrc_gNB_ue_context_s *ue_context_p = NULL; + ue_context_p = rrc_gNB_get_ue_context( + RC.nrrrc[Mod_instP], + rntiP); + + if (ue_context_p != NULL) { + LOG_D(RRC,"Frame %d, Subframe %d: UE %x UL failure, activating timer\n",frameP,subframeP,rntiP); + if(ue_context_p->ue_context.ul_failure_timer == 0) + ue_context_p->ue_context.ul_failure_timer=1; + } else { + LOG_D(RRC,"Frame %d, Subframe %d: UL failure: UE %x unknown \n",frameP,subframeP,rntiP); + } +} diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 789fb84a288e355543262196e2f87fdb373af88e..e36644afb0089375208ded1a1b8834af5b76668e 100755 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -1220,47 +1220,6 @@ void fill_initial_cellGroupConfig(rnti_t rnti, logicalChannelConfig->ul_SpecificParameters->logicalChannelSR_DelayTimerApplied = 0; rlc_BearerConfig->mac_LogicalChannelConfig = logicalChannelConfig; ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig); - - /* - // SRB2 - NR_RLC_BearerConfig_t *rlc_BearerConfig2 = NULL; - NR_RLC_Config_t *rlc_Config2 = NULL; - NR_LogicalChannelConfig_t *logicalChannelConfig2= NULL; - long *logicalChannelGroup2 = NULL; - rlc_BearerConfig2 = calloc(1, sizeof(NR_RLC_BearerConfig_t)); - rlc_BearerConfig2->logicalChannelIdentity = 2; - rlc_BearerConfig2->servedRadioBearer = calloc(1, sizeof(*rlc_BearerConfig2->servedRadioBearer)); - rlc_BearerConfig2->servedRadioBearer->present = NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity; - rlc_BearerConfig2->servedRadioBearer->choice.srb_Identity = 2; - rlc_BearerConfig2->reestablishRLC = NULL; - rlc_Config2 = calloc(1, sizeof(NR_RLC_Config_t)); - rlc_Config2->present = NR_RLC_Config_PR_am; - rlc_Config2->choice.am = calloc(1, sizeof(*rlc_Config2->choice.am)); - rlc_Config2->choice.am->dl_AM_RLC.sn_FieldLength = calloc(1, sizeof(NR_SN_FieldLengthAM_t)); - *(rlc_Config2->choice.am->dl_AM_RLC.sn_FieldLength) = NR_SN_FieldLengthAM_size12; - rlc_Config2->choice.am->dl_AM_RLC.t_Reassembly = NR_T_Reassembly_ms35; - rlc_Config2->choice.am->dl_AM_RLC.t_StatusProhibit = NR_T_StatusProhibit_ms0; - rlc_Config2->choice.am->ul_AM_RLC.sn_FieldLength = calloc(1, sizeof(NR_SN_FieldLengthAM_t)); - *(rlc_Config2->choice.am->ul_AM_RLC.sn_FieldLength) = NR_SN_FieldLengthAM_size12; - rlc_Config2->choice.am->ul_AM_RLC.t_PollRetransmit = NR_T_PollRetransmit_ms45; - rlc_Config2->choice.am->ul_AM_RLC.pollPDU = NR_PollPDU_infinity; - rlc_Config2->choice.am->ul_AM_RLC.pollByte = NR_PollByte_infinity; - rlc_Config2->choice.am->ul_AM_RLC.maxRetxThreshold = NR_UL_AM_RLC__maxRetxThreshold_t8; - rlc_BearerConfig2->rlc_Config = rlc_Config2; - logicalChannelConfig2 = calloc(1, sizeof(NR_LogicalChannelConfig_t)); - logicalChannelConfig2->ul_SpecificParameters = calloc(1, sizeof(*logicalChannelConfig2->ul_SpecificParameters)); - logicalChannelConfig2->ul_SpecificParameters->priority = 1; - logicalChannelConfig2->ul_SpecificParameters->prioritisedBitRate = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; - logicalChannelGroup2 = CALLOC(1, sizeof(long)); - *logicalChannelGroup2 = 0; - logicalChannelConfig2->ul_SpecificParameters->logicalChannelGroup = logicalChannelGroup2; - logicalChannelConfig2->ul_SpecificParameters->schedulingRequestID = CALLOC(1, sizeof(*logicalChannelConfig2->ul_SpecificParameters->schedulingRequestID)); - *logicalChannelConfig2->ul_SpecificParameters->schedulingRequestID = 0; - logicalChannelConfig2->ul_SpecificParameters->logicalChannelSR_Mask = 0; - logicalChannelConfig2->ul_SpecificParameters->logicalChannelSR_DelayTimerApplied = 0; - rlc_BearerConfig2->mac_LogicalChannelConfig = logicalChannelConfig2; - ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig2); - */ cellGroupConfig->rlc_BearerToReleaseList = NULL; @@ -1653,13 +1612,14 @@ int16_t do_RRCReconfiguration( // *security_config->keyToUse = NR_SecurityConfig__keyToUse_master; ie = calloc(1, sizeof(NR_RRCReconfiguration_IEs_t)); - ie->radioBearerConfig = calloc(1, sizeof(NR_RadioBearerConfig_t)); - ie->radioBearerConfig->srb_ToAddModList = SRB_configList; - ie->radioBearerConfig->drb_ToAddModList = DRB_configList; - ie->radioBearerConfig->securityConfig = security_config; - ie->radioBearerConfig->srb3_ToRelease = NULL; - ie->radioBearerConfig->drb_ToReleaseList = DRB_releaseList; - + if (SRB_configList || DRB_configList) { + ie->radioBearerConfig = calloc(1, sizeof(NR_RadioBearerConfig_t)); + ie->radioBearerConfig->srb_ToAddModList = SRB_configList; + ie->radioBearerConfig->drb_ToAddModList = DRB_configList; + ie->radioBearerConfig->securityConfig = security_config; + ie->radioBearerConfig->srb3_ToRelease = NULL; + ie->radioBearerConfig->drb_ToReleaseList = DRB_releaseList; + } /******************** Secondary Cell Group ********************/ // rrc_gNB_carrier_data_t *carrier = &(gnb_rrc_inst->carrier); // fill_default_secondaryCellGroup( carrier->servingcellconfigcommon, diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 5efb2e1e644edebd75fd9463680af8ff3aeee4f1..5fd9b5d638076623cc2b3c93737094a0724fbd90 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -356,7 +356,7 @@ typedef struct gNB_RRC_UE_s { /* list of e_rab to be setup by RRC layers */ /* list of pdu session to be setup by RRC layers */ e_rab_param_t e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB]; - pdu_session_param_t pdusession[NR_NB_RB_MAX];//[NGAP_MAX_PDU_SESSION]; + pdu_session_param_t pduSession[NR_NB_RB_MAX];//[NGAP_MAX_PDU_SESSION]; //release e_rabs uint8_t nb_release_of_e_rabs; e_rab_failed_t e_rabs_release_failed[S1AP_MAX_E_RAB]; @@ -381,6 +381,7 @@ typedef struct gNB_RRC_UE_s { uint32_t ue_reestablishment_timer_thres; uint8_t e_rab_release_command_flag; uint8_t pdu_session_release_command_flag; + uint8_t established_pdu_sessions_flag; uint32_t ue_rrc_inactivity_timer; int8_t reestablishment_xid; //------------------------------------------------------------------------------// diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index ff7547832e5bf28a1f66791eac1896e5dbe7fc0e..20656deff4ca246a049bedb8ef2512592cd770c6 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -106,6 +106,13 @@ int generate_CG_Config(gNB_RRC_INST *rrc, NR_RRCReconfiguration_t *reconfig, NR_RadioBearerConfig_t *rbconfig); +void apply_macrlc_config(gNB_RRC_INST *rrc, + rrc_gNB_ue_context_t *const ue_context_pP, + const protocol_ctxt_t *const ctxt_pP ); + +void apply_pdcp_config(rrc_gNB_ue_context_t *const ue_context_pP, + const protocol_ctxt_t *const ctxt_pP ); + void rrc_gNB_generate_RRCSetup( const protocol_ctxt_t *const ctxt_pP, diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 23e3391c853b824e22e081770ede83baee7ba1d2..8ad6b5c8e600aafe95bad7088a542205a0e739d5 100755 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -378,6 +378,46 @@ rrc_gNB_get_next_transaction_identifier( return nr_rrc_transaction_identifier[gnb_mod_idP]; } +void apply_macrlc_config(gNB_RRC_INST *rrc, + rrc_gNB_ue_context_t *const ue_context_pP, + const protocol_ctxt_t *const ctxt_pP ) { + + rrc_mac_config_req_gNB(rrc->module_id, + rrc->carrier.ssb_SubcarrierOffset, + rrc->carrier.pdsch_AntennaPorts, + rrc->carrier.pusch_AntennaPorts, + NULL, + 0, + ue_context_pP->ue_context.rnti, + get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup : (NR_CellGroupConfig_t *)NULL); + + nr_rrc_rlc_config_asn1_req(ctxt_pP, + ue_context_pP->ue_context.SRB_configList, + NULL, + NULL, + NULL, + get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL); + +} + +void apply_pdcp_config(rrc_gNB_ue_context_t *const ue_context_pP, + const protocol_ctxt_t *const ctxt_pP ) { + + nr_rrc_pdcp_config_asn1_req(ctxt_pP, + ue_context_pP->ue_context.SRB_configList, + NULL, + NULL, + 0xff, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL); + +} + //----------------------------------------------------------------------------- void rrc_gNB_generate_RRCSetup( @@ -487,34 +527,9 @@ rrc_gNB_generate_RRCSetup( // ue_context_pP->ue_context.ue_rrc_inactivity_timer = 0; // configure MAC - rrc_mac_config_req_gNB(rrc->module_id, - rrc->carrier.ssb_SubcarrierOffset, - rrc->carrier.pdsch_AntennaPorts, - rrc->carrier.pusch_AntennaPorts, - NULL, - 0, - ue_context_pP->ue_context.rnti, - get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup : (NR_CellGroupConfig_t *)NULL); - - nr_rrc_rlc_config_asn1_req(ctxt_pP, - ue_context_pP->ue_context.SRB_configList, - NULL, - NULL, - NULL, - get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL); + apply_macrlc_config(rrc,ue_context_pP,ctxt_pP); - nr_rrc_pdcp_config_asn1_req(ctxt_pP, - ue_context_pP->ue_context.SRB_configList, - NULL, - NULL, - 0xff, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL); + apply_pdcp_config(ue_context_pP,ctxt_pP); #endif } break; @@ -784,6 +799,22 @@ rrc_gNB_generate_defaultRRCReconfiguration( dedicatedNAS_MessageList = CALLOC(1, sizeof(struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList)); + /* Add all NAS PDUs to the list */ + for (int i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) { + if (ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer != NULL) { + dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t)); + memset(dedicatedNAS_Message, 0, sizeof(OCTET_STRING_t)); + OCTET_STRING_fromBuf(dedicatedNAS_Message, + (char *)ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer, + ue_context_pP->ue_context.pduSession[i].param.nas_pdu.length); + ASN_SEQUENCE_ADD(&dedicatedNAS_MessageList->list, dedicatedNAS_Message); + } + + ue_context_pP->ue_context.pduSession[i].status = PDU_SESSION_STATUS_DONE; + LOG_D(NR_RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n", + i, ue_context_pP->ue_context.pduSession[i].status, "PDU_SESSION_STATUS_DONE"); + } + if (ue_context_pP->ue_context.nas_pdu_flag == 1) { dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t)); memset(dedicatedNAS_Message, 0, sizeof(OCTET_STRING_t)); @@ -815,6 +846,15 @@ rrc_gNB_generate_defaultRRCReconfiguration( free(ue_context_pP->ue_context.nas_pdu.buffer); LOG_DUMPMSG(NR_RRC, DEBUG_RRC,(char *)buffer, size, "[MSG] RRC Reconfiguration\n"); + + /* Free all NAS PDUs */ + for (int i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) { + if (ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer != NULL) { + free(ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer); + ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer = NULL; + } + } + LOG_I(NR_RRC, "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate NR_RRCReconfiguration (bytes %d, UE id %x)\n", ctxt_pP->module_id, ctxt_pP->frame, @@ -916,15 +956,14 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( /* Configure SRB2 */ SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[xid]; - if (*SRB_configList2) { - free(*SRB_configList2); + if (*SRB_configList2 == NULL) { + *SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2)); + memset(*SRB_configList2, 0, sizeof(**SRB_configList2)); + SRB2_config = CALLOC(1, sizeof(*SRB2_config)); + SRB2_config->srb_Identity = 2; + ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config); + ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config); } - *SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2)); - memset(*SRB_configList2, 0, sizeof(**SRB_configList2)); - SRB2_config = CALLOC(1, sizeof(*SRB2_config)); - SRB2_config->srb_Identity = 2; - ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config); - ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config); DRB_configList = &ue_context_pP->ue_context.DRB_configList; if (*DRB_configList) { @@ -947,7 +986,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( break; } - if (ue_context_pP->ue_context.pdusession[i].status >= PDU_SESSION_STATUS_DONE) { + if (ue_context_pP->ue_context.pduSession[i].status >= PDU_SESSION_STATUS_DONE) { continue; } @@ -958,15 +997,15 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( // sdap_Config sdap_config = CALLOC(1, sizeof(NR_SDAP_Config_t)); memset(sdap_config, 0, sizeof(NR_SDAP_Config_t)); - sdap_config->pdu_Session = ue_context_pP->ue_context.pdusession[i].param.pdusession_id; + sdap_config->pdu_Session = ue_context_pP->ue_context.pduSession[i].param.pdusession_id; sdap_config->sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_absent; - sdap_config->sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_present; + sdap_config->sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_absent; sdap_config->defaultDRB = TRUE; sdap_config->mappedQoS_FlowsToAdd = calloc(1, sizeof(struct NR_SDAP_Config__mappedQoS_FlowsToAdd)); memset(sdap_config->mappedQoS_FlowsToAdd, 0, sizeof(struct NR_SDAP_Config__mappedQoS_FlowsToAdd)); - for (qos_flow_index = 0; qos_flow_index < ue_context_pP->ue_context.pdusession[i].param.nb_qos; qos_flow_index++) { - qfi = ue_context_pP->ue_context.pdusession[i].param.qos[qos_flow_index].qfi; + for (qos_flow_index = 0; qos_flow_index < ue_context_pP->ue_context.pduSession[i].param.nb_qos; qos_flow_index++) { + qfi = ue_context_pP->ue_context.pduSession[i].param.qos[qos_flow_index].qfi; ASN_SEQUENCE_ADD(&sdap_config->mappedQoS_FlowsToAdd->list, &qfi); } sdap_config->mappedQoS_FlowsToRelease = NULL; @@ -996,8 +1035,8 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( DRB_config->pdcp_Config->ext1 = NULL; // Reference TS23501 Table 5.7.4-1: Standardized 5QI to QoS characteristics mapping - for (qos_flow_index = 0; qos_flow_index < ue_context_pP->ue_context.pdusession[i].param.nb_qos; qos_flow_index++) { - switch (ue_context_pP->ue_context.pdusession[i].param.qos[qos_flow_index].fiveQI) { + for (qos_flow_index = 0; qos_flow_index < ue_context_pP->ue_context.pduSession[i].param.nb_qos; qos_flow_index++) { + switch (ue_context_pP->ue_context.pduSession[i].param.qos[qos_flow_index].fiveQI) { case 1: //100ms case 2: //150ms case 3: //50ms @@ -1011,9 +1050,9 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( break; default: - LOG_E(NR_RRC,"not supported 5qi %lu\n", ue_context_pP->ue_context.pdusession[i].param.qos[qos_flow_index].fiveQI); - ue_context_pP->ue_context.pdusession[i].status = PDU_SESSION_STATUS_FAILED; - ue_context_pP->ue_context.pdusession[i].xid = xid; + LOG_E(NR_RRC,"not supported 5qi %lu\n", ue_context_pP->ue_context.pduSession[i].param.qos[qos_flow_index].fiveQI); + ue_context_pP->ue_context.pduSession[i].status = PDU_SESSION_STATUS_FAILED; + ue_context_pP->ue_context.pduSession[i].xid = xid; pdu_sessions_done++; free(DRB_config); continue; @@ -1023,18 +1062,18 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( ASN_SEQUENCE_ADD(&(*DRB_configList)->list, DRB_config); ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config); - ue_context_pP->ue_context.pdusession[i].status = PDU_SESSION_STATUS_DONE; - ue_context_pP->ue_context.pdusession[i].xid = xid; + ue_context_pP->ue_context.pduSession[i].status = PDU_SESSION_STATUS_DONE; + ue_context_pP->ue_context.pduSession[i].xid = xid; - if (ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer != NULL) { + if (ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer != NULL) { dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t)); memset(dedicatedNAS_Message, 0, sizeof(OCTET_STRING_t)); OCTET_STRING_fromBuf(dedicatedNAS_Message, - (char *)ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer, - ue_context_pP->ue_context.pdusession[i].param.nas_pdu.length); + (char *)ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer, + ue_context_pP->ue_context.pduSession[i].param.nas_pdu.length); ASN_SEQUENCE_ADD(&dedicatedNAS_MessageList->list, dedicatedNAS_Message); - LOG_I(NR_RRC,"add NAS info with size %d (pdusession id %d)\n",ue_context_pP->ue_context.pdusession[i].param.nas_pdu.length, i); + LOG_I(NR_RRC,"add NAS info with size %d (pdusession id %d)\n",ue_context_pP->ue_context.pduSession[i].param.nas_pdu.length, i); } else { // TODO LOG_E(NR_RRC,"no NAS info (pdusession id %d)\n", i); @@ -1065,10 +1104,10 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( /* Free all NAS PDUs */ for (i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) { - if (ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer != NULL) { + if (ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer != NULL) { /* Free the NAS PDU buffer and invalidate it */ - free(ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer); - ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer = NULL; + free(ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer); + ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer = NULL; } } @@ -1137,7 +1176,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release( *DRB_Release_configList2 = CALLOC(1, sizeof(**DRB_Release_configList2)); for(i = 0; i < NB_RB_MAX; i++) { - if((ue_context_pP->ue_context.pdusession[i].status == PDU_SESSION_STATUS_TORELEASE) && ue_context_pP->ue_context.pdusession[i].xid == xid) { + if((ue_context_pP->ue_context.pduSession[i].status == PDU_SESSION_STATUS_TORELEASE) && ue_context_pP->ue_context.pduSession[i].xid == xid) { DRB_release = CALLOC(1, sizeof(NR_DRB_Identity_t)); *DRB_release = i+1; ASN_SEQUENCE_ADD(&(*DRB_Release_configList2)->list, DRB_release); @@ -1238,6 +1277,7 @@ rrc_gNB_process_RRCReconfigurationComplete( NR_DRB_ToReleaseList_t *DRB_Release_configList2 = ue_context_pP->ue_context.DRB_Release_configList2[xid]; NR_DRB_Identity_t *drb_id_p = NULL; // uint8_t nr_DRB2LCHAN[8]; + gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; ue_context_pP->ue_context.ue_reestablishment_timer = 0; @@ -1268,7 +1308,7 @@ rrc_gNB_process_RRCReconfigurationComplete( SRB_configList, // NULL, DRB_configList, DRB_Release_configList2, - 0xff, // already configured during the securitymodecommand + 0, // already configured during the securitymodecommand kRRCenc, kRRCint, kUPenc, @@ -1278,6 +1318,15 @@ rrc_gNB_process_RRCReconfigurationComplete( get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL); /* Refresh SRBs/DRBs */ if (!NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) { + rrc_mac_config_req_gNB(rrc->module_id, + rrc->carrier.ssb_SubcarrierOffset, + rrc->carrier.pdsch_AntennaPorts, + rrc->carrier.pusch_AntennaPorts, + NULL, + 0, + ue_context_pP->ue_context.rnti, + ue_context_pP->ue_context.masterCellGroup + ); LOG_D(NR_RRC,"Configuring RLC DRBs/SRBs for UE %x\n",ue_context_pP->ue_context.rnti); nr_rrc_rlc_config_asn1_req(ctxt_pP, SRB_configList, // NULL, @@ -1592,13 +1641,13 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete( memset(&create_tunnel_req, 0, sizeof(create_tunnel_req)); for ( j = 0, i = 0; i < NB_RB_MAX; i++) { - if (ue_context_pP->ue_context.pdusession[i].status == PDU_SESSION_STATUS_ESTABLISHED || ue_context_pP->ue_context.pdusession[i].status == PDU_SESSION_STATUS_DONE) { - create_tunnel_req.pdusession_id[j] = ue_context_pP->ue_context.pdusession[i].param.pdusession_id; - create_tunnel_req.upf_NGu_teid[j] = ue_context_pP->ue_context.pdusession[i].param.gtp_teid; + if (ue_context_pP->ue_context.pduSession[i].status == PDU_SESSION_STATUS_ESTABLISHED || ue_context_pP->ue_context.pduSession[i].status == PDU_SESSION_STATUS_DONE) { + create_tunnel_req.pdusession_id[j] = ue_context_pP->ue_context.pduSession[i].param.pdusession_id; + create_tunnel_req.upf_NGu_teid[j] = ue_context_pP->ue_context.pduSession[i].param.gtp_teid; memcpy(create_tunnel_req.upf_addr[j].buffer, - ue_context_pP->ue_context.pdusession[i].param.upf_addr.buffer, + ue_context_pP->ue_context.pduSession[i].param.upf_addr.buffer, sizeof(uint8_t)*20); - create_tunnel_req.upf_addr[j].length = ue_context_pP->ue_context.pdusession[i].param.upf_addr.length; + create_tunnel_req.upf_addr[j].length = ue_context_pP->ue_context.pduSession[i].param.upf_addr.length; j++; } } @@ -1658,10 +1707,10 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete( /* TODO parameters yet to process ... */ /* TODO should test if pdu session are Ok before! */ - ue_context_pP->ue_context.pdusession[i].status = PDU_SESSION_STATUS_DONE; - ue_context_pP->ue_context.pdusession[i].xid = xid; + ue_context_pP->ue_context.pduSession[i].status = PDU_SESSION_STATUS_DONE; + ue_context_pP->ue_context.pduSession[i].xid = xid; LOG_D(NR_RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n", - i, ue_context_pP->ue_context.pdusession[i].status, "PDU_SESSION_STATUS_DONE"); + i, ue_context_pP->ue_context.pduSession[i].status, "PDU_SESSION_STATUS_DONE"); } memset(buffer, 0, RRC_BUF_SIZE); @@ -1682,10 +1731,10 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete( /* Free all NAS PDUs */ for (i = 0; i < ue_context_pP->ue_context.nb_of_pdusessions; i++) { - if (ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer != NULL) { + if (ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer != NULL) { /* Free the NAS PDU buffer and invalidate it */ - free(ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer); - ue_context_pP->ue_context.pdusession[i].param.nas_pdu.buffer = NULL; + free(ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer); + ue_context_pP->ue_context.pduSession[i].param.nas_pdu.buffer = NULL; } } @@ -2015,10 +2064,10 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, ue_context_p->ue_context.reestablishment_xid); for (uint8_t pdusessionid = 0; pdusessionid < ue_context_p->ue_context.nb_of_pdusessions; pdusessionid++) { - if (ue_context_p->ue_context.pdusession[pdusessionid].status == PDU_SESSION_STATUS_DONE) { - ue_context_p->ue_context.pdusession[pdusessionid].status = PDU_SESSION_STATUS_ESTABLISHED; + if (ue_context_p->ue_context.pduSession[pdusessionid].status == PDU_SESSION_STATUS_DONE) { + ue_context_p->ue_context.pduSession[pdusessionid].status = PDU_SESSION_STATUS_ESTABLISHED; } else { - ue_context_p->ue_context.pdusession[pdusessionid].status = PDU_SESSION_STATUS_FAILED; + ue_context_p->ue_context.pduSession[pdusessionid].status = PDU_SESSION_STATUS_FAILED; } } } @@ -2264,7 +2313,7 @@ rrc_gNB_decode_dcch( GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti; for(i = 0; i < NB_RB_MAX; i++) { - if(xid == ue_context_p->ue_context.pdusession[i].xid) { + if(xid == ue_context_p->ue_context.pduSession[i].xid) { GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).pdusession_id[GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_pdusession++] = ue_context_p->ue_context.gnb_gtp_psi[i]; ue_context_p->ue_context.gnb_gtp_teid[i] = 0; @@ -2276,13 +2325,14 @@ rrc_gNB_decode_dcch( itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->instance, msg_delete_tunnels_p); //NGAP_PDUSESSION_RELEASE_RESPONSE rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE(ctxt_pP, ue_context_p, xid); - } else { - rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(ctxt_pP, - ue_context_p, - ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier); + } else if (ue_context_p->ue_context.established_pdu_sessions_flag != 1) { + if (ue_context_p->ue_context.setup_pdu_sessions > 0) { + rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(ctxt_pP, + ue_context_p, + ul_dcch_msg->message.choice.c1->choice.rrcReconfigurationComplete->rrc_TransactionIdentifier); + } } } - if (first_rrcreconfiguration == 0){ first_rrcreconfiguration = 1; rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p); @@ -2563,7 +2613,13 @@ rrc_gNB_decode_dcch( ue_context_p, ul_dcch_msg); } - rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p); + + if (ue_context_p->ue_context.established_pdu_sessions_flag == 1) { + rrc_gNB_generate_dedicatedRRCReconfiguration(ctxt_pP, ue_context_p); + } else { + rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p); + } + break; case NR_UL_DCCH_MessageType__c1_PR_rrcReestablishmentComplete: @@ -2771,8 +2827,290 @@ void rrc_gNB_process_dc_overall_timeout(const module_id_t gnb_mod_idP, x2ap_ENDC rrc_remove_nsa_user(rrc, m->rnti); } +unsigned int mask_flip(unsigned int x) { + return((((x>>8) + (x<<8))&0xffff)>>6); +} + +unsigned int get_dl_bw_mask(gNB_RRC_INST *rrc,NR_UE_NR_Capability_t *cap) { + + + int common_band = *rrc->carrier.servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; + int common_scs = rrc->carrier.servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; + for (int i=0;i<cap->rf_Parameters.supportedBandListNR.list.count;i++) { + NR_BandNR_t *bandNRinfo = cap->rf_Parameters.supportedBandListNR.list.array[i]; + if (bandNRinfo->bandNR == common_band) { + if (common_band < 257) { // FR1 + switch (common_scs) { + case NR_SubcarrierSpacing_kHz15 : + if (bandNRinfo->channelBWs_DL && + bandNRinfo->channelBWs_DL->choice.fr1 && + bandNRinfo->channelBWs_DL->choice.fr1->scs_15kHz) + return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_DL->choice.fr1->scs_15kHz->buf)); + break; + case NR_SubcarrierSpacing_kHz30 : + if (bandNRinfo->channelBWs_DL && + bandNRinfo->channelBWs_DL->choice.fr1 && + bandNRinfo->channelBWs_DL->choice.fr1->scs_30kHz) + return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_DL->choice.fr1->scs_30kHz->buf)); + break; + case NR_SubcarrierSpacing_kHz60 : + if (bandNRinfo->channelBWs_DL && + bandNRinfo->channelBWs_DL->choice.fr1 && + bandNRinfo->channelBWs_DL->choice.fr1->scs_60kHz) + return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_DL->choice.fr1->scs_60kHz->buf)); + break; + } + } + else { + switch (common_scs) { + case NR_SubcarrierSpacing_kHz60 : + if (bandNRinfo->channelBWs_DL && + bandNRinfo->channelBWs_DL->choice.fr2 && + bandNRinfo->channelBWs_DL->choice.fr2->scs_60kHz) + return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_DL->choice.fr2->scs_60kHz->buf)); + break; + case NR_SubcarrierSpacing_kHz120 : + if (bandNRinfo->channelBWs_DL && + bandNRinfo->channelBWs_DL->choice.fr2 && + bandNRinfo->channelBWs_DL->choice.fr2->scs_120kHz) + return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_DL->choice.fr2->scs_120kHz->buf)); + break; + } + } + } + } + return(0); +} + +unsigned int get_ul_bw_mask(gNB_RRC_INST *rrc,NR_UE_NR_Capability_t *cap) { + + + int common_band = *rrc->carrier.servingcellconfigcommon->uplinkConfigCommon->frequencyInfoUL->frequencyBandList->list.array[0]; + int common_scs = rrc->carrier.servingcellconfigcommon->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; + for (int i=0;i<cap->rf_Parameters.supportedBandListNR.list.count;i++) { + NR_BandNR_t *bandNRinfo = cap->rf_Parameters.supportedBandListNR.list.array[i]; + if (bandNRinfo->bandNR == common_band) { + if (common_band < 257) { // FR1 + switch (common_scs) { + case NR_SubcarrierSpacing_kHz15 : + if (bandNRinfo->channelBWs_UL && + bandNRinfo->channelBWs_UL->choice.fr1 && + bandNRinfo->channelBWs_UL->choice.fr1->scs_15kHz) + return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_UL->choice.fr1->scs_15kHz->buf)); + break; + case NR_SubcarrierSpacing_kHz30 : + if (bandNRinfo->channelBWs_UL && + bandNRinfo->channelBWs_UL->choice.fr1 && + bandNRinfo->channelBWs_UL->choice.fr1->scs_30kHz) + return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_UL->choice.fr1->scs_30kHz->buf)); + break; + case NR_SubcarrierSpacing_kHz60 : + if (bandNRinfo->channelBWs_UL && + bandNRinfo->channelBWs_UL->choice.fr1 && + bandNRinfo->channelBWs_UL->choice.fr1->scs_60kHz) + return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_UL->choice.fr1->scs_60kHz->buf)); + break; + } + } + else { + switch (common_scs) { + case NR_SubcarrierSpacing_kHz60 : + if (bandNRinfo->channelBWs_UL && + bandNRinfo->channelBWs_UL->choice.fr2 && + bandNRinfo->channelBWs_UL->choice.fr2->scs_60kHz) + return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_UL->choice.fr2->scs_60kHz->buf)); + break; + case NR_SubcarrierSpacing_kHz120 : + if (bandNRinfo->channelBWs_UL && + bandNRinfo->channelBWs_UL->choice.fr2 && + bandNRinfo->channelBWs_UL->choice.fr2->scs_120kHz) + return(mask_flip((unsigned int)*(uint16_t*)bandNRinfo->channelBWs_UL->choice.fr2->scs_120kHz->buf)); + break; + } + } + } + } + return(0); +} + +int is_dl_256QAM_supported(gNB_RRC_INST *rrc,NR_UE_NR_Capability_t *cap) { + int common_band = *rrc->carrier.servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; + int common_scs = rrc->carrier.servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; + if (common_band>256) { + for (int i=0;i<cap->rf_Parameters.supportedBandListNR.list.count;i++) { + NR_BandNR_t *bandNRinfo = cap->rf_Parameters.supportedBandListNR.list.array[i]; + if (bandNRinfo->bandNR == common_band && !bandNRinfo->pdsch_256QAM_FR2) return (0); + } + } + else if (cap->phy_Parameters.phy_ParametersFR1 && !cap->phy_Parameters.phy_ParametersFR1->pdsch_256QAM_FR1) return(0); + + // check featureSet + NR_FeatureSets_t *fs=cap->featureSets; + if (fs) { + // go through DL feature sets and look for one with current SCS + for (int i=0;i<fs->featureSetsDownlinkPerCC->list.count;i++) { + if (fs->featureSetsDownlinkPerCC->list.array[i]->supportedSubcarrierSpacingDL == common_scs && + fs->featureSetsDownlinkPerCC->list.array[i]->supportedModulationOrderDL && + *fs->featureSetsDownlinkPerCC->list.array[i]->supportedModulationOrderDL == NR_ModulationOrder_qam256) return(1); + } + } + return(0); +} + +int is_ul_256QAM_supported(gNB_RRC_INST *rrc,NR_UE_NR_Capability_t *cap) { + int common_band = *rrc->carrier.servingcellconfigcommon->uplinkConfigCommon->frequencyInfoUL->frequencyBandList->list.array[0]; + int common_scs = rrc->carrier.servingcellconfigcommon->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; + for (int i=0;i<cap->rf_Parameters.supportedBandListNR.list.count;i++) { + NR_BandNR_t *bandNRinfo = cap->rf_Parameters.supportedBandListNR.list.array[i]; + if (bandNRinfo->bandNR == common_band && !bandNRinfo->pusch_256QAM) return (0); + } + + // check featureSet + NR_FeatureSets_t *fs=cap->featureSets; + if (fs) { + // go through UL feature sets and look for one with current SCS + for (int i=0;i<fs->featureSetsUplinkPerCC->list.count;i++) { + if (fs->featureSetsUplinkPerCC->list.array[i]->supportedSubcarrierSpacingUL == common_scs && + fs->featureSetsUplinkPerCC->list.array[i]->supportedModulationOrderUL && + *fs->featureSetsUplinkPerCC->list.array[i]->supportedModulationOrderUL == NR_ModulationOrder_qam256) return(1); + } + } + return(0); +} + +int get_ul_mimo_layersCB(gNB_RRC_INST *rrc,NR_UE_NR_Capability_t *cap) { + int common_scs = rrc->carrier.servingcellconfigcommon->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; + + // check featureSet + NR_FeatureSets_t *fs=cap->featureSets; + if (fs) { + // go through UL feature sets and look for one with current SCS + for (int i=0;i<fs->featureSetsUplinkPerCC->list.count;i++) { + if (fs->featureSetsUplinkPerCC->list.array[i]->supportedSubcarrierSpacingUL == common_scs && + fs->featureSetsUplinkPerCC->list.array[i]->mimo_CB_PUSCH && + fs->featureSetsUplinkPerCC->list.array[i]->mimo_CB_PUSCH->maxNumberMIMO_LayersCB_PUSCH) + return(1<<*fs->featureSetsUplinkPerCC->list.array[i]->mimo_CB_PUSCH->maxNumberMIMO_LayersCB_PUSCH); + } + } + return(1); +} + +int get_ul_mimo_layers(gNB_RRC_INST *rrc,NR_UE_NR_Capability_t *cap) { + int common_scs = rrc->carrier.servingcellconfigcommon->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; + + // check featureSet + NR_FeatureSets_t *fs=cap->featureSets; + if (fs) { + // go through UL feature sets and look for one with current SCS + for (int i=0;i<fs->featureSetsUplinkPerCC->list.count;i++) { + if (fs->featureSetsUplinkPerCC->list.array[i]->supportedSubcarrierSpacingUL == common_scs && + fs->featureSetsUplinkPerCC->list.array[i]->maxNumberMIMO_LayersNonCB_PUSCH) + return(1<<*fs->featureSetsUplinkPerCC->list.array[i]->maxNumberMIMO_LayersNonCB_PUSCH); + } + } + return(1); +} + +int get_dl_mimo_layers(gNB_RRC_INST *rrc,NR_UE_NR_Capability_t *cap) { + int common_scs = rrc->carrier.servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; + + // check featureSet + NR_FeatureSets_t *fs=cap->featureSets; + if (fs) { + // go through UL feature sets and look for one with current SCS + for (int i=0;i<fs->featureSetsDownlinkPerCC->list.count;i++) { + if (fs->featureSetsUplinkPerCC->list.array[i]->supportedSubcarrierSpacingUL == common_scs && + fs->featureSetsDownlinkPerCC->list.array[i]->maxNumberMIMO_LayersPDSCH) + return(2<<*fs->featureSetsDownlinkPerCC->list.array[i]->maxNumberMIMO_LayersPDSCH); + } + } + return(1); +} void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) { + MessageDef *msg; + rrc_gNB_ue_context_t *ue_context_p = NULL; + FILE *fd=NULL;//fopen("nrRRCstats.log","w"); + RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &(RC.nrrrc[ctxt_pP->module_id]->rrc_ue_head)) { + ctxt_pP->rnti = ue_context_p->ue_id_rnti; + + if (fd) { + if (ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.presence == TRUE) { + fprintf(fd,"NR RRC UE rnti %x: S-TMSI %x failure timer %d/8\n", + ue_context_p->ue_id_rnti, + ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.fiveg_tmsi, + ue_context_p->ue_context.ul_failure_timer); + } else { + fprintf(fd,"NR RRC UE rnti %x failure timer %d/8\n", + ue_context_p->ue_id_rnti, + ue_context_p->ue_context.ul_failure_timer); + } + + if (ue_context_p->ue_context.UE_Capability_nr) { + fprintf(fd,"NR RRC UE cap: BW DL %x. BW UL %x, 256 QAM DL %s, 256 QAM UL %s, DL MIMO Layers %d UL MIMO Layers (CB) %d UL MIMO Layers (nonCB) %d\n", + get_dl_bw_mask(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr), + get_ul_bw_mask(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr), + is_dl_256QAM_supported(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr) == 1 ? "yes" : "no", + is_ul_256QAM_supported(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr) == 1 ? "yes" : "no", + get_dl_mimo_layers(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr), + get_ul_mimo_layersCB(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr), + get_ul_mimo_layers(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr)); + } + } + if (ue_context_p->ue_context.ul_failure_timer > 0) { + ue_context_p->ue_context.ul_failure_timer++; + + if (ue_context_p->ue_context.ul_failure_timer >= 20000) { + // remove UE after 20 seconds after MAC (or else) has indicated UL failure + LOG_I(RRC, "Removing UE %x instance, because of uplink failure timer timeout\n", + ue_context_p->ue_context.rnti); + if(ue_context_p->ue_context.StatusRrc >= NR_RRC_CONNECTED){ + rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ( + ctxt_pP->module_id, + ue_context_p, + NGAP_CAUSE_RADIO_NETWORK, + 30); + }else{ + mac_remove_nr_ue(ctxt_pP->module_id, ctxt_pP->rnti); + rrc_rlc_remove_ue(ctxt_pP); + pdcp_remove_UE(ctxt_pP); + + /* remove RRC UE Context */ + ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rnti); + if (ue_context_p) { + rrc_gNB_remove_ue_context(ctxt_pP, RC.nrrrc[ctxt_pP->module_id], ue_context_p); + LOG_I(NR_RRC, "remove UE %x \n", ctxt_pP->rnti); + } + } + break; // break RB_FOREACH + } + } + + if (ue_context_p->ue_context.ue_release_timer_rrc > 0) { + ue_context_p->ue_context.ue_release_timer_rrc++; + + if (ue_context_p->ue_context.ue_release_timer_rrc >= ue_context_p->ue_context.ue_release_timer_thres_rrc) { + LOG_I(NR_RRC, "Removing UE %x instance after UE_CONTEXT_RELEASE_Complete (ue_release_timer_rrc timeout)\n", + ue_context_p->ue_context.rnti); + ue_context_p->ue_context.ue_release_timer_rrc = 0; + + mac_remove_nr_ue(ctxt_pP->module_id, ctxt_pP->rnti); + rrc_rlc_remove_ue(ctxt_pP); + pdcp_remove_UE(ctxt_pP); + + /* remove RRC UE Context */ + ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rnti); + if (ue_context_p) { + rrc_gNB_remove_ue_context(ctxt_pP, RC.nrrrc[ctxt_pP->module_id], ue_context_p); + LOG_I(NR_RRC, "remove UE %x \n", ctxt_pP->rnti); + } + + break; // break RB_FOREACH + } + } + } + + if (fd) fclose(fd); /* send a tick to x2ap */ if (is_x2ap_enabled()){ @@ -2790,7 +3128,6 @@ void *rrc_gnb_task(void *args_p) { int result; //SRB_INFO *srb_info_p; //int CC_id; - protocol_ctxt_t ctxt={.module_id=0, .enb_flag=1, .instance=0, @@ -2801,7 +3138,6 @@ void *rrc_gnb_task(void *args_p) { .configured=true, .brOption=false }; - itti_mark_task_ready(TASK_RRC_GNB); LOG_I(NR_RRC,"Entering main loop of NR_RRC message task\n"); @@ -3242,11 +3578,13 @@ rrc_gNB_generate_RRCRelease( itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); #else if (NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) { + uint8_t *message_buffer = itti_malloc (TASK_RRC_GNB, TASK_CU_F1, size); + memcpy (message_buffer, buffer, size); MessageDef *m = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_CMD); F1AP_UE_CONTEXT_RELEASE_CMD(m).rnti = ctxt_pP->rnti; F1AP_UE_CONTEXT_RELEASE_CMD(m).cause = F1AP_CAUSE_RADIO_NETWORK; F1AP_UE_CONTEXT_RELEASE_CMD(m).cause_value = 10; // 10 = F1AP_CauseRadioNetwork_normal_release - F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container = buffer; + F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container = message_buffer; F1AP_UE_CONTEXT_RELEASE_CMD(m).rrc_container_length = size; itti_send_msg_to_task(TASK_CU_F1, ctxt_pP->module_id, m); } else { @@ -3257,6 +3595,9 @@ rrc_gNB_generate_RRCRelease( size, buffer, PDCP_TRANSMISSION_MODE_CONTROL); + + rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(ctxt_pP->instance, ue_context_pP->ue_context.gNB_ue_ngap_id); + ue_context_pP->ue_context.ue_release_timer_rrc = 1; } #endif } diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 619880da59821a7eb364475715be46ed314b8b97..b7f9d2c671f9653de39bf1c4dd4a6ce5a12d0021 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -57,6 +57,8 @@ #include "RRC/NR/MESSAGES/asn1_msg.h" #include "NR_UERadioAccessCapabilityInformation.h" #include "NR_UE-CapabilityRAT-ContainerList.h" +#include "NGAP_Cause.h" +#include "NGAP_CauseRadioNetwork.h" #include "f1ap_messages_types.h" extern RAN_CONTEXT_t RC; @@ -352,8 +354,8 @@ nr_rrc_pdcp_config_security( if (print_keys == 1 ) { print_keys =0; LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, ue_context_pP->ue_context.kgnb, 32,"\nKgNB:" ); - LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, kRRCenc, 32,"\nKRRCenc:" ); - LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, kRRCint, 32,"\nKRRCint:" ); + LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, kRRCenc, 16,"\nKRRCenc:" ); + LOG_DUMPMSG(NR_RRC, DEBUG_SECURITY, kRRCint, 16,"\nKRRCint:" ); } } @@ -504,6 +506,10 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ( rrc_gNB_ue_context_t *ue_context_p = NULL; protocol_ctxt_t ctxt; uint8_t pdu_sessions_done = 0; + gtpv1u_gnb_create_tunnel_req_t create_tunnel_req; + gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp; + uint8_t inde_list[NR_NB_RB_MAX - 3]= {0}; + int ret = 0; ue_initial_id = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).ue_initial_id; gNB_ue_ngap_id = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).gNB_ue_ngap_id; @@ -527,28 +533,64 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ( ue_context_p->ue_context.amf_ue_ngap_id = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).amf_ue_ngap_id; ue_context_p->ue_context.nas_pdu_flag = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nas_pdu_flag; - if (NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nb_of_pdusessions != 0) { - ue_context_p->ue_context.nb_of_pdusessions = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nb_of_pdusessions; + uint8_t nb_pdusessions_tosetup = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nb_of_pdusessions; + if (nb_pdusessions_tosetup != 0) { + memset(&create_tunnel_req, 0, sizeof(gtpv1u_gnb_create_tunnel_req_t)); for (int i = 0; i < NR_NB_RB_MAX - 3; i++) { - if(ue_context_p->ue_context.pdusession[i].status >= PDU_SESSION_STATUS_DONE) - continue; - ue_context_p->ue_context.pdusession[i].status = PDU_SESSION_STATUS_NEW; - ue_context_p->ue_context.pdusession[i].param = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done]; - pdu_sessions_done++; + if(ue_context_p->ue_context.pduSession[i].status >= PDU_SESSION_STATUS_DONE) + continue; + ue_context_p->ue_context.pduSession[i].status = PDU_SESSION_STATUS_NEW; + ue_context_p->ue_context.pduSession[i].param = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done]; + create_tunnel_req.pdusession_id[pdu_sessions_done] = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].pdusession_id; + create_tunnel_req.upf_NGu_teid[pdu_sessions_done] = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].gtp_teid; + create_tunnel_req.upf_addr[pdu_sessions_done].length = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].upf_addr.length; + memcpy(create_tunnel_req.upf_addr[pdu_sessions_done].buffer, + NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].upf_addr.buffer, + sizeof(uint8_t)*20); + LOG_I(NR_RRC, "PDUSESSION SETUP: local index %d teid %u, pdusession id %d \n", + i, + create_tunnel_req.upf_NGu_teid[pdu_sessions_done], + create_tunnel_req.pdusession_id[pdu_sessions_done]); + inde_list[pdu_sessions_done] = i; + pdu_sessions_done++; + + if(pdu_sessions_done >= nb_pdusessions_tosetup) { + break; + } + } - // TODO establish PDU SESSION + ue_context_p->ue_context.nb_of_pdusessions = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nb_of_pdusessions; + create_tunnel_req.rnti = ue_context_p->ue_context.rnti; + create_tunnel_req.num_tunnels = pdu_sessions_done; - if(pdu_sessions_done >= NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nb_of_pdusessions) { - break; - } + ret = gtpv1u_create_ngu_tunnel( + instance, + &create_tunnel_req, + &create_tunnel_resp); + if (ret != 0) { + LOG_E(NR_RRC,"rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ : gtpv1u_create_ngu_tunnel failed,start to release UE %x\n",ue_context_p->ue_context.rnti); + ue_context_p->ue_context.ue_release_timer_ng = 1; + ue_context_p->ue_context.ue_release_timer_thres_ng = 100; + ue_context_p->ue_context.ue_release_timer = 0; + ue_context_p->ue_context.ue_reestablishment_timer = 0; + ue_context_p->ue_context.ul_failure_timer = 20000; + ue_context_p->ue_context.ul_failure_timer = 0; + return (0); } + + nr_rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( + &ctxt, + &create_tunnel_resp, + &inde_list[0]); + ue_context_p->ue_context.setup_pdu_sessions += nb_pdusessions_tosetup; + ue_context_p->ue_context.established_pdu_sessions_flag = 1; } /* NAS PDU */ - ue_context_p->ue_context.nas_pdu_flag = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu_flag; - if (ue_context_p->ue_context.nas_pdu_flag == 1) { - ue_context_p->ue_context.nas_pdu.length = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu.length; - ue_context_p->ue_context.nas_pdu.buffer = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu.buffer; + if (NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu_flag == 1) { + ue_context_p->ue_context.nas_pdu_flag = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu_flag; + ue_context_p->ue_context.nas_pdu.length = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu.length; + ue_context_p->ue_context.nas_pdu.buffer = NGAP_INITIAL_CONTEXT_SETUP_REQ(msg_p).nas_pdu.buffer; } /* security */ @@ -598,25 +640,34 @@ rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP( { MessageDef *msg_p = NULL; int pdusession; - int e_rabs_done = 0; - int e_rabs_failed = 0; + int pdu_sessions_done = 0; + int pdu_sessions_failed = 0; + int qos_flow_index = 0; msg_p = itti_alloc_new_message (TASK_RRC_ENB, 0, NGAP_INITIAL_CONTEXT_SETUP_RESP); NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).gNB_ue_ngap_id = ue_context_pP->ue_context.gNB_ue_ngap_id; for (pdusession = 0; pdusession < ue_context_pP->ue_context.nb_of_pdusessions; pdusession++) { - if (ue_context_pP->ue_context.pdusession[pdusession].status == E_RAB_STATUS_DONE) { - e_rabs_done++; - NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].pdusession_id = ue_context_pP->ue_context.pdusession[pdusession].param.pdusession_id; + if (ue_context_pP->ue_context.pduSession[pdusession].status == PDU_SESSION_STATUS_DONE) { + pdu_sessions_done++; + NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].pdusession_id = ue_context_pP->ue_context.pduSession[pdusession].param.pdusession_id; // TODO add other information from S1-U when it will be integrated NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].gtp_teid = ue_context_pP->ue_context.gnb_gtp_teid[pdusession]; memcpy(NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].gNB_addr.buffer , ue_context_pP->ue_context.gnb_gtp_addrs[pdusession].buffer, 20); NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].gNB_addr.length = 4; - ue_context_pP->ue_context.pdusession[pdusession].status = E_RAB_STATUS_ESTABLISHED; + ue_context_pP->ue_context.pduSession[pdusession].status = PDU_SESSION_STATUS_ESTABLISHED; + NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].nb_of_qos_flow = ue_context_pP->ue_context.pduSession[pdusession].param.nb_qos; + for (qos_flow_index = 0; qos_flow_index < ue_context_pP->ue_context.pduSession[pdusession].param.nb_qos; qos_flow_index++) { + NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].associated_qos_flows[qos_flow_index].qfi = + ue_context_pP->ue_context.pduSession[pdusession].param.qos[qos_flow_index].qfi; + NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions[pdusession].associated_qos_flows[qos_flow_index].qos_flow_mapping_ind = QOSFLOW_MAPPING_INDICATION_DL; + } } else { - e_rabs_failed++; - ue_context_pP->ue_context.pdusession[pdusession].status = E_RAB_STATUS_FAILED; - NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions_failed[pdusession].pdusession_id = ue_context_pP->ue_context.pdusession[pdusession].param.pdusession_id; + pdu_sessions_failed++; + ue_context_pP->ue_context.pduSession[pdusession].status = PDU_SESSION_STATUS_FAILED; + NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions_failed[pdusession].pdusession_id = ue_context_pP->ue_context.pduSession[pdusession].param.pdusession_id; // TODO add cause when it will be integrated + NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions_failed[pdusession].cause = NGAP_Cause_PR_radioNetwork; + NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).pdusessions_failed[pdusession].cause_value = NGAP_CauseRadioNetwork_unknown_PDU_session_ID; } } @@ -629,9 +680,9 @@ rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP( MSC_AS_TIME_ARGS(ctxt_pP), ue_context_pP->ue_id_rnti, NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).gNB_ue_ngap_id, - e_rabs_done, e_rabs_failed); - NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).nb_of_pdusessions = e_rabs_done; - NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).nb_of_pdusessions_failed = e_rabs_failed; + pdu_sessions_done, pdu_sessions_failed); + NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).nb_of_pdusessions = pdu_sessions_done; + NGAP_INITIAL_CONTEXT_SETUP_RESP (msg_p).nb_of_pdusessions_failed = pdu_sessions_failed; itti_send_msg_to_task (TASK_NGAP, ctxt_pP->instance, msg_p); } @@ -902,10 +953,10 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP( for (pdusession = 0; pdusession < ue_context_pP->ue_context.setup_pdu_sessions; pdusession++) { // if (xid == ue_context_pP->ue_context.pdusession[pdusession].xid) { - if (ue_context_pP->ue_context.pdusession[pdusession].status == PDU_SESSION_STATUS_DONE) { - NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].pdusession_id = ue_context_pP->ue_context.pdusession[pdusession].param.pdusession_id; + if (ue_context_pP->ue_context.pduSession[pdusession].status == PDU_SESSION_STATUS_DONE) { + NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].pdusession_id = ue_context_pP->ue_context.pduSession[pdusession].param.pdusession_id; // NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].pdusession_id = 1; - NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].nb_of_qos_flow = ue_context_pP->ue_context.pdusession[pdusession].param.nb_qos; + NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].nb_of_qos_flow = ue_context_pP->ue_context.pduSession[pdusession].param.nb_qos; NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].gtp_teid = ue_context_pP->ue_context.gnb_gtp_teid[pdusession]; NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].gNB_addr.pdu_session_type = PDUSessionType_ipv4; NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].gNB_addr.length = ue_context_pP->ue_context.gnb_gtp_addrs[pdusession].length; @@ -913,13 +964,13 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP( ue_context_pP->ue_context.gnb_gtp_addrs[pdusession].buffer, sizeof(uint8_t)*20); for (qos_flow_index = 0; qos_flow_index < NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].nb_of_qos_flow; qos_flow_index++) { NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].associated_qos_flows[qos_flow_index].qfi = - ue_context_pP->ue_context.pdusession[pdusession].param.qos[qos_flow_index].qfi; + ue_context_pP->ue_context.pduSession[pdusession].param.qos[qos_flow_index].qfi; NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession].associated_qos_flows[qos_flow_index].qos_flow_mapping_ind = QOSFLOW_MAPPING_INDICATION_DL; } - ue_context_pP->ue_context.pdusession[pdusession].status = PDU_SESSION_STATUS_ESTABLISHED; + ue_context_pP->ue_context.pduSession[pdusession].status = PDU_SESSION_STATUS_ESTABLISHED; LOG_I (NR_RRC,"gnb_gtp_addr (msg index %d, pdu_sessions index %d, status %d, xid %d): nb_of_pdusessions %d, pdusession_id %d, teid: %u, addr: %d.%d.%d.%d \n ", - pdu_sessions_done, pdusession, ue_context_pP->ue_context.pdusession[pdusession].status, xid, + pdu_sessions_done, pdusession, ue_context_pP->ue_context.pduSession[pdusession].status, xid, ue_context_pP->ue_context.nb_of_pdusessions, NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions[pdu_sessions_done].pdusession_id, NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions[pdu_sessions_done].gtp_teid, @@ -928,12 +979,12 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP( NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions[pdu_sessions_done].gNB_addr.buffer[2], NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions[pdu_sessions_done].gNB_addr.buffer[3]); pdu_sessions_done++; - } else if ((ue_context_pP->ue_context.pdusession[pdusession].status == PDU_SESSION_STATUS_NEW) || - (ue_context_pP->ue_context.pdusession[pdusession].status == PDU_SESSION_STATUS_ESTABLISHED)) { + } else if ((ue_context_pP->ue_context.pduSession[pdusession].status == PDU_SESSION_STATUS_NEW) || + (ue_context_pP->ue_context.pduSession[pdusession].status == PDU_SESSION_STATUS_ESTABLISHED)) { LOG_D (NR_RRC,"PDU-SESSION is NEW or already ESTABLISHED\n"); } else { /* to be improved */ - ue_context_pP->ue_context.pdusession[pdusession].status = PDU_SESSION_STATUS_FAILED; - NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions_failed[pdu_sessions_failed].pdusession_id = ue_context_pP->ue_context.pdusession[pdusession].param.pdusession_id; + ue_context_pP->ue_context.pduSession[pdusession].status = PDU_SESSION_STATUS_FAILED; + NGAP_PDUSESSION_SETUP_RESP (msg_p).pdusessions_failed[pdu_sessions_failed].pdusession_id = ue_context_pP->ue_context.pduSession[pdusession].param.pdusession_id; pdu_sessions_failed++; // TODO add cause when it will be integrated } @@ -962,7 +1013,7 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP( } for(int i = 0; i < NB_RB_MAX; i++) { - ue_context_pP->ue_context.pdusession[i].xid = -1; + ue_context_pP->ue_context.pduSession[i].xid = -1; } return; @@ -1008,20 +1059,20 @@ rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ( PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0); for (int i = 0; i < NR_NB_RB_MAX - 3; i++) { - if(ue_context_p->ue_context.pdusession[i].status >= PDU_SESSION_STATUS_DONE) + if(ue_context_p->ue_context.pduSession[i].status >= PDU_SESSION_STATUS_DONE) continue; - ue_context_p->ue_context.pdusession[i].status = PDU_SESSION_STATUS_NEW; - ue_context_p->ue_context.pdusession[i].param = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done]; + ue_context_p->ue_context.pduSession[i].status = PDU_SESSION_STATUS_NEW; + ue_context_p->ue_context.pduSession[i].param = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done]; create_tunnel_req.pdusession_id[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].pdusession_id; create_tunnel_req.upf_NGu_teid[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].gtp_teid; memcpy(create_tunnel_req.upf_addr[pdu_sessions_done].buffer, - NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[i].upf_addr.buffer, + NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].upf_addr.buffer, sizeof(uint8_t)*20); - create_tunnel_req.upf_addr[pdu_sessions_done].length = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[i].upf_addr.length; + create_tunnel_req.upf_addr[pdu_sessions_done].length = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].upf_addr.length; LOG_I(NR_RRC,"NGAP PDUSESSION SETUP REQ: local index %d teid %u, pdusession id %d \n", i, - create_tunnel_req.upf_NGu_teid[i], - create_tunnel_req.pdusession_id[i]); + create_tunnel_req.upf_NGu_teid[pdu_sessions_done], + create_tunnel_req.pdusession_id[pdu_sessions_done]); inde_list[pdu_sessions_done] = i; pdu_sessions_done++; @@ -1089,7 +1140,7 @@ rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ( NGAP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).cause_value = cause_valueP; NGAP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).nb_of_pdusessions = ue_context_pP->ue_context.setup_pdu_sessions; for (int pdusession = 0; pdusession < ue_context_pP->ue_context.setup_pdu_sessions; pdusession++) { - NGAP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).pdusessions[pdusession].pdusession_id = ue_context_pP->ue_context.pdusession[pdusession].param.pdusession_id; + NGAP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).pdusessions[pdusession].pdusession_id = ue_context_pP->ue_context.pduSession[pdusession].param.pdusession_id; } itti_send_msg_to_task(TASK_NGAP, GNB_MODULE_ID_TO_INSTANCE(gnb_mod_idP), msg_context_release_req_p); } @@ -1174,11 +1225,25 @@ rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND( return -1; } else { ue_context_p->ue_context.ue_release_timer_ng = 0; + ue_context_p->ue_context.ue_release_timer_thres_rrc = 1000; PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0); + ctxt.eNB_index = 0; rrc_gNB_generate_RRCRelease(&ctxt, ue_context_p); return 0; } } + +void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE( + instance_t instance, + uint32_t gNB_ue_ngap_id) { + MSC_LOG_TX_MESSAGE(MSC_RRC_GNB, MSC_NGAP_GNB, NULL, 0, + "0 NGAP_UE_CONTEXT_RELEASE_COMPLETE gNB_ue_ngap_id 0x%06"PRIX32" ", + gNB_ue_ngap_id); + MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_UE_CONTEXT_RELEASE_COMPLETE); + NGAP_UE_CONTEXT_RELEASE_COMPLETE(msg).gNB_ue_ngap_id = gNB_ue_ngap_id; + itti_send_msg_to_task(TASK_NGAP, instance, msg); +} + //------------------------------------------------------------------------------ /* * Remove UE ids (ue_initial_id and ng_id) from hashtables. @@ -1288,12 +1353,12 @@ rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE( NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).gNB_ue_ngap_id = ue_context_pP->ue_context.gNB_ue_ngap_id; for (int i = 0; i < NB_RB_MAX; i++) { - if (xid == ue_context_pP->ue_context.pdusession[i].xid) { + if (xid == ue_context_pP->ue_context.pduSession[i].xid) { NGAP_PDUSESSION_RELEASE_RESPONSE (msg_p).pdusession_release[pdu_sessions_released].pdusession_id = - ue_context_pP->ue_context.pdusession[i].param.pdusession_id; + ue_context_pP->ue_context.pduSession[i].param.pdusession_id; pdu_sessions_released++; //clear - memset(&ue_context_pP->ue_context.pdusession[i], 0, sizeof(pdu_session_param_t)); + memset(&ue_context_pP->ue_context.pduSession[i], 0, sizeof(pdu_session_param_t)); } } @@ -1309,7 +1374,7 @@ rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE( //clear xid for(int i = 0; i < NB_RB_MAX; i++) { - ue_context_pP->ue_context.pdusession[i].xid = -1; + ue_context_pP->ue_context.pduSession[i].xid = -1; } //clear release pdusessions @@ -1370,7 +1435,7 @@ rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND( } for (i = 0; i < NR_NB_RB_MAX; i++) { - if (pdusession_release_params[pdusession].pdusession_id == ue_context_p->ue_context.pdusession[i].param.pdusession_id) { + if (pdusession_release_params[pdusession].pdusession_id == ue_context_p->ue_context.pduSession[i].param.pdusession_id) { b_existed = 1; break; } @@ -1384,13 +1449,13 @@ rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND( ue_context_p->ue_context.pdusessions_release_failed[ue_context_p->ue_context.nb_release_of_pdusessions].cause_value = 30; ue_context_p->ue_context.nb_release_of_pdusessions++; } else { - if(ue_context_p->ue_context.pdusession[i].status == PDU_SESSION_STATUS_FAILED) { - ue_context_p->ue_context.pdusession[i].xid = xid; + if(ue_context_p->ue_context.pduSession[i].status == PDU_SESSION_STATUS_FAILED) { + ue_context_p->ue_context.pduSession[i].xid = xid; continue; - } else if(ue_context_p->ue_context.pdusession[i].status == PDU_SESSION_STATUS_ESTABLISHED) { - LOG_I(NR_RRC, "RELEASE pdusession %d \n", ue_context_p->ue_context.pdusession[i].param.pdusession_id); - ue_context_p->ue_context.pdusession[i].status = PDU_SESSION_STATUS_TORELEASE; - ue_context_p->ue_context.pdusession[i].xid = xid; + } else if(ue_context_p->ue_context.pduSession[i].status == PDU_SESSION_STATUS_ESTABLISHED) { + LOG_I(NR_RRC, "RELEASE pdusession %d \n", ue_context_p->ue_context.pduSession[i].param.pdusession_id); + ue_context_p->ue_context.pduSession[i].status = PDU_SESSION_STATUS_TORELEASE; + ue_context_p->ue_context.pduSession[i].xid = xid; pdusession_release_drb++; } else { // pdusession_id status NG @@ -1414,7 +1479,7 @@ rrc_gNB_process_NGAP_PDUSESSION_RELEASE_COMMAND( GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti; for(i = 0; i < NB_RB_MAX; i++) { - if(xid == ue_context_p->ue_context.pdusession[i].xid) { + if(xid == ue_context_p->ue_context.pduSession[i].xid) { GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).pdusession_id[GTPV1U_GNB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_pdusession++] = ue_context_p->ue_context.gnb_gtp_psi[i]; ue_context_p->ue_context.gnb_gtp_teid[i] = 0; memset(&ue_context_p->ue_context.gnb_gtp_addrs[i], 0, sizeof(ue_context_p->ue_context.gnb_gtp_addrs[i])); diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.h b/openair2/RRC/NR/rrc_gNB_NGAP.h index f13c468f94f7141b28866725f9b2ae9aa67b4c80..8779d62ff6b37d9ff7a9464ea87eb1245a2a97a3 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.h +++ b/openair2/RRC/NR/rrc_gNB_NGAP.h @@ -129,6 +129,10 @@ rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND( instance_t instance ); +void rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE( + instance_t instance, + uint32_t gNB_ue_ngap_id); + void rrc_gNB_NGAP_remove_ue_ids( gNB_RRC_INST *const rrc_instance_pP, diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.c b/openair2/RRC/NR/rrc_gNB_UE_context.c index 988db09cc1e2573cd14c3b8cec6a436ab837cf7d..eb7559f69d8c63fa27565df050e5f6114fdb022c 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.c +++ b/openair2/RRC/NR/rrc_gNB_UE_context.c @@ -135,7 +135,7 @@ rrc_gNB_allocate_new_UE_context( for(int i = 0; i < NB_RB_MAX; i++) { new_p->ue_context.e_rab[i].xid = -1; - new_p->ue_context.pdusession[i].xid = -1; + new_p->ue_context.pduSession[i].xid = -1; new_p->ue_context.modify_e_rab[i].xid = -1; } diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index 3736ed52444b96d08cde297566d031aaf56b8aa8..64db21c967833746f4db88bd4293aca515ee3eb6 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -61,8 +61,15 @@ void fill_default_coresetZero(NR_ControlResourceSet_t *coreset0, NR_ServingCellC // frequencyDomainResources '11111111 00000000 00000000 00000000 00000000 00000'B, if(coreset0->frequencyDomainResources.buf == NULL) coreset0->frequencyDomainResources.buf = calloc(1,6); - coreset0->frequencyDomainResources.buf[0] = 0xff; - coreset0->frequencyDomainResources.buf[1] = 0; + int curr_bwp = NRRIV2BW(servingcellconfigcommon->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, 275); + if (curr_bwp < 48) + coreset0->frequencyDomainResources.buf[0] = 0xf0; + else + coreset0->frequencyDomainResources.buf[0] = 0xff; + if (curr_bwp < 96) + coreset0->frequencyDomainResources.buf[1] = 0; + else + coreset0->frequencyDomainResources.buf[1] = 0xff; coreset0->frequencyDomainResources.buf[2] = 0; coreset0->frequencyDomainResources.buf[3] = 0; coreset0->frequencyDomainResources.buf[4] = 0; @@ -633,7 +640,10 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco } bwp->bwp_Dedicated->pdsch_Config->choice.setup->dataScramblingIdentityPDSCH = NULL; - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type=NULL;//calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type)); + if (n_physical_antenna_ports > 1)// for MIMO, we use DMRS Config Type 2 + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type=calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type)); + else + bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type=NULL; bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->maxLength=NULL; bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->scramblingID0=NULL; bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->scramblingID1=NULL; diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index cb8eca950495ae383867e4c4a52796c0a0325664..c988ec9b80202555d485462b95e2b9c84e58a340 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -69,9 +69,7 @@ #include "SIMULATION/TOOLS/sim.h" // for taus #include <executables/softmodem-common.h> -#if defined(ITTI_SIM) || defined(RFSIM_NAS) #include "nr_nas_msg_sim.h" -#endif NR_UE_RRC_INST_t *NR_UE_rrc_inst; /* NAS Attach request with IMSI */ @@ -1267,16 +1265,34 @@ nr_rrc_ue_process_masterCellGroup( // NSA procedures } + if(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config == NULL){ + NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config = calloc(1,sizeof(NR_CellGroupConfig_t)); + } + if( cellGroupConfig->rlc_BearerToReleaseList != NULL){ //TODO (perform RLC bearer release as specified in 5.3.5.5.3) } if( cellGroupConfig->rlc_BearerToAddModList != NULL){ //TODO (perform the RLC bearer addition/modification as specified in 5.3.5.5.4) + if(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList != NULL){ + free(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList); + } + NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList = calloc(1, sizeof(struct NR_CellGroupConfig__rlc_BearerToAddModList)); + memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList,cellGroupConfig->rlc_BearerToAddModList, + sizeof(struct NR_CellGroupConfig__rlc_BearerToAddModList)); } if( cellGroupConfig->mac_CellGroupConfig != NULL){ //TODO (configure the MAC entity of this cell group as specified in 5.3.5.5.5) + LOG_I(RRC, "Received mac_CellGroupConfig from gNB\n"); + if(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->mac_CellGroupConfig != NULL){ + LOG_E(RRC, "UE RRC instance already contains mac CellGroupConfig which will be overwritten\n"); + free(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->mac_CellGroupConfig); + } + NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->mac_CellGroupConfig = malloc(sizeof(struct NR_MAC_CellGroupConfig)); + memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->mac_CellGroupConfig,cellGroupConfig->mac_CellGroupConfig, + sizeof(struct NR_MAC_CellGroupConfig)); } if( cellGroupConfig->sCellToReleaseList != NULL){ @@ -1332,14 +1348,21 @@ static void rrc_ue_generate_RRCSetupComplete( AssertFatal(1==0,"2 > csi_MeasConfig is not null\n"); if (AMF_MODE_ENABLED) { -#if defined(ITTI_SIM) || defined(RFSIM_NAS) +#if defined(ITTI_SIM) as_nas_info_t initialNasMsg; - generateRegistrationRequest(&initialNasMsg); + generateRegistrationRequest(&initialNasMsg, ctxt_pP->module_id); nas_msg = (char*)initialNasMsg.data; nas_msg_length = initialNasMsg.length; #else - nas_msg = (char *) NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data; - nas_msg_length = NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.length; + if (get_softmodem_params()->sa) { + as_nas_info_t initialNasMsg; + generateRegistrationRequest(&initialNasMsg, ctxt_pP->module_id); + nas_msg = (char*)initialNasMsg.data; + nas_msg_length = initialNasMsg.length; + } else { + nas_msg = (char *) NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data; + nas_msg_length = NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.length; + } #endif } else { nas_msg = nr_nas_attach_req_imsi; @@ -2115,28 +2138,27 @@ nr_rrc_ue_establish_srb2( (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4)); // Refresh DRBs - // nr_rrc_pdcp_config_asn1_req(ctxt_pP, - // NULL, - // radioBearerConfig->drb_ToAddModList, - // NULL, - // NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm | - // (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4), - // NULL, - // NULL, - // kUPenc, - // NULL, - // NULL, - // NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB, - // NULL); + nr_rrc_pdcp_config_asn1_req(ctxt_pP, + NULL, + radioBearerConfig->drb_ToAddModList, + NULL, + 0, + NULL, + NULL, + kUPenc, + NULL, + NULL, + NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB, + NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList); // Refresh DRBs - // nr_rrc_rlc_config_asn1_req(ctxt_pP, - // NULL, - // radioBearerConfig->drb_ToAddModList, - // NULL, - // NULL, - // NULL - // ); - } // drb_ToAddModList + nr_rrc_rlc_config_asn1_req(ctxt_pP, + NULL, + radioBearerConfig->drb_ToAddModList, + NULL, + NULL, + NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList + ); + } // drb_ToAddModList // if (radioBearerConfig->drb_ToReleaseList != NULL) { for (i = 0; i < radioBearerConfig->drb_ToReleaseList->list.count; i++) { @@ -2171,9 +2193,16 @@ nr_rrc_ue_establish_srb2( // nr_rrc_ue_process_measConfig(ctxt_pP, gNB_index, ie->measConfig); } + if(ie->nonCriticalExtension->masterCellGroup!=NULL) { + nr_rrc_ue_process_masterCellGroup( + ctxt_pP, + gNB_index, + ie->nonCriticalExtension->masterCellGroup); + } + if (ie->radioBearerConfig != NULL) { LOG_I(NR_RRC, "radio Bearer Configuration is present\n"); - // nr_sa_rrc_ue_process_radioBearerConfig(ctxt_pP, gNB_index, ie->radioBearerConfig); + nr_sa_rrc_ue_process_radioBearerConfig(ctxt_pP, gNB_index, ie->radioBearerConfig); } /* Check if there is dedicated NAS information to forward to NAS */ @@ -2255,8 +2284,7 @@ nr_rrc_ue_establish_srb2( if (Srb_id != 1) { LOG_E(NR_RRC,"[UE %d] Frame %d: Received message on DL-DCCH (SRB%ld), should not have ...\n", - ctxt_pP->module_id, ctxt_pP->frame, Srb_id); - return -1; + ctxt_pP->module_id, ctxt_pP->frame, Srb_id); } else { LOG_D(NR_RRC, "Received message on SRB%ld\n", Srb_id); } diff --git a/openair2/UTIL/OPT/README.txt b/openair2/UTIL/OPT/README.txt index 2ac68f83fdbf1057f414e88a7559e6eb0c7345db..13ec727fd5a5b41c3cc4f0d58e6e543db92e0422 100644 --- a/openair2/UTIL/OPT/README.txt +++ b/openair2/UTIL/OPT/README.txt @@ -1,13 +1,14 @@ -How to configure wireshark for dissecting LTE protocols: +How to configure wireshark for dissecting LTE/NR protocols: - start the wireshark as a sudoers - goto analyze->enabled prototols - => enable mac_lte_udp and rlc_lte_udp + => enable mac_xxx_udp and rlc_xxx_udp (xxx is lte or nr) - goto edit/preferences and expand Protocols - select UDP and check "try heuristic sub-dissectors first" - - select MAC-LTE, and check all the options (checkboxes), and set the "which layer info to show in info column" to "MAC info" - - select RLC-LTE, and check all the options except the "May see RLC headers only", and + - select MAC-LTE (or MAC-NR), and check all the options (checkboxes), and set the "which layer info to show in info column" to "MAC info" + - select RLC-LTE (or NR), and check all the options except the "May see RLC headers only", and set the "call PDCP dissector for DRB PDUs" to "12-bit SN". Optionally you may select the sequence analysis for RLC AM/UM. + - select PDCP-LTE (or NR) How to use - start eNB or UE with option --opt.type wireshark diff --git a/openair2/UTIL/OPT/opt.h b/openair2/UTIL/OPT/opt.h index ab591d3a6572c7c114149baa78e8509ee97b9ab7..ae6a3eb2a65fb4e8dac6eabaa69942381afbc445 100644 --- a/openair2/UTIL/OPT/opt.h +++ b/openair2/UTIL/OPT/opt.h @@ -59,7 +59,8 @@ typedef uint16_t guint16; typedef uint32_t guint32; typedef guint8 gboolean; -#include "packet-mac-lte.h" +#include <openair2/UTIL/OPT/wireshark_headers.h> + #include "mac_pcap.h" /* OPT parameters definitions */ @@ -107,9 +108,10 @@ typedef enum radio_type_e { */ extern int opt_enabled; -#define trace_pdu(x...) if (opt_enabled) trace_pdu_implementation(x) +#define trace_pdu(x...) if (opt_enabled) trace_pdu_implementation(0, x) +#define trace_NRpdu(x...) if (opt_enabled) trace_pdu_implementation(1, x) -void trace_pdu_implementation(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size, +void trace_pdu_implementation(int nr, int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size, int ueid, int rntiType, int rnti, uint16_t sysFrame, uint8_t subframe, int oob_event, int oob_event_value); diff --git a/openair2/UTIL/OPT/packet-mac-lte.h b/openair2/UTIL/OPT/packet-mac-lte.h deleted file mode 100644 index 2d36e02df4d580af33f9fa5423dc984480f2d47f..0000000000000000000000000000000000000000 --- a/openair2/UTIL/OPT/packet-mac-lte.h +++ /dev/null @@ -1,382 +0,0 @@ -/* packet-mac-lte.h - * - * Martin Mathieson - * - * Wireshark - Network traffic analyzer - * By Gerald Combs <gerald@wireshark.org> - * Copyright 1998 Gerald Combs - * - * SPDX-License-Identifier: GPL-2.0-or-later - * - * This header file may also be distributed under - * the terms of the BSD Licence as follows: - * - * Copyright (C) 2009 Martin Mathieson. All rights reserved. - * - * SPDX-License-Identifier: BSD-2-Clause - */ - - /* - this is wireshark, commit: commit eda834b6e29c36e05a63a6056afa98390ff79357 - Date: Wed Aug 22 14:36:20 2018 +0200 - modified to be used in OpenAir to create the LTE MAC/RLC encapsulated in UDP as per Wireshark feature - */ - -#ifndef __UTIL_OPT_PACKET_MAC_LTE__H__ -#define __UTIL_OPT_PACKET_MAC_LTE__H__ - -#include "ws_symbol_export.h" - -/** data structure to hold time values with nanosecond resolution*/ -typedef struct { - time_t secs; - int nsecs; -} nstime_t; - - -/* radioType */ -#define FDD_RADIO 1 -#define TDD_RADIO 2 - -/* Direction */ -#define DIRECTION_UPLINK 0 -#define DIRECTION_DOWNLINK 1 - -/* rntiType */ -#define WS_NO_RNTI 0 -#define WS_P_RNTI 1 -#define WS_RA_RNTI 2 -#define WS_C_RNTI 3 -#define WS_SI_RNTI 4 -#define WS_SPS_RNTI 5 -#define WS_M_RNTI 6 -#define WS_SL_BCH_RNTI 7 -#define WS_SL_RNTI 8 -#define WS_SC_RNTI 9 -#define WS_G_RNTI 10 - -typedef enum mac_lte_oob_event { - ltemac_send_preamble, - ltemac_send_sr, - ltemac_sr_failure -} mac_lte_oob_event; - -typedef enum mac_lte_dl_retx { - dl_retx_no, - dl_retx_yes, - dl_retx_unknown -} mac_lte_dl_retx; - -typedef enum mac_lte_crc_status { - crc_fail = 0, - crc_success = 1, - crc_high_code_rate = 2, - crc_pdsch_lost = 3, - crc_duplicate_nonzero_rv = 4, - crc_false_dci = 5 -} mac_lte_crc_status; - -/* N.B. for SCellIndex-r13 extends to 31 */ -typedef enum mac_lte_carrier_id { - carrier_id_primary, - carrier_id_secondary_1, - carrier_id_secondary_2, - carrier_id_secondary_3, - carrier_id_secondary_4, - carrier_id_secondary_5, - carrier_id_secondary_6, - carrier_id_secondary_7 -} mac_lte_carrier_id; - -typedef enum mac_lte_ce_mode { - no_ce_mode = 0, - ce_mode_a = 1, - ce_mode_b = 2 -} mac_lte_ce_mode; - -typedef enum mac_lte_nb_mode { - no_nb_mode = 0, - nb_mode = 1 -} mac_lte_nb_mode; - -/* Context info attached to each LTE MAC frame */ -typedef struct mac_lte_info -{ - /* Needed for decode */ - guint8 radioType; - guint8 direction; - guint8 rntiType; - - /* Extra info to display */ - guint16 rnti; - guint16 ueid; - - /* Timing info */ - guint16 sysframeNumber; - guint16 subframeNumber; - - /* Optional field. More interesting for TDD (FDD is always -4 subframeNumber) */ - gboolean subframeNumberOfGrantPresent; - guint16 subframeNumberOfGrant; - - /* Flag set only if doing PHY-level data test - i.e. there may not be a - well-formed MAC PDU so just show as raw data */ - gboolean isPredefinedData; - - /* Length of DL PDU or UL grant size in bytes */ - guint16 length; - - /* 0=newTx, 1=first-retx, etc */ - guint8 reTxCount; - guint8 isPHICHNACK; /* FALSE=PDCCH retx grant, TRUE=PHICH NACK */ - - /* UL only. Indicates if the R10 extendedBSR-Sizes parameter is set */ - gboolean isExtendedBSRSizes; - - /* UL only. Indicates if the R10 simultaneousPUCCH-PUSCH parameter is set for PCell */ - gboolean isSimultPUCCHPUSCHPCell; - - /* UL only. Indicates if the R10 extendedBSR-Sizes parameter is set for PSCell */ - gboolean isSimultPUCCHPUSCHPSCell; - - /* Status of CRC check. For UE it is DL only. For eNodeB it is UL - only. For an analyzer, it is present for both DL and UL. */ - gboolean crcStatusValid; - mac_lte_crc_status crcStatus; - - /* Carrier ID */ - mac_lte_carrier_id carrierId; - - /* DL only. Is this known to be a retransmission? */ - mac_lte_dl_retx dl_retx; - - /* DL only. CE mode to be used for RAR decoding */ - mac_lte_ce_mode ceMode; - - /* DL and UL. NB-IoT mode of the UE */ - mac_lte_nb_mode nbMode; - - /* UL only, for now used for CE mode A RAR decoding */ - guint8 nUlRb; - - /* More Physical layer info (see direction above for which side of union to use) */ - union { - struct mac_lte_ul_phy_info - { - guint8 present; /* Remaining UL fields are present and should be displayed */ - guint8 modulation_type; - guint8 tbs_index; - guint8 resource_block_length; - guint8 resource_block_start; - guint8 harq_id; - gboolean ndi; - } ul_info; - struct mac_lte_dl_phy_info - { - guint8 present; /* Remaining DL fields are present and should be displayed */ - guint8 dci_format; - guint8 resource_allocation_type; - guint8 aggregation_level; - guint8 mcs_index; - guint8 redundancy_version_index; - guint8 resource_block_length; - guint8 harq_id; - gboolean ndi; - guint8 transport_block; /* 0..1 */ - } dl_info; - } detailed_phy_info; - - /* Relating to out-of-band events */ - /* N.B. dissector will only look to these fields if length is 0... */ - mac_lte_oob_event oob_event; - guint8 rapid; - guint8 rach_attempt_number; - #define MAX_SRs 20 - guint16 number_of_srs; - guint16 oob_ueid[MAX_SRs]; - guint16 oob_rnti[MAX_SRs]; -} mac_lte_info; - - -typedef struct mac_lte_tap_info { - /* Info from context */ - guint16 rnti; - guint16 ueid; - guint8 rntiType; - guint8 isPredefinedData; - gboolean crcStatusValid; - mac_lte_crc_status crcStatus; - guint8 direction; - - guint8 isPHYRetx; - guint16 ueInTTI; - - nstime_t mac_lte_time; - - /* Number of bytes (which part is used depends upon context settings) */ - guint32 single_number_of_bytes; - guint32 bytes_for_lcid[11]; - guint32 sdus_for_lcid[11]; - guint8 number_of_rars; - guint8 number_of_paging_ids; - - /* Number of padding bytes includes padding subheaders and trailing padding */ - guint16 padding_bytes; - guint16 raw_length; -} mac_lte_tap_info; - - - -/*****************************************************************/ -/* UDP framing format */ -/* ----------------------- */ -/* Several people have asked about dissecting MAC by framing */ -/* PDUs over IP. A suggested format over UDP has been created */ -/* and implemented by this dissector, using the definitions */ -/* below. A link to an example program showing you how to encode */ -/* these headers and send LTE MAC PDUs on a UDP socket is */ -/* provided at https://wiki.wireshark.org/MAC-LTE */ -/* */ -/* A heuristic dissector (enabled by a preference) will */ -/* recognise a signature at the beginning of these frames. */ -/*****************************************************************/ - - -/* Signature. Rather than try to define a port for this, or make the - port number a preference, frames will start with this string (with no - terminating NULL */ -#define MAC_LTE_START_STRING "mac-lte" - -/* Fixed fields. This is followed by the following 3 mandatory fields: - - radioType (1 byte) - - direction (1 byte) - - rntiType (1 byte) - (where the allowed values are defined above */ - -/* Optional fields. Attaching this info to frames will allow you - to show you display/filter/plot/add-custom-columns on these fields, so should - be added if available. - The format is to have the tag, followed by the value (there is no length field, - it's implicit from the tag) */ - -#define MAC_LTE_RNTI_TAG 0x02 -/* 2 bytes, network order */ - -#define MAC_LTE_UEID_TAG 0x03 -/* 2 bytes, network order */ - -#define MAC_LTE_FRAME_SUBFRAME_TAG 0x04 -/* 2 bytes, network order, SFN is stored in 12 MSB and SF in 4 LSB */ - -#define MAC_LTE_PREDEFINED_DATA_TAG 0x05 -/* 1 byte */ - -#define MAC_LTE_RETX_TAG 0x06 -/* 1 byte */ - -#define MAC_LTE_CRC_STATUS_TAG 0x07 -/* 1 byte */ - -#define MAC_LTE_EXT_BSR_SIZES_TAG 0x08 -/* 0 byte */ - -#define MAC_LTE_SEND_PREAMBLE_TAG 0x09 -/* 2 bytes, RAPID value (1 byte) followed by RACH attempt number (1 byte) */ - -#define MAC_LTE_CARRIER_ID_TAG 0x0A -/* 1 byte */ - -#define MAC_LTE_PHY_TAG 0x0B -/* variable length, length (1 byte) then depending on direction - in UL: modulation type (1 byte), TBS index (1 byte), RB length (1 byte), - RB start (1 byte), HARQ id (1 byte), NDI (1 byte) - in DL: DCI format (1 byte), resource allocation type (1 byte), aggregation level (1 byte), - MCS index (1 byte), redundancy version (1 byte), resource block length (1 byte), - HARQ id (1 byte), NDI (1 byte), TB (1 byte), DL reTx (1 byte) */ - -#define MAC_LTE_SIMULT_PUCCH_PUSCH_PCELL_TAG 0x0C -/* 0 byte */ - -#define MAC_LTE_SIMULT_PUCCH_PUSCH_PSCELL_TAG 0x0D -/* 0 byte */ - -#define MAC_LTE_CE_MODE_TAG 0x0E -/* 1 byte containing mac_lte_ce_mode enum value */ - -#define MAC_LTE_NB_MODE_TAG 0x0F -/* 1 byte containing mac_lte_nb_mode enum value */ - -#define MAC_LTE_N_UL_RB_TAG 0x10 -/* 1 byte containing the number of UL resource blocks: 6, 15, 25, 50, 75 or 100 */ - -#define MAC_LTE_SR_TAG 0x11 -/* 2 bytes for the number of items, followed by that number of ueid, rnti (2 bytes each) */ - - -/* MAC PDU. Following this tag comes the actual MAC PDU (there is no length, the PDU - continues until the end of the frame) */ -#define MAC_LTE_PAYLOAD_TAG 0x01 - - -/* Type to store parameters for configuring LCID->RLC channel settings for DRB */ -/* Some are optional, and may not be seen (e.g. on reestablishment) */ -typedef struct drb_mapping_t -{ - guint16 ueid; /* Mandatory */ - guint8 drbid; /* Mandatory */ - gboolean lcid_present; - guint8 lcid; /* Part of LogicalChannelConfig - optional */ - gboolean rlcMode_present; - guint8 rlcMode; /* Part of RLC config - optional */ - gboolean rlc_ul_ext_li_field; /* Part of RLC config - optional */ - gboolean rlc_dl_ext_li_field; /* Part of RLC config - optional */ - gboolean rlc_ul_ext_am_sn; /* Part of RLC config - optional */ - gboolean rlc_dl_ext_am_sn; /* Part of RLC config - optional */ - gboolean um_sn_length_present; - guint8 um_sn_length; /* Part of RLC config - optional */ - gboolean ul_priority_present; - guint8 ul_priority; /* Part of LogicalChannelConfig - optional */ - gboolean pdcp_sn_size_present; - guint8 pdcp_sn_size; /* Part of pdcp-Config - optional */ -} drb_mapping_t; - - - -/* Dedicated DRX config. Used to verify that a sensible config is given. - Also, beginning to configure MAC with this config and (optionally) show - DRX config and state (cycles/timers) attached to each UL/DL PDU! */ -typedef struct drx_config_t { - gboolean configured; - guint32 frameNum; - guint32 previousFrameNum; - - guint32 onDurationTimer; - guint32 inactivityTimer; - guint32 retransmissionTimer; - guint32 longCycle; - guint32 cycleOffset; - /* Optional Short cycle */ - gboolean shortCycleConfigured; - guint32 shortCycle; - guint32 shortCycleTimer; -} drx_config_t; - -/* RRC can indicate whether simultaneous PUCCH/PUSCH is used */ -typedef enum { - SIMULT_PUCCH_PUSCH_PCELL = 0, - SIMULT_PUCCH_PUSCH_PSCELL -} simult_pucch_pusch_cell_type; -/* - * Editor modelines - http://www.wireshark.org/tools/modelines.html - * - * Local variables: - * c-basic-offset: 4 - * tab-width: 8 - * indent-tabs-mode: nil - * End: - * - * vi: set shiftwidth=4 tabstop=8 expandtab: - * :indentSize=4:tabSize=8:noTabs=true: - */ - -#endif diff --git a/openair2/UTIL/OPT/packet-rohc.h b/openair2/UTIL/OPT/packet-rohc.h new file mode 100644 index 0000000000000000000000000000000000000000..c6c807f6872d139768f916bd3f166e45933705ce --- /dev/null +++ b/openair2/UTIL/OPT/packet-rohc.h @@ -0,0 +1,72 @@ +/* packet-rohc.h + * Routines for RObust Header Compression (ROHC) dissection. + * + * Copyright 2011, Anders Broman <anders.broman[at]ericsson.com> + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Ref: + * http://www.ietf.org/rfc/rfc3095.txt RObust Header Compression (ROHC): Framework and four profiles: RTP, UDP, ESP, and uncompressed + * http://datatracker.ietf.org/doc/rfc4815/ RObust Header Compression (ROHC): Corrections and Clarifications to RFC 3095 + * http://datatracker.ietf.org/doc/rfc5225/ RObust Header Compression Version 2 (ROHCv2): Profiles for RTP, UDP, IP, ESP and UDP-Lite + */ + +#ifndef PACKET_ROHC_H +#define PACKET_ROHC_H + +#define MAX_CID 15 + + /* ROHC Profiles */ +#define ROHC_PROFILE_UNCOMPRESSED 0 +#define ROHC_PROFILE_RTP 1 +#define ROHC_PROFILE_UDP 2 +#define ROHC_PROFILE_IP 4 +#define ROHC_PROFILE_UNKNOWN 0xFFFF + +enum rohc_mode +{ + MODE_NOT_SET = 0, + UNIDIRECTIONAL = 1, + OPTIMISTIC_BIDIRECTIONAL = 2, + RELIABLE_BIDIRECTIONAL = 3 +}; + +enum rohc_d_mode +{ + NO_CONTEXT = 1, + STATIC_CONTEXT = 2, + FULL_CONTEXT = 3 +}; +typedef struct rohc_info +{ + gboolean rohc_compression; + guint8 rohc_ip_version; + gboolean cid_inclusion_info; + gboolean large_cid_present; + enum rohc_mode mode; + gboolean rnd; + gboolean udp_checksum_present; + guint16 profile; + proto_item *last_created_item; +} rohc_info; + + +typedef struct rohc_context +{ + guint8 rohc_ip_version[MAX_CID+1]; + gboolean large_cid_present[MAX_CID+1]; + enum rohc_mode mode[MAX_CID+1]; + enum rohc_d_mode d_mode[MAX_CID+1]; + gboolean rnd[MAX_CID+1]; + gboolean udp_checkum_present[MAX_CID+1]; + guint16 profile[MAX_CID+1]; + gboolean rohc_context_init[MAX_CID+1]; + gint ir_frame_number[MAX_CID+1]; /* The frame number of the last IR packet seen */ + +} rohc_context; + +#endif /* PACKET_ROHC_H */ diff --git a/openair2/UTIL/OPT/probe.c b/openair2/UTIL/OPT/probe.c index 3f416c92553d97bfa1cc3a6a09d12255ed804e76..e64f7724c6399833723a6f84dd5176cd31b6b6f0 100644 --- a/openair2/UTIL/OPT/probe.c +++ b/openair2/UTIL/OPT/probe.c @@ -128,12 +128,6 @@ typedef struct { opt_listener_t opt_listener; -static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType, - guint16 rnti, guint16 ueid, guint16 sysframeNumber, - guint8 isPredefinedData, guint8 retx, guint8 crcStatus, - guint8 oob_event, guint8 oob_event_value, - uint8_t *pdu_buffer, unsigned int pdu_buffer_size); - unsigned short checksum(unsigned short *ptr, int length) { int sum = 0; u_short answer = 0; @@ -152,7 +146,7 @@ unsigned short checksum(unsigned short *ptr, int length) { } /* Write an individual PDU (PCAP packet header + mac-context + mac-pdu) */ -static int MAC_LTE_PCAP_WritePDU(const uint8_t *PDU, +static int PCAP_WritePDU(const uint8_t *PDU, unsigned int length) { pcaprec_hdr_t packet_header; // IPv4 header @@ -288,7 +282,7 @@ int opt_create_listener_socket(char *ip_address, uint16_t port) { */ /* Add framing header to MAC PDU and send. */ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType, - guint16 rnti, guint16 ueid, guint16 sfnSf, + guint16 rnti, guint16 ueid, guint16 frame, guint16 subframe, guint8 isPredefinedData, guint8 retx, guint8 crcStatus, guint8 oob_event, guint8 oob_event_value, uint8_t *pdu_buffer, unsigned int pdu_buffer_size) { @@ -317,9 +311,9 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType, tmp16 = htons(ueid); memcpy(frameBuffer+frameOffset, &tmp16, 2); frameOffset += 2; - /* Subframe number */ + /* Subframe number */ frameBuffer[frameOffset++] = MAC_LTE_FRAME_SUBFRAME_TAG; - tmp16 = htons(sfnSf); // frame counter : this will give an expert info as wireshark expects SF and not F + tmp16 = htons((frame<<4)+subframe); // frame counter : this will give an expert info as wireshark expects SF and not F memcpy(frameBuffer+frameOffset, &tmp16, 2); frameOffset += 2; frameBuffer[frameOffset++] = MAC_LTE_CRC_STATUS_TAG; @@ -400,7 +394,76 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType, bytesSent = sendto(g_socksd, frameBuffer, frameOffset, 0, (const struct sockaddr *)&g_serv_addr, sizeof(g_serv_addr)); else - bytesSent = MAC_LTE_PCAP_WritePDU(frameBuffer, frameOffset); + bytesSent = PCAP_WritePDU(frameBuffer, frameOffset); + + if (bytesSent != frameOffset) { + LOG_W(OPT, "trace_pdu expected %d bytes, got %ld (errno=%d)\n", + frameOffset, bytesSent, errno); + //exit(1); + } +} + +static void SendFrameNR(guint8 radioType, guint8 direction, guint8 rntiType, + guint16 rnti, guint16 ueid, guint16 frame, guint16 subframe, + guint8 isPredefinedData, guint8 retx, guint8 crcStatus, + guint8 oob_event, guint8 oob_event_value, + uint8_t *pdu_buffer, unsigned int pdu_buffer_size) { + unsigned char frameBuffer[9000]; + unsigned int frameOffset; + ssize_t bytesSent; + frameOffset = 0; + uint16_t tmp16; + memcpy(frameBuffer+frameOffset, MAC_NR_START_STRING, + strlen(MAC_NR_START_STRING)); + frameOffset += strlen(MAC_NR_START_STRING); + /******************************************************************************/ + /* Now write out fixed fields (the mandatory elements of struct mac_lte_info) */ + frameBuffer[frameOffset++] = radioType; + frameBuffer[frameOffset++] = direction; + frameBuffer[frameOffset++] = rntiType; + /*************************************/ + /* Now optional fields */ + /* RNTI */ + frameBuffer[frameOffset++] = MAC_NR_RNTI_TAG; + tmp16 = htons(rnti); + memcpy(frameBuffer+frameOffset, &tmp16, 2); + frameOffset += 2; + /* UEId */ + frameBuffer[frameOffset++] = MAC_NR_UEID_TAG; + tmp16 = htons(ueid); + memcpy(frameBuffer+frameOffset, &tmp16, 2); + frameOffset += 2; + /* Subframe number */ + frameBuffer[frameOffset++] = MAC_NR_FRAME_SLOT_TAG; + tmp16 = htons(frame); // frame counter : this will give an expert info as wireshark expects SF and not F + memcpy(frameBuffer+frameOffset, &tmp16, 2); + frameOffset += 2; + tmp16 = htons(subframe); // frame counter : this will give an expert info as wireshark expects SF and not F + memcpy(frameBuffer+frameOffset, &tmp16, 2); + frameOffset += 2; + if (direction == 0 ) { //ulink + frameBuffer[frameOffset++] = MAC_NR_PHR_TYPE2_OTHERCELL_TAG; + frameBuffer[frameOffset++] = 0; + } + + /***************************************/ + /* Now write the MAC PDU */ + frameBuffer[frameOffset++] = MAC_NR_PAYLOAD_TAG; + + /* Append actual PDU */ + //memcpy(frameBuffer+frameOffset, g_PDUBuffer, g_PDUOffset); + //frameOffset += g_PDUOffset; + if (pdu_buffer != NULL) { + memcpy(frameBuffer+frameOffset, (void *)pdu_buffer, pdu_buffer_size); + frameOffset += pdu_buffer_size; + } + + if ( opt_type == OPT_WIRESHARK ) + /* Send out the data over the UDP socket */ + bytesSent = sendto(g_socksd, frameBuffer, frameOffset, 0, + (const struct sockaddr *)&g_serv_addr, sizeof(g_serv_addr)); + else + bytesSent = PCAP_WritePDU(frameBuffer, frameOffset); if (bytesSent != frameOffset) { LOG_W(OPT, "trace_pdu expected %d bytes, got %ld (errno=%d)\n", @@ -413,20 +476,23 @@ static void SendFrame(guint8 radioType, guint8 direction, guint8 rntiType, extern RAN_CONTEXT_t RC; #include <openair1/PHY/phy_extern_ue.h> /* Remote serveraddress (where Wireshark is running) */ -void trace_pdu_implementation(int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size, +void trace_pdu_implementation(int nr, int direction, uint8_t *pdu_buffer, unsigned int pdu_buffer_size, int ueid, int rntiType, int rnti, uint16_t sysFrameNumber, uint8_t subFrameNumber, int oob_event, int oob_event_value) { int radioType=FDD_RADIO; LOG_D(OPT,"sending packet to wireshark: direction=%s, size: %d, ueid: %d, rnti: %x, frame/sf: %d.%d\n", direction?"DL":"UL", pdu_buffer_size, ueid, rnti, sysFrameNumber,subFrameNumber); - if (RC.eNB && RC.eNB[0][0]!=NULL) - radioType=RC.eNB[0][0]->frame_parms.frame_type== FDD ? FDD_RADIO:TDD_RADIO; - else if (PHY_vars_UE_g && PHY_vars_UE_g[0][0] != NULL) - radioType=PHY_vars_UE_g[0][0]->frame_parms.frame_type== FDD ? FDD_RADIO:TDD_RADIO; - else { - LOG_E(OPT,"not a eNB neither a UE!!! \n"); - return; + if (nr) { + radioType=TDD_RADIO; + } else { + if (RC.eNB && RC.eNB[0][0]!=NULL) + radioType=RC.eNB[0][0]->frame_parms.frame_type== FDD ? FDD_RADIO:TDD_RADIO; + else if (PHY_vars_UE_g && PHY_vars_UE_g[0][0] != NULL) + radioType=PHY_vars_UE_g[0][0]->frame_parms.frame_type== FDD ? FDD_RADIO:TDD_RADIO; + else { + LOG_E(OPT,"not a 4G eNB neither a 4G UE!!! \n"); + } } switch (opt_type) { @@ -448,9 +514,17 @@ void trace_pdu_implementation(int direction, uint8_t *pdu_buffer, unsigned int p break; } + if (nr) + SendFrameNR( radioType, + (direction == DIRECTION_DOWNLINK) ? DIRECTION_DOWNLINK : DIRECTION_UPLINK, + rntiType, rnti, ueid, sysFrameNumber, subFrameNumber, + 1, 0, 1, //guint8 isPredefinedData, guint8 retx, guint8 crcStatus + oob_event,oob_event_value, + pdu_buffer, pdu_buffer_size); + else SendFrame( radioType, (direction == DIRECTION_DOWNLINK) ? DIRECTION_DOWNLINK : DIRECTION_UPLINK, - rntiType, rnti, ueid, (sysFrameNumber<<4) + subFrameNumber, + rntiType, rnti, ueid, sysFrameNumber, subFrameNumber, 1, 0, 1, //guint8 isPredefinedData, guint8 retx, guint8 crcStatus oob_event,oob_event_value, pdu_buffer, pdu_buffer_size); diff --git a/openair2/UTIL/OPT/wireshark_headers.h b/openair2/UTIL/OPT/wireshark_headers.h new file mode 100644 index 0000000000000000000000000000000000000000..27d8753ffe8c9e676a211399babb80f3d554a5ef --- /dev/null +++ b/openair2/UTIL/OPT/wireshark_headers.h @@ -0,0 +1,895 @@ +/* packet-mac-lte.h + * + * Martin Mathieson + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * Copyright (C) 2009 Martin Mathieson. All rights reserved. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + + /* + this is wireshark, commit: commit eda834b6e29c36e05a63a6056afa98390ff79357 + Date: Wed Aug 22 14:36:20 2018 +0200 + modified to be used in OpenAir to create the LTE MAC/RLC encapsulated in UDP as per Wireshark feature + */ + +#ifndef __UTIL_OPT_PACKET_MAC_LTE__H__ +#define __UTIL_OPT_PACKET_MAC_LTE__H__ + +/** data structure to hold time values with nanosecond resolution*/ +typedef struct { + time_t secs; + int nsecs; +} nstime_t; + + +/* radioType */ +#define FDD_RADIO 1 +#define TDD_RADIO 2 + +/* Direction */ +#define DIRECTION_UPLINK 0 +#define DIRECTION_DOWNLINK 1 + +/* rntiType */ +#define WS_NO_RNTI 0 +#define WS_P_RNTI 1 +#define WS_RA_RNTI 2 +#define WS_C_RNTI 3 +#define WS_SI_RNTI 4 +#define WS_SPS_RNTI 5 +#define WS_M_RNTI 6 +#define WS_SL_BCH_RNTI 7 +#define WS_SL_RNTI 8 +#define WS_SC_RNTI 9 +#define WS_G_RNTI 10 + +#define WS_CS_RNTI 5 + +typedef enum mac_lte_oob_event { + ltemac_send_preamble, + ltemac_send_sr, + ltemac_sr_failure +} mac_lte_oob_event; + +typedef enum mac_lte_dl_retx { + dl_retx_no, + dl_retx_yes, + dl_retx_unknown +} mac_lte_dl_retx; + +typedef enum mac_lte_crc_status { + crc_fail = 0, + crc_success = 1, + crc_high_code_rate = 2, + crc_pdsch_lost = 3, + crc_duplicate_nonzero_rv = 4, + crc_false_dci = 5 +} mac_lte_crc_status; + +/* N.B. for SCellIndex-r13 extends to 31 */ +typedef enum mac_lte_carrier_id { + carrier_id_primary, + carrier_id_secondary_1, + carrier_id_secondary_2, + carrier_id_secondary_3, + carrier_id_secondary_4, + carrier_id_secondary_5, + carrier_id_secondary_6, + carrier_id_secondary_7 +} mac_lte_carrier_id; + +typedef enum mac_lte_ce_mode { + no_ce_mode = 0, + ce_mode_a = 1, + ce_mode_b = 2 +} mac_lte_ce_mode; + +typedef enum mac_lte_nb_mode { + no_nb_mode = 0, + nb_mode = 1 +} mac_lte_nb_mode; + +/* Context info attached to each LTE MAC frame */ +typedef struct mac_lte_info +{ + /* Needed for decode */ + guint8 radioType; + guint8 direction; + guint8 rntiType; + + /* Extra info to display */ + guint16 rnti; + guint16 ueid; + + /* Timing info */ + guint16 sysframeNumber; + guint16 subframeNumber; + gboolean sfnSfInfoPresent; + + /* Optional field. More interesting for TDD (FDD is always -4 subframeNumber) */ + gboolean subframeNumberOfGrantPresent; + guint16 subframeNumberOfGrant; + + /* Flag set only if doing PHY-level data test - i.e. there may not be a + well-formed MAC PDU so just show as raw data */ + gboolean isPredefinedData; + + /* Length of DL PDU or UL grant size in bytes */ + guint16 length; + + /* 0=newTx, 1=first-retx, etc */ + guint8 reTxCount; + guint8 isPHICHNACK; /* FALSE=PDCCH retx grant, TRUE=PHICH NACK */ + + /* UL only. Indicates if the R10 extendedBSR-Sizes parameter is set */ + gboolean isExtendedBSRSizes; + + /* UL only. Indicates if the R10 simultaneousPUCCH-PUSCH parameter is set for PCell */ + gboolean isSimultPUCCHPUSCHPCell; + + /* UL only. Indicates if the R10 extendedBSR-Sizes parameter is set for PSCell */ + gboolean isSimultPUCCHPUSCHPSCell; + + /* Status of CRC check. For UE it is DL only. For eNodeB it is UL + only. For an analyzer, it is present for both DL and UL. */ + gboolean crcStatusValid; + mac_lte_crc_status crcStatus; + + /* Carrier ID */ + mac_lte_carrier_id carrierId; + + /* DL only. Is this known to be a retransmission? */ + mac_lte_dl_retx dl_retx; + + /* DL only. CE mode to be used for RAR decoding */ + mac_lte_ce_mode ceMode; + + /* DL and UL. NB-IoT mode of the UE */ + mac_lte_nb_mode nbMode; + + /* UL only, for now used for CE mode A RAR decoding */ + guint8 nUlRb; + + /* More Physical layer info (see direction above for which side of union to use) */ + union { + struct mac_lte_ul_phy_info + { + guint8 present; /* Remaining UL fields are present and should be displayed */ + guint8 modulation_type; + guint8 tbs_index; + guint8 resource_block_length; + guint8 resource_block_start; + guint8 harq_id; + gboolean ndi; + } ul_info; + struct mac_lte_dl_phy_info + { + guint8 present; /* Remaining DL fields are present and should be displayed */ + guint8 dci_format; + guint8 resource_allocation_type; + guint8 aggregation_level; + guint8 mcs_index; + guint8 redundancy_version_index; + guint8 resource_block_length; + guint8 harq_id; + gboolean ndi; + guint8 transport_block; /* 0..1 */ + } dl_info; + } detailed_phy_info; + + /* Relating to out-of-band events */ + /* N.B. dissector will only look to these fields if length is 0... */ + mac_lte_oob_event oob_event; + guint8 rapid; + guint8 rach_attempt_number; + #define MAX_SRs 20 + guint16 number_of_srs; + guint16 oob_ueid[MAX_SRs]; + guint16 oob_rnti[MAX_SRs]; +} mac_lte_info; + + /* 0 to 10 and 32 to 38 */ +#define MAC_LTE_DATA_LCID_COUNT_MAX 18 +#define MAC_LTE_START_STRING "mac-lte" + +/* Fixed fields. This is followed by the following 3 mandatory fields: + - radioType (1 byte) + - direction (1 byte) + - rntiType (1 byte) + (where the allowed values are defined above */ + +/* Optional fields. Attaching this info to frames will allow you + to show you display/filter/plot/add-custom-columns on these fields, so should + be added if available. + The format is to have the tag, followed by the value (there is no length field, + it's implicit from the tag) */ + +#define MAC_LTE_RNTI_TAG 0x02 +/* 2 bytes, network order */ + +#define MAC_LTE_UEID_TAG 0x03 +/* 2 bytes, network order */ + +#define MAC_LTE_FRAME_SUBFRAME_TAG 0x04 +/* 2 bytes, network order, SFN is stored in 12 MSB and SF in 4 LSB */ + +#define MAC_LTE_PREDEFINED_DATA_TAG 0x05 +/* 1 byte */ + +#define MAC_LTE_RETX_TAG 0x06 +/* 1 byte */ + +#define MAC_LTE_CRC_STATUS_TAG 0x07 +/* 1 byte */ + +#define MAC_LTE_EXT_BSR_SIZES_TAG 0x08 +/* 0 byte */ + +#define MAC_LTE_SEND_PREAMBLE_TAG 0x09 +/* 2 bytes, RAPID value (1 byte) followed by RACH attempt number (1 byte) */ + +#define MAC_LTE_CARRIER_ID_TAG 0x0A +/* 1 byte */ + +#define MAC_LTE_PHY_TAG 0x0B +/* variable length, length (1 byte) then depending on direction + in UL: modulation type (1 byte), TBS index (1 byte), RB length (1 byte), + RB start (1 byte), HARQ id (1 byte), NDI (1 byte) + in DL: DCI format (1 byte), resource allocation type (1 byte), aggregation level (1 byte), + MCS index (1 byte), redundancy version (1 byte), resource block length (1 byte), + HARQ id (1 byte), NDI (1 byte), TB (1 byte), DL reTx (1 byte) */ + +#define MAC_LTE_SIMULT_PUCCH_PUSCH_PCELL_TAG 0x0C +/* 0 byte */ + +#define MAC_LTE_SIMULT_PUCCH_PUSCH_PSCELL_TAG 0x0D +/* 0 byte */ + +#define MAC_LTE_CE_MODE_TAG 0x0E +/* 1 byte containing mac_lte_ce_mode enum value */ + +#define MAC_LTE_NB_MODE_TAG 0x0F +/* 1 byte containing mac_lte_nb_mode enum value */ + +#define MAC_LTE_N_UL_RB_TAG 0x10 +/* 1 byte containing the number of UL resource blocks: 6, 15, 25, 50, 75 or 100 */ + +#define MAC_LTE_SR_TAG 0x11 +/* 2 bytes for the number of items, followed by that number of ueid, rnti (2 bytes each) */ + + +/* MAC PDU. Following this tag comes the actual MAC PDU (there is no length, the PDU + continues until the end of the frame) */ +#define MAC_LTE_PAYLOAD_TAG 0x01 + +/* rlcMode */ +#define RLC_TM_MODE 1 +#define RLC_UM_MODE 2 +#define RLC_AM_MODE 4 +#define RLC_PREDEF 8 + +/* priority ? */ + +/* channelType */ +#define CHANNEL_TYPE_CCCH 1 +#define CHANNEL_TYPE_BCCH_BCH 2 +#define CHANNEL_TYPE_PCCH 3 +#define CHANNEL_TYPE_SRB 4 +#define CHANNEL_TYPE_DRB 5 +#define CHANNEL_TYPE_BCCH_DL_SCH 6 +#define CHANNEL_TYPE_MCCH 7 +#define CHANNEL_TYPE_MTCH 8 + +/* sequenceNumberLength */ +#define UM_SN_LENGTH_5_BITS 5 +#define UM_SN_LENGTH_10_BITS 10 +#define AM_SN_LENGTH_10_BITS 10 +#define AM_SN_LENGTH_16_BITS 16 + + +typedef enum rlc_lte_nb_mode { + rlc_no_nb_mode = 0, + rlc_nb_mode = 1 +} rlc_lte_nb_mode; + + +/* Info attached to each LTE RLC frame */ +typedef struct rlc_lte_info +{ + guint8 rlcMode; + guint8 direction; + guint8 priority; + guint8 sequenceNumberLength; + guint16 ueid; + guint16 channelType; + guint16 channelId; /* for SRB: 1=SRB1, 2=SRB2, 3=SRB1bis; for DRB: DRB ID */ + guint16 pduLength; + gboolean extendedLiField; + rlc_lte_nb_mode nbMode; +} rlc_lte_info; + + +typedef struct rlc_lte_tap_info { + /* Info from context */ + guint8 rlcMode; + guint8 direction; + guint8 priority; + guint16 ueid; + guint16 channelType; + guint16 channelId; + guint16 pduLength; + guint8 sequenceNumberLength; + + nstime_t rlc_lte_time; + guint8 loggedInMACFrame; + guint16 sequenceNumber; + guint8 isResegmented; + guint8 isControlPDU; + guint16 ACKNo; + #define MAX_NACKs 128 + guint16 noOfNACKs; + guint16 NACKs[MAX_NACKs]; + + guint16 missingSNs; +} rlc_lte_tap_info; + + +/* Signature. Rather than try to define a port for this, or make the + port number a preference, frames will start with this string (with no + terminating NULL */ +#define RLC_LTE_START_STRING "rlc-lte" + +/* Fixed field. This is followed by the following 1 mandatory field: + - rlcMode (1 byte) + (where the allowed values are defined above */ + +/* Conditional field. This field is mandatory in case of RLC Unacknowledged mode. + In case of RLC Acknowledged mode, the field is optional (assume 10 bits by default). + The format is to have the tag, followed by the value (there is no length field, + it's implicit from the tag). The allowed values are defined above. */ + +#define RLC_LTE_SN_LENGTH_TAG 0x02 +/* 1 byte */ + +/* Optional fields. Attaching this info to frames will allow you + to show you display/filter/plot/add-custom-columns on these fields, so should + be added if available. + The format is to have the tag, followed by the value (there is no length field, + it's implicit from the tag) */ + +#define RLC_LTE_DIRECTION_TAG 0x03 +/* 1 byte */ + +#define RLC_LTE_PRIORITY_TAG 0x04 +/* 1 byte */ + +#define RLC_LTE_UEID_TAG 0x05 +/* 2 bytes, network order */ + +#define RLC_LTE_CHANNEL_TYPE_TAG 0x06 +/* 2 bytes, network order */ + +#define RLC_LTE_CHANNEL_ID_TAG 0x07 +/* 2 bytes, network order */ + +#define RLC_LTE_EXT_LI_FIELD_TAG 0x08 +/* 0 byte, tag presence indicates that AM DRB PDU is using an extended LI field of 15 bits */ + +#define RLC_LTE_NB_MODE_TAG 0x09 +/* 1 byte containing rlc_lte_nb_mode enum value */ + +/* RLC PDU. Following this tag comes the actual RLC PDU (there is no length, the PDU + continues until the end of the frame) */ +#define RLC_LTE_PAYLOAD_TAG 0x01 + +enum pdcp_plane +{ + SIGNALING_PLANE = 1, + USER_PLANE = 2 +}; + +typedef enum LogicalChannelType +{ + Channel_DCCH=1, + Channel_BCCH=2, + Channel_CCCH=3, + Channel_PCCH=4, + Channel_DCCH_NB=5, + Channel_BCCH_NB=6, + Channel_CCCH_NB=7, + Channel_PCCH_NB=8 +} LogicalChannelType; + +typedef enum +{ + BCH_TRANSPORT=1, + DLSCH_TRANSPORT=2 +} BCCHTransportType; + +#define PDCP_SN_LENGTH_5_BITS 5 +#define PDCP_SN_LENGTH_7_BITS 7 +#define PDCP_SN_LENGTH_12_BITS 12 +#define PDCP_SN_LENGTH_15_BITS 15 +#define PDCP_SN_LENGTH_18_BITS 18 + +enum lte_security_integrity_algorithm_e { eia0, eia1, eia2, eia3 }; +enum lte_security_ciphering_algorithm_e { eea0, eea1, eea2, eea3 }; + +typedef struct pdcp_lte_security_info_t +{ + guint32 configuration_frame; + gboolean seen_next_ul_pdu; /* i.e. have we seen SecurityModeResponse */ + enum lte_security_integrity_algorithm_e integrity; + enum lte_security_ciphering_algorithm_e ciphering; + + /* Store previous settings so can revert if get SecurityModeFailure */ + guint32 previous_configuration_frame; + enum lte_security_integrity_algorithm_e previous_integrity; + enum lte_security_ciphering_algorithm_e previous_ciphering; +} pdcp_lte_security_info_t; + + +/***********************************************************************/ +/* UDP framing format */ +/* ----------------------- */ +/* Several people have asked about dissecting PDCP by framing */ +/* PDUs over IP. A suggested format over UDP has been defined */ +/* and implemented by this dissector, using the definitions */ +/* below. A link to an example program showing you how to encode */ +/* these headers and send LTE PDCP PDUs on a UDP socket is */ +/* provided at https://gitlab.com/wireshark/wireshark/-/wikis/PDCP-LTE */ +/* */ +/* A heuristic dissecter (enabled by a preference) will */ +/* recognise a signature at the beginning of these frames. */ +/* Until someone is using this format, suggestions for changes */ +/* are welcome. */ +/***********************************************************************/ + + +/* Signature. Rather than try to define a port for this, or make the + port number a preference, frames will start with this string (with no + terminating NULL */ +#define PDCP_LTE_START_STRING "pdcp-lte" + +/* Fixed fields. This is followed by the following 3 mandatory fields: + - no_header_pdu (1 byte) + - plane (1 byte) + - rohc_compression ( byte) + (where the allowed values are defined above) */ + +/* Conditional field. This field is mandatory in case of User Plane PDCP PDU. + The format is to have the tag, followed by the value (there is no length field, + it's implicit from the tag). The allowed values are defined above. */ + +#define PDCP_LTE_SEQNUM_LENGTH_TAG 0x02 +/* 1 byte */ + +/* Optional fields. Attaching this info to frames will allow you + to show you display/filter/plot/add-custom-columns on these fields, so should + be added if available. + The format is to have the tag, followed by the value (there is no length field, + it's implicit from the tag) */ + +#define PDCP_LTE_DIRECTION_TAG 0x03 +/* 1 byte */ + +#define PDCP_LTE_LOG_CHAN_TYPE_TAG 0x04 +/* 1 byte */ + +#define PDCP_LTE_BCCH_TRANSPORT_TYPE_TAG 0x05 +/* 1 byte */ + +#define PDCP_LTE_ROHC_IP_VERSION_TAG 0x06 +/* 2 bytes, network order */ + +#define PDCP_LTE_ROHC_CID_INC_INFO_TAG 0x07 +/* 1 byte */ + +#define PDCP_LTE_ROHC_LARGE_CID_PRES_TAG 0x08 +/* 1 byte */ + +#define PDCP_LTE_ROHC_MODE_TAG 0x09 +/* 1 byte */ + +#define PDCP_LTE_ROHC_RND_TAG 0x0A +/* 1 byte */ + +#define PDCP_LTE_ROHC_UDP_CHECKSUM_PRES_TAG 0x0B +/* 1 byte */ + +#define PDCP_LTE_ROHC_PROFILE_TAG 0x0C +/* 2 bytes, network order */ + +#define PDCP_LTE_CHANNEL_ID_TAG 0x0D +/* 2 bytes, network order */ + +#define PDCP_LTE_UEID_TAG 0x0E +/* 2 bytes, network order */ + +/* PDCP PDU. Following this tag comes the actual PDCP PDU (there is no length, the PDU + continues until the end of the frame) */ +#define PDCP_LTE_PAYLOAD_TAG 0x01 + + + +/* Called by RRC, or other configuration protocols */ + +/* Function to configure ciphering & integrity algorithms */ +void set_pdcp_lte_security_algorithms(guint16 ueid, pdcp_lte_security_info_t *security_info); + +/* Function to indicate securityModeCommand did not complete */ +void set_pdcp_lte_security_algorithms_failed(guint16 ueid); + + +/* Called by external dissectors */ +void set_pdcp_lte_rrc_ciphering_key(guint16 ueid, const char *key); +void set_pdcp_lte_rrc_integrity_key(guint16 ueid, const char *key); +void set_pdcp_lte_up_ciphering_key(guint16 ueid, const char *key); + + + +/* Context info attached to each NR MAC frame */ +typedef struct mac_nr_info +{ + /* Needed for decode */ + guint8 radioType; + guint8 direction; + guint8 rntiType; + + /* Extra info to display */ + guint16 rnti; + guint16 ueid; + guint8 harqid; + + /* Will these be included in the ME PHR report? */ + guint8 phr_type2_othercell; + + /* Timing info */ + gboolean sfnSlotInfoPresent; + guint16 sysframeNumber; + guint16 slotNumber; + + /* Length of DL PDU or UL grant size in bytes */ + guint16 length; + +} mac_nr_info; + + +/*****************************************************************/ +/* UDP framing format */ +/* ----------------------- */ +/* Several people have asked about dissecting MAC by framing */ +/* PDUs over IP. A suggested format over UDP has been created */ +/* and implemented by this dissector, using the definitions */ +/* below. */ +/* */ +/* A heuristic dissector (enabled by a preference) will */ +/* recognise a signature at the beginning of these frames. */ +/*****************************************************************/ + + +/* Signature. Rather than try to define a port for this, or make the + port number a preference, frames will start with this string (with no + terminating NULL */ +#define MAC_NR_START_STRING "mac-nr" + +/* Fixed fields. This is followed by the following 3 mandatory fields: + - radioType (1 byte) + - direction (1 byte) + - rntiType (1 byte) + (where the allowed values are defined above */ + +/* Optional fields. Attaching this info to frames will allow you + to show you display/filter/plot/add-custom-columns on these fields, so should + be added if available. + The format is to have the tag, followed by the value (there is no length field, + it's implicit from the tag) */ + +#define MAC_NR_RNTI_TAG 0x02 +/* 2 bytes, network order */ + +#define MAC_NR_UEID_TAG 0x03 +/* 2 bytes, network order */ + +#define MAC_NR_FRAME_SUBFRAME_TAG 0x04 +/* 2 bytes, deprecated, do not use it */ + +#define MAC_NR_PHR_TYPE2_OTHERCELL_TAG 0x05 +/* 1 byte, TRUE/FALSE */ + +#define MAC_NR_HARQID 0x06 +/* 1 byte */ + +#define MAC_NR_FRAME_SLOT_TAG 0x07 +/* 4 bytes, network order, SFN is stored in the 2 first bytes and slot number in the 2 last bytes */ + +/* MAC PDU. Following this tag comes the actual MAC PDU (there is no length, the PDU + continues until the end of the frame) */ +#define MAC_NR_PAYLOAD_TAG 0x01 + + +/* Type to store parameters for configuring LCID->RLC channel settings for DRB */ +/* Some are optional, and may not be seen (e.g. on reestablishment) */ +typedef struct nr_drb_mac_rlc_mapping_t +{ + gboolean active; + guint16 ueid; /* Mandatory */ + guint8 drbid; /* Mandatory */ + + gboolean lcid_present; + guint8 lcid; /* Part of LogicalChannelConfig - optional */ + gboolean rlcMode_present; + guint8 rlcMode; /* Part of RLC config - optional */ + + guint8 tempDirection; /* So know direction of next SN length... */ + + gboolean rlcUlSnLength_present; + guint8 rlcUlSnLength; /* Part of RLC config - optional */ + gboolean rlcDlSnLength_present; + guint8 rlcDlSnLength; /* Part of RLC config - optional */ +} nr_drb_mac_rlc_mapping_t; + +/* rlcMode */ +#define RLC_TM_MODE 1 +#define RLC_UM_MODE 2 +#define RLC_AM_MODE 4 + +/* bearerType */ +#define BEARER_TYPE_CCCH 1 +#define BEARER_TYPE_BCCH_BCH 2 +#define BEARER_TYPE_PCCH 3 +#define BEARER_TYPE_SRB 4 +#define BEARER_TYPE_DRB 5 +#define BEARER_TYPE_BCCH_DL_SCH 6 + +/* sequenceNumberLength */ +#define TM_SN_LENGTH_0_BITS 0 +#define UM_SN_LENGTH_6_BITS 6 +#define UM_SN_LENGTH_12_BITS 12 +#define AM_SN_LENGTH_12_BITS 12 +#define AM_SN_LENGTH_18_BITS 18 + +/* Info attached to each NR RLC frame */ +typedef struct rlc_nr_info +{ + guint8 rlcMode; + guint8 direction; + guint8 sequenceNumberLength; + guint8 bearerType; + guint8 bearerId; + guint16 ueid; + guint16 pduLength; +} rlc_nr_info; + +typedef struct nr_drb_rlc_pdcp_mapping_t +{ + gboolean active; + guint16 ueid; /* Mandatory */ + guint8 drbid; /* Mandatory */ + + gboolean pdcpUlSnLength_present; + guint8 pdcpUlSnLength; /* Part of PDCP config - optional */ + gboolean pdcpDlSnLength_present; + guint8 pdcpDlSnLength; /* Part of PDCP config - optional */ + gboolean pdcpUlSdap; + gboolean pdcpDlSdap; + gboolean pdcpIntegrityProtection; + gboolean pdcpCipheringDisabled; + +} nr_drb_rlc_pdcp_mapping_t; + +/* TODO: could probably merge this struct with above */ +typedef struct pdcp_ue_parameters { + guint32 id; + guint8 pdcp_sn_bits_ul; + guint8 pdcp_sn_bits_dl; + gboolean pdcp_sdap_ul; + gboolean pdcp_sdap_dl; + gboolean pdcp_integrity; + gboolean pdcp_ciphering_disabled; +} pdcp_bearer_parameters; + +/*****************************************************************/ +/* UDP framing format */ +/* ----------------------- */ +/* Several people have asked about dissecting RLC by framing */ +/* PDUs over IP. A suggested format over UDP has been defined */ +/* and implemented by this dissector, using the definitions */ +/* below. */ +/* */ +/* A heuristic dissector (enabled by a preference) will */ +/* recognise a signature at the beginning of these frames. */ +/*****************************************************************/ + + +/* Signature. Rather than try to define a port for this, or make the + port number a preference, frames will start with this string (with no + terminating NULL */ +#define RLC_NR_START_STRING "rlc-nr" + +/* Fixed field. This is followed by the following 2 mandatory field: + - rlcMode (1 byte) + - sequenceNumberLength (1 byte) + (where the allowed values are defined above) */ + +/* Optional fields. Attaching this info to frames will allow you + to show you display/filter/plot/add-custom-columns on these fields, so should + be added if available. + The format is to have the tag, followed by the value (there is no length field, + it's implicit from the tag) */ + +#define RLC_NR_DIRECTION_TAG 0x02 +/* 1 byte */ + +#define RLC_NR_UEID_TAG 0x03 +/* 2 bytes, network order */ + +#define RLC_NR_BEARER_TYPE_TAG 0x04 +/* 1 byte */ + +#define RLC_NR_BEARER_ID_TAG 0x05 +/* 1 byte */ + +/* RLC PDU. Following this tag comes the actual RLC PDU (there is no length, the PDU + continues until the end of the frame) */ +#define RLC_NR_PAYLOAD_TAG 0x01 + +enum pdcp_nr_plane +{ + NR_SIGNALING_PLANE = 1, + NR_USER_PLANE = 2 +}; + +typedef enum NRBearerType +{ + Bearer_DCCH=1, + Bearer_BCCH_BCH=2, + Bearer_BCCH_DL_SCH=3, + Bearer_CCCH=4, + Bearer_PCCH=5, +} NRBearerType; + + +#define PDCP_NR_SN_LENGTH_12_BITS 12 +#define PDCP_NR_SN_LENGTH_18_BITS 18 + +#define PDCP_NR_UL_SDAP_HEADER_PRESENT 0x01 +#define PDCP_NR_DL_SDAP_HEADER_PRESENT 0x02 + +enum nr_security_integrity_algorithm_e { nia0, nia1, nia2, nia3 }; +enum nr_security_ciphering_algorithm_e { nea0, nea1, nea2, nea3, nea_disabled=999}; + +typedef struct pdcp_nr_security_info_t +{ + guint32 configuration_frame; + gboolean seen_next_ul_pdu; /* i.e. have we seen SecurityModeResponse */ + enum nr_security_integrity_algorithm_e integrity; + enum nr_security_ciphering_algorithm_e ciphering; + + /* Store previous settings so can revert if get SecurityModeFailure */ + guint32 previous_configuration_frame; + enum nr_security_integrity_algorithm_e previous_integrity; + enum nr_security_ciphering_algorithm_e previous_ciphering; +} pdcp_nr_security_info_t; + + +/*****************************************************************/ +/* UDP framing format */ +/* ----------------------- */ +/* Several people have asked about dissecting PDCP by framing */ +/* PDUs over IP. A suggested format over UDP has been defined */ +/* and implemented by this dissector, using the definitions */ +/* below. */ +/* */ +/* A heuristic dissector (enabled by a preference) will */ +/* recognise a signature at the beginning of these frames. */ +/* Until someone is using this format, suggestions for changes */ +/* are welcome. */ +/*****************************************************************/ + + +/* Signature. Rather than try to define a port for this, or make the + port number a preference, frames will start with this string (with no + terminating NULL */ +#define PDCP_NR_START_STRING "pdcp-nr" + +/* Fixed fields: + - plane (1 byte) */ + +/* Conditional field. This field is mandatory in case of User Plane PDCP PDU. + The format is to have the tag, followed by the value (there is no length field, + it's implicit from the tag). The allowed values are defined above. */ + +#define PDCP_NR_SEQNUM_LENGTH_TAG 0x02 +/* 1 byte */ + +/* Optional fields. Attaching this info should be added if available. + The format is to have the tag, followed by the value (there is no length field, + it's implicit from the tag) */ + +#define PDCP_NR_DIRECTION_TAG 0x03 +/* 1 byte */ + +#define PDCP_NR_BEARER_TYPE_TAG 0x04 +/* 1 byte */ + +#define PDCP_NR_BEARER_ID_TAG 0x05 +/* 1 byte */ + +#define PDCP_NR_UEID_TAG 0x06 +/* 2 bytes, network order */ + +#define PDCP_NR_ROHC_COMPRESSION_TAG 0x07 +/* 0 byte */ + +/* N.B. The following ROHC values only have significance if rohc_compression + is in use for the current channel */ + +#define PDCP_NR_ROHC_IP_VERSION_TAG 0x08 +/* 1 byte */ + +#define PDCP_NR_ROHC_CID_INC_INFO_TAG 0x09 +/* 0 byte */ + +#define PDCP_NR_ROHC_LARGE_CID_PRES_TAG 0x0A +/* 0 byte */ + +#define PDCP_NR_ROHC_MODE_TAG 0x0B +/* 1 byte */ + +#define PDCP_NR_ROHC_RND_TAG 0x0C +/* 0 byte */ + +#define PDCP_NR_ROHC_UDP_CHECKSUM_PRES_TAG 0x0D +/* 0 byte */ + +#define PDCP_NR_ROHC_PROFILE_TAG 0x0E +/* 2 bytes, network order */ + +#define PDCP_NR_MACI_PRES_TAG 0x0F +/* 0 byte */ + +#define PDCP_NR_SDAP_HEADER_TAG 0x10 +/* 1 byte, bitmask with PDCP_NR_UL_SDAP_HEADER_PRESENT and/or PDCP_NR_DL_SDAP_HEADER_PRESENT */ + +#define PDCP_NR_CIPHER_DISABLED_TAG 0x11 +/* 0 byte */ + +/* PDCP PDU. Following this tag comes the actual PDCP PDU (there is no length, the PDU + continues until the end of the frame) */ +#define PDCP_NR_PAYLOAD_TAG 0x01 + + +/* Called by RRC, or other configuration protocols */ + +/* Function to configure ciphering & integrity algorithms */ +void set_pdcp_nr_security_algorithms(guint16 ueid, pdcp_nr_security_info_t *security_info); + +/* Function to indicate securityModeCommand did not complete */ +void set_pdcp_nr_security_algorithms_failed(guint16 ueid); + + +/* Called by external dissectors */ +void set_pdcp_nr_rrc_ciphering_key(guint16 ueid, const char *key); +void set_pdcp_nr_rrc_integrity_key(guint16 ueid, const char *key); +void set_pdcp_nr_up_ciphering_key(guint16 ueid, const char *key); +void set_pdcp_nr_up_integrity_key(guint16 ueid, const char *key); + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ +#endif diff --git a/openair2/X2AP/x2ap_eNB.c b/openair2/X2AP/x2ap_eNB.c index 0474d417df4af2890ae4fcde23678b53d5efdc20..38e6149ccd2ef103f8425720c53816ca3a546cd4 100644 --- a/openair2/X2AP/x2ap_eNB.c +++ b/openair2/X2AP/x2ap_eNB.c @@ -115,7 +115,12 @@ void x2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa if (x2ap_enb_data_p != NULL) { /* some sanity check - to be refined at some point */ if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { - X2AP_ERROR("x2ap_enb_data_p not NULL and sctp state not SCTP_STATE_ESTABLISHED, what to do?\n"); + X2AP_ERROR("x2ap_enb_data_p not NULL and sctp state not SCTP_STATE_ESTABLISHED?\n"); + if (sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN){ + RB_REMOVE(x2ap_enb_map, &instance_p->x2ap_enb_head, x2ap_enb_data_p); + return; + } + exit(1); } diff --git a/openair3/NAS/COMMON/IES/FGSMobileIdentity.c b/openair3/NAS/COMMON/IES/FGSMobileIdentity.c index e3204b4c0c7816fee36eb029067162612b783b1f..5f920105f9b1307ff28d3761853dfbc13893b7c0 100644 --- a/openair3/NAS/COMMON/IES/FGSMobileIdentity.c +++ b/openair3/NAS/COMMON/IES/FGSMobileIdentity.c @@ -194,23 +194,23 @@ static int encode_guti_5gs_mobile_identity(Guti5GSMobileIdentity_t *guti, uint8_ static int encode_suci_5gs_mobile_identity(Suci5GSMobileIdentity_t *suci, uint8_t *buffer) { uint32_t encoded = 0; - *(buffer + encoded) = 0x00 | (suci->supiformat << 4) | (suci->typeofidentity); + *(buffer + encoded) = (suci->supiformat << 4) | (suci->typeofidentity); encoded++; - *(buffer + encoded) = 0x00 | ((suci->mccdigit2 & 0xf) << 4) | + *(buffer + encoded) = ((suci->mccdigit2 & 0xf) << 4) | (suci->mccdigit1 & 0xf); encoded++; - *(buffer + encoded) = 0x00 | ((suci->mncdigit3 & 0xf) << 4) | + *(buffer + encoded) = ((suci->mncdigit3 & 0xf) << 4) | (suci->mccdigit3 & 0xf); encoded++; - *(buffer + encoded) = 0x00 | ((suci->mncdigit2 & 0xf) << 4) | + *(buffer + encoded) = ((suci->mncdigit2 & 0xf) << 4) | (suci->mncdigit1 & 0xf); encoded++; - *(buffer + encoded) = 0x00 | ((suci->routingindicatordigit2 & 0xf) << 4) | + *(buffer + encoded) = ((suci->routingindicatordigit2 & 0xf) << 4) | (suci->routingindicatordigit1 & 0xf); encoded++; - *(buffer + encoded) = 0x00 | ((suci->routingindicatordigit4 & 0xf) << 4) | + *(buffer + encoded) = ((suci->routingindicatordigit4 & 0xf) << 4) | (suci->routingindicatordigit3 & 0xf); encoded++; @@ -220,8 +220,15 @@ static int encode_suci_5gs_mobile_identity(Suci5GSMobileIdentity_t *suci, uint8_ *(buffer + encoded) = suci->homenetworkpki; encoded++; - IES_ENCODE_U32(buffer, encoded, suci->schemeoutput); + char *ptr=suci->schemeoutput; + while ( ptr < suci->schemeoutput+strlen(suci->schemeoutput) ) { + buffer[encoded]=((*(ptr+1)-'0')<<4) | (*(ptr) -'0'); + encoded++; + ptr+=2; + } + if (strlen(suci->schemeoutput)%2 == 1) + buffer[encoded++]=((*(ptr-1)-'0')) | 0xF0; return encoded; } diff --git a/openair3/NAS/COMMON/IES/FGSMobileIdentity.h b/openair3/NAS/COMMON/IES/FGSMobileIdentity.h index a673a86dd1be7eea096edd0eaa603989d7e50951..7968bc33006c255f10fec598edacb78976050e58 100644 --- a/openair3/NAS/COMMON/IES/FGSMobileIdentity.h +++ b/openair3/NAS/COMMON/IES/FGSMobileIdentity.h @@ -64,7 +64,7 @@ typedef struct { uint8_t spare6:1; uint8_t protectionschemeId:4; uint8_t homenetworkpki; - uint32_t schemeoutput; + char schemeoutput[32]; } Suci5GSMobileIdentity_t; typedef struct { diff --git a/openair3/NAS/COMMON/NR_NAS_defs.h b/openair3/NAS/COMMON/NR_NAS_defs.h index 906c0cf504a9d61059c509fc3c758e6605b81907..54ac8c037e9f3b672870ee6489dfb1e3e980ea5e 100644 --- a/openair3/NAS/COMMON/NR_NAS_defs.h +++ b/openair3/NAS/COMMON/NR_NAS_defs.h @@ -387,5 +387,6 @@ void processNAS(void *msg, NRUEcontext_t *UE); int identityRequest(void **msg, NRUEcontext_t *UE); int authenticationRequest(void **msg, NRUEcontext_t *UE); int securityModeCommand(void **msg, NRUEcontext_t *UE); +void servingNetworkName(uint8_t *msg, char * imsiStr, int nmc_size); #endif diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index 55e21390bfe2f49f2e4e2de9276cc571a914a409..7308f677a18a271b41e98f98eb48b25067377bda 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -38,24 +38,15 @@ #include "aka_functions.h" #include "secu_defs.h" #include "PduSessionEstablishRequest.h" -# include "intertask_interface.h" - -/*char netName[] = "5G:mnc093.mcc208.3gppnetwork.org"; -char imsi[] = "2089300007487"; -// USIM_API_K: 5122250214c33e723a5dd523fc145fc0 -uint8_t k[16] = {0x51, 0x22, 0x25, 0x02, 0x14,0xc3, 0x3e, 0x72, 0x3a, 0x5d, 0xd5, 0x23, 0xfc, 0x14, 0x5f, 0xc0}; -// OPC: 981d464c7c52eb6e5036234984ad0bcf -const uint8_t opc[16] = {0x98, 0x1d, 0x46, 0x4c,0x7c,0x52,0xeb, 0x6e, 0x50, 0x36, 0x23, 0x49, 0x84, 0xad, 0x0b, 0xcf};*/ - -char netName[] = "5G:mnc099.mcc208.3gppnetwork.org"; -char imsi[] = "2089900007487"; //"208990100001100"; -// USIM_API_K: fe c8 6b a6 eb 70 7e d0 89 05 75 7b 1b b4 4b 8f -uint8_t k[16] = {0xfe, 0xc8, 0x6b, 0xa6, 0xeb, 0x70, 0x7e, 0xd0, 0x89, 0x05, 0x75, 0x7b, 0x1b, 0xb4, 0x4b, 0x8f}; -// OPC: c4 24 49 36 3b ba d0 2b 66 d1 6b c9 75 d7 7c c1 -const uint8_t opc[16] = {0xc4, 0x24, 0x49, 0x36, 0x3b, 0xba, 0xd0, 0x2b, 0x66, 0xd1, 0x6b, 0xc9, 0x75, 0xd7, 0x7c, 0xc1}; +#include "intertask_interface.h" +#include "openair2/RRC/NAS/nas_config.h" +#include <openair3/UICC/usim_interface.h> +#include <openair3/NAS/COMMON/NR_NAS_defs.h> +#include <openair1/PHY/phy_extern_nr_ue.h> uint8_t *registration_request_buf; uint32_t registration_request_len; +extern char *baseNetAddress; static int nas_protected_security_header_encode( char *buffer, @@ -160,11 +151,11 @@ int mm_msg_encode(MM_msg *mm_msg, uint8_t *buffer, uint32_t len) { LOG_FUNC_RETURN (header_result + encode_result); } -void transferRES(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uint8_t rand[16], uint8_t *output) { - uint8_t S[100]; +void transferRES(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uint8_t rand[16], uint8_t *output, uicc_t* uicc) { + uint8_t S[100]={0}; S[0] = 0x6B; - int netNamesize = strlen(netName); - memcpy(&S[1], netName, netNamesize); + servingNetworkName (S+1, uicc->imsiStr, uicc->nmc_size); + int netNamesize = strlen((char*)S+1); S[1 + netNamesize] = (netNamesize & 0xff00) >> 8; S[2 + netNamesize] = (netNamesize & 0x00ff); for (int i = 0; i < 16; i++) @@ -201,14 +192,15 @@ void transferRES(uint8_t ck[16], uint8_t ik[16], uint8_t *input, uint8_t rand[16 output[i] = out[16 + i]; } -void derive_kausf(uint8_t ck[16], uint8_t ik[16], uint8_t sqn[6], uint8_t kausf[32]) { - uint8_t S[100]; +void derive_kausf(uint8_t ck[16], uint8_t ik[16], uint8_t sqn[6], uint8_t kausf[32], uicc_t *uicc) { + uint8_t S[100]={0}; uint8_t key[32]; - int netNamesize = strlen(netName); + memcpy(&key[0], ck, 16); memcpy(&key[16], ik, 16); //KEY S[0] = 0x6A; - memcpy(&S[1], netName, netNamesize); + servingNetworkName (S+1, uicc->imsiStr, uicc->nmc_size); + int netNamesize = strlen((char*)S+1); S[1 + netNamesize] = (uint8_t)((netNamesize & 0xff00) >> 8); S[2 + netNamesize] = (uint8_t)(netNamesize & 0x00ff); for (int i = 0; i < 6; i++) { @@ -219,21 +211,21 @@ void derive_kausf(uint8_t ck[16], uint8_t ik[16], uint8_t sqn[6], uint8_t kausf[ kdf(key, 32, S, 11 + netNamesize, kausf, 32); } -void derive_kseaf(uint8_t kausf[32], uint8_t kseaf[32]) { - uint8_t S[100]; - int netNamesize = strlen(netName); +void derive_kseaf(uint8_t kausf[32], uint8_t kseaf[32], uicc_t *uicc) { + uint8_t S[100]={0}; S[0] = 0x6C; //FC - memcpy(&S[1], netName, netNamesize); + servingNetworkName (S+1, uicc->imsiStr, uicc->nmc_size); + int netNamesize = strlen((char*)S+1); S[1 + netNamesize] = (uint8_t)((netNamesize & 0xff00) >> 8); S[2 + netNamesize] = (uint8_t)(netNamesize & 0x00ff); kdf(kausf, 32, S, 3 + netNamesize, kseaf, 32); } -void derive_kamf(uint8_t *kseaf, uint8_t *kamf, uint16_t abba) { - int imsiLen = strlen(imsi); +void derive_kamf(uint8_t *kseaf, uint8_t *kamf, uint16_t abba, uicc_t* uicc) { + int imsiLen = strlen(uicc->imsiStr); uint8_t S[100]; S[0] = 0x6D; //FC = 0x6D - memcpy(&S[1], imsi, imsiLen); + memcpy(&S[1], uicc->imsiStr, imsiLen ); S[1 + imsiLen] = (uint8_t)((imsiLen & 0xff00) >> 8); S[2 + imsiLen] = (uint8_t)(imsiLen & 0x00ff); S[3 + imsiLen] = abba & 0x00ff; @@ -259,11 +251,11 @@ void derive_knas(algorithm_type_dist_t nas_alg_type, uint8_t nas_alg_id, uint8_t knas_int[i] = out[16 + i]; } -void generateRegistrationRequest(as_nas_info_t *initialNasMsg) { +void generateRegistrationRequest(as_nas_info_t *initialNasMsg, int Mod_id) { int size = sizeof(mm_msg_header_t); - fgs_nas_message_t nas_msg; - memset(&nas_msg, 0, sizeof(fgs_nas_message_t)); + fgs_nas_message_t nas_msg={0}; MM_msg *mm_msg; + uicc_t * uicc=checkUicc(Mod_id); mm_msg = &nas_msg.plain.mm_msg; // set header @@ -288,26 +280,31 @@ void generateRegistrationRequest(as_nas_info_t *initialNasMsg) { mm_msg->registration_request.fgsmobileidentity.guti.amfpointer = 0; mm_msg->registration_request.fgsmobileidentity.guti.amfsetid = 1016; mm_msg->registration_request.fgsmobileidentity.guti.tmsi = 10; - mm_msg->registration_request.fgsmobileidentity.guti.mncdigit1 = 9; - mm_msg->registration_request.fgsmobileidentity.guti.mncdigit2 = 9; - mm_msg->registration_request.fgsmobileidentity.guti.mncdigit3 = 0xf; - mm_msg->registration_request.fgsmobileidentity.guti.mccdigit1 = 2; - mm_msg->registration_request.fgsmobileidentity.guti.mccdigit2 = 0; - mm_msg->registration_request.fgsmobileidentity.guti.mccdigit3 = 8; + mm_msg->registration_request.fgsmobileidentity.guti.mncdigit1 = + uicc->nmc_size==2 ? uicc->imsiStr[3]-'0' : uicc->imsiStr[4]-'0'; + mm_msg->registration_request.fgsmobileidentity.guti.mncdigit2 = + uicc->nmc_size==2 ? uicc->imsiStr[4]-'0' : uicc->imsiStr[5]-'0'; + mm_msg->registration_request.fgsmobileidentity.guti.mncdigit3 = + uicc->nmc_size==2 ? 0xf : uicc->imsiStr[3]-'0'; + mm_msg->registration_request.fgsmobileidentity.guti.mccdigit1 = uicc->imsiStr[0]-'0'; + mm_msg->registration_request.fgsmobileidentity.guti.mccdigit2 = uicc->imsiStr[1]-'0'; + mm_msg->registration_request.fgsmobileidentity.guti.mccdigit3 = uicc->imsiStr[2]-'0'; size += 13; } else { mm_msg->registration_request.fgsmobileidentity.suci.typeofidentity = FGS_MOBILE_IDENTITY_SUCI; - mm_msg->registration_request.fgsmobileidentity.suci.mncdigit1 = 9; - mm_msg->registration_request.fgsmobileidentity.suci.mncdigit2 = 9; - mm_msg->registration_request.fgsmobileidentity.suci.mncdigit3 = 0xf; - mm_msg->registration_request.fgsmobileidentity.suci.mccdigit1 = 2; - mm_msg->registration_request.fgsmobileidentity.suci.mccdigit2 = 0; - mm_msg->registration_request.fgsmobileidentity.suci.mccdigit3 = 8; - mm_msg->registration_request.fgsmobileidentity.suci.schemeoutput = 0x4778; - - size += 14; + mm_msg->registration_request.fgsmobileidentity.suci.mncdigit1 = + uicc->nmc_size==2 ? uicc->imsiStr[3]-'0' : uicc->imsiStr[4]-'0'; + mm_msg->registration_request.fgsmobileidentity.suci.mncdigit2 = + uicc->nmc_size==2 ? uicc->imsiStr[4]-'0' : uicc->imsiStr[5]-'0'; + mm_msg->registration_request.fgsmobileidentity.suci.mncdigit3 = + uicc->nmc_size==2 ? 0xf : uicc->imsiStr[3]-'0'; + mm_msg->registration_request.fgsmobileidentity.suci.mccdigit1 = uicc->imsiStr[0]-'0'; + mm_msg->registration_request.fgsmobileidentity.suci.mccdigit2 = uicc->imsiStr[1]-'0'; + mm_msg->registration_request.fgsmobileidentity.suci.mccdigit3 = uicc->imsiStr[2]-'0'; + memcpy(mm_msg->registration_request.fgsmobileidentity.suci.schemeoutput, uicc->imsiStr+3+uicc->nmc_size, strlen(uicc->imsiStr) - (3+uicc->nmc_size)); + size += sizeof(Suci5GSMobileIdentity_t); } mm_msg->registration_request.presencemask |= REGISTRATION_REQUEST_5GMM_CAPABILITY_PRESENT; @@ -334,7 +331,7 @@ void generateRegistrationRequest(as_nas_info_t *initialNasMsg) { } -void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype) { +void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype, uicc_t* uicc) { int size = sizeof(mm_msg_header_t); fgs_nas_message_t nas_msg; memset(&nas_msg, 0, sizeof(fgs_nas_message_t)); @@ -356,15 +353,17 @@ void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype size += 1; if(identitytype == FGS_MOBILE_IDENTITY_SUCI){ mm_msg->fgs_identity_response.fgsmobileidentity.suci.typeofidentity = FGS_MOBILE_IDENTITY_SUCI; - mm_msg->fgs_identity_response.fgsmobileidentity.suci.mncdigit1 = 9; - mm_msg->fgs_identity_response.fgsmobileidentity.suci.mncdigit2 = 9; - mm_msg->fgs_identity_response.fgsmobileidentity.suci.mncdigit3 = 0xf; - mm_msg->fgs_identity_response.fgsmobileidentity.suci.mccdigit1 = 2; - mm_msg->fgs_identity_response.fgsmobileidentity.suci.mccdigit2 = 0; - mm_msg->fgs_identity_response.fgsmobileidentity.suci.mccdigit3 = 8; - mm_msg->fgs_identity_response.fgsmobileidentity.suci.schemeoutput = 0x4778; - - size += 14; + mm_msg->fgs_identity_response.fgsmobileidentity.suci.mncdigit1 = + uicc->nmc_size==2 ? uicc->imsiStr[3]-'0' : uicc->imsiStr[4]-'0'; + mm_msg->fgs_identity_response.fgsmobileidentity.suci.mncdigit2 = + uicc->nmc_size==2 ? uicc->imsiStr[4]-'0' : uicc->imsiStr[5]-'0'; + mm_msg->fgs_identity_response.fgsmobileidentity.suci.mncdigit3 = + uicc->nmc_size==2? 0xF : uicc->imsiStr[3]-'0'; + mm_msg->fgs_identity_response.fgsmobileidentity.suci.mccdigit1 = uicc->imsiStr[0]-'0'; + mm_msg->fgs_identity_response.fgsmobileidentity.suci.mccdigit2 = uicc->imsiStr[1]-'0'; + mm_msg->fgs_identity_response.fgsmobileidentity.suci.mccdigit3 = uicc->imsiStr[2]-'0'; + memcpy(mm_msg->registration_request.fgsmobileidentity.suci.schemeoutput, uicc->imsiStr+3+uicc->nmc_size, strlen(uicc->imsiStr) - (3+uicc->nmc_size)); + size += sizeof(Suci5GSMobileIdentity_t); } // encode the message @@ -375,7 +374,7 @@ void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype } OctetString knas_int; -void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *buf){ +static void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *buf, uicc_t *uicc){ uint8_t ak[6]; @@ -393,9 +392,9 @@ void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *buf){ uint8_t resTemp[16]; uint8_t ck[16], ik[16], output[16]; - f2345(k, rand, resTemp, ck, ik, ak, opc); + f2345(uicc->key, rand, resTemp, ck, ik, ak, uicc->opc); - transferRES(ck, ik, resTemp, rand, output); + transferRES(ck, ik, resTemp, rand, output, uicc); // get knas_int knas_int.length = 16; @@ -404,9 +403,9 @@ void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *buf){ sqn[index] = buf[26+index]; } - derive_kausf(ck, ik, sqn, kausf); - derive_kseaf(kausf, kseaf); - derive_kamf(kseaf, kamf, 0x0000); + derive_kausf(ck, ik, sqn, kausf, uicc); + derive_kseaf(kausf, kseaf, uicc); + derive_kamf(kseaf, kamf, 0x0000, uicc); derive_knas(0x02, 2, kamf, knas_int.value); printf("kausf:"); @@ -613,6 +612,19 @@ void generateRegistrationComplete(as_nas_info_t *initialNasMsg, SORTransparentCo } } +void decodeDownlinkNASTransport(as_nas_info_t *initialNasMsg, uint8_t * pdu_buffer){ + uint8_t msg_type = *(pdu_buffer + 16); + if(msg_type == FGS_PDU_SESSION_ESTABLISHMENT_ACC){ + sprintf(baseNetAddress, "%d.%d", *(pdu_buffer + 39),*(pdu_buffer + 40)); + int third_octet = *(pdu_buffer + 41); + int fourth_octet = *(pdu_buffer + 42); + LOG_I(NAS, "Received PDU Session Establishment Accept\n"); + nas_config(1,third_octet,fourth_octet,"ue"); + } else { + LOG_E(NAS, "Received unexpected message in DLinformationTransfer %d\n", msg_type); + } +} + void generatePduSessionEstablishRequest(as_nas_info_t *initialNasMsg){ //wait send RegistrationComplete usleep(100*150); @@ -700,6 +712,7 @@ void generatePduSessionEstablishRequest(as_nas_info_t *initialNasMsg){ } } + void *nas_nrue_task(void *args_p) { MessageDef *msg_p; @@ -719,6 +732,8 @@ void *nas_nrue_task(void *args_p) if (msg_p != NULL) { instance = msg_p->ittiMsgHeader.originInstance; Mod_id = instance ; + uicc_t *uicc=checkUicc(Mod_id); + if (instance == INSTANCE_DEFAULT) { printf("%s:%d: FATAL: instance is INSTANCE_DEFAULT, should not happen.\n", __FILE__, __LINE__); @@ -815,6 +830,16 @@ void *nas_nrue_task(void *args_p) LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(PduSessionEstablishRequest)\n"); } } + else if((pdu_buffer + 16) != NULL){ + msg_type = *(pdu_buffer + 16); + if(msg_type == FGS_PDU_SESSION_ESTABLISHMENT_ACC){ + sprintf(baseNetAddress, "%d.%d", *(pdu_buffer + 39),*(pdu_buffer + 40)); + int third_octet = *(pdu_buffer + 41); + int fourth_octet = *(pdu_buffer + 42); + LOG_I(NAS, "Received PDU Session Establishment Accept\n"); + nas_config(1,third_octet,fourth_octet,"ue"); + } + } break; } @@ -838,8 +863,7 @@ void *nas_nrue_task(void *args_p) Mod_id, NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.length, NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data); - as_nas_info_t initialNasMsg; - memset(&initialNasMsg, 0, sizeof(as_nas_info_t)); + as_nas_info_t initialNasMsg={0}; pdu_buffer = NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data; if((pdu_buffer + 1) != NULL){ @@ -856,14 +880,18 @@ void *nas_nrue_task(void *args_p) switch(msg_type){ case FGS_IDENTITY_REQUEST: - generateIdentityResponse(&initialNasMsg,*(pdu_buffer+3)); + generateIdentityResponse(&initialNasMsg,*(pdu_buffer+3), uicc); break; case FGS_AUTHENTICATION_REQUEST: - generateAuthenticationResp(&initialNasMsg, pdu_buffer); + generateAuthenticationResp(&initialNasMsg, pdu_buffer, uicc); break; case FGS_SECURITY_MODE_COMMAND: generateSecurityModeComplete(&initialNasMsg); break; + case FGS_DOWNLINK_NAS_TRANSPORT: + decodeDownlinkNASTransport(&initialNasMsg, pdu_buffer); + break; + default: LOG_W(NR_RRC,"unknow message type %d\n",msg_type); break; diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.h b/openair3/NAS/NR_UE/nr_nas_msg_sim.h index 2f123a6f04822605d18b5d721947c164c9c80460..348c27ecc89d44d1a4d6fd2bd250819f4203d401 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.h +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.h @@ -56,9 +56,11 @@ #define FGS_SECURITY_MODE_COMMAND 0b01011101 /* 93 = 0x5d */ #define FGS_SECURITY_MODE_COMPLETE 0b01011110 /* 94 = 0x5e */ #define FGS_UPLINK_NAS_TRANSPORT 0b01100111 /* 103= 0x67 */ +#define FGS_DOWNLINK_NAS_TRANSPORT 0b01101000 /* 104= 0x68 */ // message type for 5GS session management #define FGS_PDU_SESSION_ESTABLISHMENT_REQ 0b11000001 /* 193= 0xc1 */ +#define FGS_PDU_SESSION_ESTABLISHMENT_ACC 0b11000010 /* 194= 0xc2 */ #define INITIAL_REGISTRATION 0b001 @@ -114,9 +116,7 @@ typedef union { fgs_nas_message_plain_t plain; } fgs_nas_message_t; -void generateRegistrationRequest(as_nas_info_t *initialNasMsg); -void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype); -void generateAuthenticationResp(as_nas_info_t *initialNasMsg, uint8_t *buf); +void generateRegistrationRequest(as_nas_info_t *initialNasMsg, int Mod_id); void generateSecurityModeComplete(as_nas_info_t *initialNasMsg); void generateRegistrationComplete(as_nas_info_t *initialNasMsg, SORTransparentContainer *sortransparentcontainer); void generatePduSessionEstablishRequest(as_nas_info_t *initialNasMsg); diff --git a/openair3/NGAP/ngap_common.h b/openair3/NGAP/ngap_common.h index 6803adb0dda43fface7944d7d9ac93dd106df38f..283dd2bffa58ae41aca733b9a955053f04bb0bf1 100644 --- a/openair3/NGAP/ngap_common.h +++ b/openair3/NGAP/ngap_common.h @@ -142,7 +142,11 @@ extern int asn1_xer_print; } \ } \ if (ie == NULL ) { \ - NGAP_ERROR("NGAP_FIND_PROTOCOLIE_BY_ID: %s %d: ie is NULL\n",__FILE__,__LINE__);\ + if (mandatory) {\ + NGAP_ERROR("NGAP_FIND_PROTOCOLIE_BY_ID: %s %d: ie is NULL (searching for ie: %ld)\n",__FILE__,__LINE__, IE_ID);\ + abort();\ + }\ + else NGAP_INFO("NGAP_FIND_PROTOCOLIE_BY_ID: %s %d: ie is NULL (searching for ie: %ld)\n",__FILE__,__LINE__, IE_ID);\ } \ } while(0) /** \brief Function callback prototype. diff --git a/openair3/NGAP/ngap_gNB_handlers.c b/openair3/NGAP/ngap_gNB_handlers.c index e398f8fa3e1c39d0e5ac5a9d18ce57c766c794ef..401695473cfc044c16baa9912e977b16711f2a56 100644 --- a/openair3/NGAP/ngap_gNB_handlers.c +++ b/openair3/NGAP/ngap_gNB_handlers.c @@ -657,6 +657,7 @@ int ngap_gNB_handle_error_indication(uint32_t assoc_id, case NGAP_CauseRadioNetwork_up_integrity_protection_not_possible: NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_up_integrity_protection_not_possible\n"); break; + case NGAP_CauseRadioNetwork_up_confidentiality_protection_not_possible: NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_up_confidentiality_protection_not_possible\n"); break; @@ -1030,6 +1031,12 @@ int ngap_gNB_handle_initial_context_request(uint32_t assoc_id, /* Set the QOS informations */ NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].qos[qosIdx].qfi = (uint8_t)qosFlowItem_p->qosFlowIdentifier; + if(qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.present == NGAP_QosCharacteristics_PR_nonDynamic5QI){ + if(qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.choice.nonDynamic5QI != NULL){ + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].qos[qosIdx].fiveQI = + (uint64_t)qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.choice.nonDynamic5QI->fiveQI; + } + } NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].qos[qosIdx].allocation_retention_priority.priority_level = qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority.priorityLevelARP; @@ -1063,13 +1070,14 @@ int ngap_gNB_handle_initial_context_request(uint32_t assoc_id, //if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */ NGAP_AllowedNSSAI_Item_t *allow_nssai_item_p = NULL; - - NGAP_WARN("AllowedNSSAI.list.count %d\n", ie != NULL ? ie->value.choice.AllowedNSSAI.list.count : 2); + //NGAP_DEBUG("AllowedNSSAI.list.count %d\n", ie->value.choice.AllowedNSSAI.list.count); //DevAssert(ie->value.choice.AllowedNSSAI.list.count > 0); //DevAssert(ie->value.choice.AllowedNSSAI.list.count <= NGAP_maxnoofAllowedS_NSSAIs); if (ie == NULL) { + NGAP_WARN("AllowedNSSAI not present, forging 2 NSSAI\n"); + NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).nb_allowed_nssais = 2; NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[0].sST = 01; @@ -1086,7 +1094,7 @@ int ngap_gNB_handle_initial_context_request(uint32_t assoc_id, NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[1].sD[1] = 00;//22; NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[1].sD[2] = 01;//33; } else { - + NGAP_INFO("AllowedNSSAI.list.count %d\n", ie->value.choice.AllowedNSSAI.list.count); NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).nb_allowed_nssais = ie->value.choice.AllowedNSSAI.list.count; for(i = 0; i < ie->value.choice.AllowedNSSAI.list.count; i++) { diff --git a/openair3/NGAP/ngap_gNB_nas_procedures.c b/openair3/NGAP/ngap_gNB_nas_procedures.c index 6b6164358837893ab60649259c40541eeb9c4ece..8efab98dfa60d7f77ba5e7ed18806eb2d1a68cc8 100644 --- a/openair3/NGAP/ngap_gNB_nas_procedures.c +++ b/openair3/NGAP/ngap_gNB_nas_procedures.c @@ -656,6 +656,7 @@ int ngap_gNB_initial_ctxt_resp( NGAP_InitialContextSetupResponse_t *out; NGAP_InitialContextSetupResponseIEs_t *ie; uint8_t *buffer = NULL; + uint8_t pdusessionTransfer_buffer[1000]; uint32_t length; int i; asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} }; @@ -729,7 +730,8 @@ int ngap_gNB_initial_ctxt_resp( pdusessionTransfer_p = (NGAP_PDUSessionResourceSetupResponseTransfer_t *)calloc(1, sizeof(NGAP_PDUSessionResourceSetupResponseTransfer_t)); pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.present = NGAP_UPTransportLayerInformation_PR_gTPTunnel; - + + pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel = (NGAP_GTPTunnel_t *)calloc(1, sizeof(NGAP_GTPTunnel_t)); GTP_TEID_TO_ASN1(initial_ctxt_resp_p->pdusessions[i].gtp_teid, &pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->gTP_TEID); pdusessionTransfer_p->dLQosFlowPerTNLInformation.uPTransportLayerInformation.choice.gTPTunnel->transportLayerAddress.buf = malloc(initial_ctxt_resp_p->pdusessions[i].gNB_addr.length); @@ -757,17 +759,30 @@ int ngap_gNB_initial_ctxt_resp( ass_qos_item_p->qosFlowIdentifier = initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qfi; /* qosFlowMappingIndication */ - if(initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind != QOSFLOW_MAPPING_INDICATION_NON) { - ass_qos_item_p->qosFlowMappingIndication = malloc(sizeof(*ass_qos_item_p->qosFlowMappingIndication)); - *ass_qos_item_p->qosFlowMappingIndication = initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind; - } + //if(initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind != QOSFLOW_MAPPING_INDICATION_NON) { + // ass_qos_item_p->qosFlowMappingIndication = malloc(sizeof(*ass_qos_item_p->qosFlowMappingIndication)); + // *ass_qos_item_p->qosFlowMappingIndication = initial_ctxt_resp_p->pdusessions[i].associated_qos_flows[j].qos_flow_mapping_ind; + // } ASN_SEQUENCE_ADD(&pdusessionTransfer_p->dLQosFlowPerTNLInformation.associatedQosFlowList.list, ass_qos_item_p); } memset(&res, 0, sizeof(res)); - res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p); - item->pDUSessionResourceSetupResponseTransfer.buf = res.buffer; - item->pDUSessionResourceSetupResponseTransfer.size = res.result.encoded; + //res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p); + //item->pDUSessionResourceSetupResponseTransfer.buf = res.buffer; + //item->pDUSessionResourceSetupResponseTransfer.size = res.result.encoded; + + if (asn1_xer_print) { + xer_fprint(stdout, &asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p); + } + + memset(pdusessionTransfer_buffer, 0, 1000); + asn_enc_rval_t enc_rval = aper_encode_to_buffer(&asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, + NULL, + pdusessionTransfer_p, + pdusessionTransfer_buffer,1000); + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); + item->pDUSessionResourceSetupResponseTransfer.buf = pdusessionTransfer_buffer; + item->pDUSessionResourceSetupResponseTransfer.size = enc_rval.encoded; ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, pdusessionTransfer_p); @@ -846,6 +861,10 @@ int ngap_gNB_initial_ctxt_resp( ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); } + if (asn1_xer_print) { + xer_fprint(stdout, &asn_DEF_NGAP_NGAP_PDU, &pdu); + } + if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { NGAP_ERROR("Failed to encode InitialContextSetupResponse\n"); /* Encode procedure has failed... */ diff --git a/openair3/SCTP/sctp_eNB_task.c b/openair3/SCTP/sctp_eNB_task.c index af49c5c350d9cde5d6db36ffb31c78cb9749ca48..a14d4b9780c487b8f1cf01d3b510de2bc486041a 100644 --- a/openair3/SCTP/sctp_eNB_task.c +++ b/openair3/SCTP/sctp_eNB_task.c @@ -985,6 +985,7 @@ sctp_eNB_read_from_socket( if (SCTP_SHUTDOWN_EVENT == snp->sn_header.sn_type) { itti_unsubscribe_event_fd(TASK_SCTP, sctp_cnx->sd); + SCTP_WARN("Received SCTP SHUTDOWN EVENT\n"); close(sctp_cnx->sd); sctp_itti_send_association_resp( @@ -1026,7 +1027,14 @@ sctp_eNB_read_from_socket( break; default: - SCTP_WARN("unhandled: SCTP_ASSOC_CHANGE to %d\n", sctp_assoc_changed->sac_state); + if ( sctp_assoc_changed->sac_state == SCTP_SHUTDOWN_COMP) + SCTP_WARN("SCTP_ASSOC_CHANGE to SSCTP_SHUTDOWN_COMP\n"); + if ( sctp_assoc_changed->sac_state == SCTP_RESTART) + SCTP_WARN("SCTP_ASSOC_CHANGE to SCTP_RESTART\n"); + if ( sctp_assoc_changed->sac_state == SCTP_CANT_STR_ASSOC) + SCTP_ERROR("SCTP_ASSOC_CHANGE to SCTP_CANT_STR_ASSOC\n"); + if ( sctp_assoc_changed->sac_state == SCTP_COMM_LOST) + SCTP_ERROR("SCTP_ASSOC_CHANGE to SCTP_COMM_LOST\n"); break; } } diff --git a/openair3/UICC/usim_interface.c b/openair3/UICC/usim_interface.c index 15a4e2e540e3b894b998d2c5628200d4ac05f74d..0973d7508204a3ab0f8536bf9225256ef1e3bbca 100644 --- a/openair3/UICC/usim_interface.c +++ b/openair3/UICC/usim_interface.c @@ -20,9 +20,11 @@ * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org */ +#include <ctype.h> #include <openair3/UICC/usim_interface.h> #include <openair3/NAS/COMMON/milenage.h> +extern uint16_t NB_UE_INST; #define UICC_SECTION "uicc" #define UICC_CONFIG_HELP_OPTIONS " list of comma separated options to interface a simulated (real UICC to be developped). Available options: \n"\ @@ -34,18 +36,20 @@ /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ #define UICC_PARAMS_DESC {\ - {"imsi", "USIM IMSI\n", 0, strptr:&(uicc->imsiStr), defstrval:"", TYPE_STRING, 0 },\ + {"imsi", "USIM IMSI\n", 0, strptr:&(uicc->imsiStr), defstrval:"2089900007487", TYPE_STRING, 0 },\ {"nmc_size" "number of digits in NMC", 0, iptr:&(uicc->nmc_size), defintval:2, TYPE_INT, 0 },\ - {"key", "USIM Ki\n", 0, strptr:&(uicc->keyStr), defstrval:"", TYPE_STRING, 0 },\ - {"opc", "USIM OPc\n", 0, strptr:&(uicc->opcStr), defstrval:"", TYPE_STRING, 0 },\ + {"key", "USIM Ki\n", 0, strptr:&(uicc->keyStr), defstrval:"fec86ba6eb707ed08905757b1bb44b8f", TYPE_STRING, 0 },\ + {"opc", "USIM OPc\n", 0, strptr:&(uicc->opcStr), defstrval:"c42449363bbad02b66d16bc975d77cc1", TYPE_STRING, 0 },\ {"amf", "USIM amf\n", 0, strptr:&(uicc->amfStr), defstrval:"8000", TYPE_STRING, 0 },\ {"sqn", "USIM sqn\n", 0, strptr:&(uicc->sqnStr), defstrval:"000000", TYPE_STRING, 0 },\ }; +static uicc_t** uiccArray=NULL; + const char *hexTable="0123456789abcdef"; static inline uint8_t mkDigit(unsigned char in) { for (int i=0; i<16; i++) - if (in==hexTable[i]) + if (tolower(in)==hexTable[i]) return i; LOG_E(SIM,"Impossible hexa input: %c\n",in); return 0; @@ -65,7 +69,7 @@ uicc_t *init_uicc(char *sectionName) { // we can read the IMSI from the USIM // key, OPc, sqn, amf don't need to be read from the true USIM int ret = config_get( uicc_params,sizeof(uicc_params)/sizeof(paramdef_t),sectionName); - AssertFatal(ret >= 0, "configuration couldn't be performed"); + AssertFatal(ret >= 0, "configuration couldn't be performed for uicc name: %s", sectionName); LOG_I(SIM, "UICC simulation: IMSI=%s, Ki=%s, OPc=%s\n", uicc->imsiStr, uicc->keyStr, uicc->opcStr); to_hex(uicc->keyStr,uicc->key, sizeof(uicc->key) ); to_hex(uicc->opcStr,uicc->opc, sizeof(uicc->opc) ); @@ -90,3 +94,15 @@ void uicc_milenage_generate(uint8_t *autn, uicc_t *uicc) { log_dump(SIM,autn,sizeof(autn), LOG_DUMP_CHAR,"milenage output autn:"); } +uicc_t * checkUicc(int Mod_id) { + AssertFatal(Mod_id < NB_UE_INST, "Mod_id must be less than NB_UE_INST. Mod_id:%d NB_UE_INST:%d", Mod_id,NB_UE_INST); + if(uiccArray==NULL){ + uiccArray=(uicc_t **)calloc(1,sizeof(uicc_t*)*NB_UE_INST); + } + if (!uiccArray[Mod_id]) { + char uiccName[64]; + sprintf(uiccName,"uicc%d", Mod_id); + uiccArray[Mod_id]=(void*)init_uicc(uiccName); + } + return (uicc_t*) uiccArray[Mod_id]; +} diff --git a/openair3/UICC/usim_interface.h b/openair3/UICC/usim_interface.h index e8f241c1e815403905a8a551237f6382ccb1a65e..44c27c772ed32ada79fda8dc37bb9535f07226cd 100644 --- a/openair3/UICC/usim_interface.h +++ b/openair3/UICC/usim_interface.h @@ -66,6 +66,8 @@ typedef struct { /* * Read the configuration file, section name variable to be able to manage several UICC */ +uicc_t *checkUicc(int Mod_id); uicc_t *init_uicc(char *sectionName); void uicc_milenage_generate(uint8_t * autn, uicc_t *uicc); +uicc_t * checkUicc(int Mod_id); #endif diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp index 82a1d782ec5dc364a214763b95e6bffc58efdcd9..e12a4d66a85d3d9b0724159f2f6dbafcc5a89d83 100644 --- a/openair3/ocp-gtpu/gtp_itf.cpp +++ b/openair3/ocp-gtpu/gtp_itf.cpp @@ -275,12 +275,15 @@ static void gtpv1uEndTunnel(instance_t instance, gtpv1u_enb_tunnel_data_req_t *r to.sin_family = AF_INET; to.sin_port = htons(tmp.outgoing_port); to.sin_addr.s_addr = tmp.outgoing_ip_addr; + + char ip4[INET_ADDRSTRLEN]; + //char ip6[INET6_ADDRSTRLEN]; LOG_D(GTPU,"sending end packet to %s\n", inet_ntoa(to.sin_addr) ); if (sendto(compatInst(instance), (void *)&msgHdr, sizeof(msgHdr), 0,(struct sockaddr *)&to, sizeof(to) ) != sizeof(msgHdr)) { LOG_E(GTPU, - "[SD %ld] Failed to send data to " IPV4_ADDR " on port %d, buffer size %lu\n", - compatInst(instance), IPV4_ADDR_FORMAT(tmp.outgoing_ip_addr), tmp.outgoing_port, sizeof(msgHdr)); + "[SD %ld] Failed to send data to %s on port %d, buffer size %lu\n", + compatInst(instance), inet_ntop(AF_INET, &tmp.outgoing_ip_addr, ip4, INET_ADDRSTRLEN), tmp.outgoing_port, sizeof(msgHdr)); } } @@ -547,6 +550,7 @@ int gtpv1u_update_ngu_tunnel( const gtpv1u_gnb_create_tunnel_req_t *const create_tunnel_req_pP, const rnti_t prior_rnti ) { + AssertFatal( false, "to be developped\n"); return GTPNOK; } @@ -718,7 +722,7 @@ static int Gtpv1uHandleGpdu(int h, int offset=8; if( msgHdr->E || msgHdr->S ||msgHdr->PN) - offset+=4; + offset+=8; // This context is not good for gtp // frame, ... has no meaning diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index fd4a830a02bbce970bc140784ef9e332d95a1eca..877f60799049d0d7a3f963fe24c9cec81d5a3809 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -385,14 +385,14 @@ static int trx_usrp_write(openair0_device *device, #if defined(__x86_64) || defined(__i386__) #ifdef __AVX2__ nsamps2 = (nsamps+7)>>3; - __m256i buff_tx[8][nsamps2]; + __m256i buff_tx[cc<2?2:cc][nsamps2]; #else nsamps2 = (nsamps+3)>>2; - __m128i buff_tx[8][nsamps2]; + __m128i buff_tx[cc<2?2:cc][nsamps2]; #endif #elif defined(__arm__) nsamps2 = (nsamps+3)>>2; - int16x8_t buff_tx[8][nsamps2]; + int16x8_t buff_tx[cc<2?2:cc][nsamps2]; #else #error Unsupported CPU architecture, USRP device cannot be built #endif @@ -523,14 +523,14 @@ void *trx_usrp_write_thread(void * arg){ #if defined(__x86_64) || defined(__i386__) #ifdef __AVX2__ nsamps2 = (nsamps+7)>>3; - __m256i buff_tx[8][nsamps2]; + __m256i buff_tx[cc<2?2:cc][nsamps2]; #else nsamps2 = (nsamps+3)>>2; - __m128i buff_tx[8][nsamps2]; + __m128i buff_tx[cc<2?2:cc][nsamps2]; #endif #elif defined(__arm__) nsamps2 = (nsamps+3)>>2; - int16x8_t buff_tx[8][nsamps2]; + int16x8_t buff_tx[cc<2?2:cc][nsamps2]; #else #error Unsupported CPU architecture, USRP device cannot be built #endif @@ -582,7 +582,6 @@ void *trx_usrp_write_thread(void * arg){ VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_USRP_SEND_RETURN, ret ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_THREAD, 0 ); - if(0) break; } return NULL; @@ -625,14 +624,14 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp #if defined(__x86_64) || defined(__i386__) #ifdef __AVX2__ nsamps2 = (nsamps+7)>>3; - __m256i buff_tmp[4][nsamps2]; + __m256i buff_tmp[cc<2 ? 2 : cc][nsamps2]; #else nsamps2 = (nsamps+3)>>2; - __m128i buff_tmp[4][nsamps2]; + __m128i buff_tmp[cc<2 ? 2 : cc][nsamps2]; #endif #elif defined(__arm__) nsamps2 = (nsamps+3)>>2; - int16x8_t buff_tmp[4][nsamps2]; + int16x8_t buff_tmp[cc<2 ? 2 : cc][nsamps2]; #endif int rxshift; @@ -645,44 +644,33 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp rxshift=2; break; default: - AssertFatal(1==0,"Shouldn't be here\n"); - } - if (cc>1) { - // receive multiple channels (e.g. RF A and RF B) - std::vector<void *> buff_ptrs; - - samples_received=0; + AssertFatal(1==0,"Shouldn't be here\n"); + } - while (samples_received != nsamps) { - for (int i=0; i<cc; i++) buff_ptrs.push_back(buff_tmp[i]+samples_received); - samples_received += s->rx_stream->recv(buff_ptrs,nsamps-samples_received, s->rx_md); + samples_received=0; + while (samples_received != nsamps) { + if (cc>1) { + // receive multiple channels (e.g. RF A and RF B) + std::vector<void *> buff_ptrs; - if ((s->wait_for_first_pps == 0) && (s->rx_md.error_code!=uhd::rx_metadata_t::ERROR_CODE_NONE)) - break; + for (int i=0; i<cc; i++) buff_ptrs.push_back(buff_tmp[i]+samples_received); - if ((s->wait_for_first_pps == 1) && (samples_received != nsamps)) { - printf("sleep...\n"); //usleep(100); - } - } - if (samples_received == nsamps) s->wait_for_first_pps=0; - } else { + samples_received += s->rx_stream->recv(buff_ptrs, nsamps, s->rx_md); + } else { // receive a single channel (e.g. from connector RF A) - samples_received=0; - while (samples_received != nsamps) { samples_received += s->rx_stream->recv((void*)((int32_t*)buff_tmp[0]+samples_received), nsamps-samples_received, s->rx_md); + } + if ((s->wait_for_first_pps == 0) && (s->rx_md.error_code!=uhd::rx_metadata_t::ERROR_CODE_NONE)) + break; - if ((s->wait_for_first_pps == 0) && (s->rx_md.error_code!=uhd::rx_metadata_t::ERROR_CODE_NONE)) - break; - - if ((s->wait_for_first_pps == 1) && (samples_received != nsamps)) { - printf("sleep...\n"); //usleep(100); - } + if ((s->wait_for_first_pps == 1) && (samples_received != nsamps)) { + printf("sleep...\n"); //usleep(100); } - if (samples_received == nsamps) s->wait_for_first_pps=0; } + if (samples_received == nsamps) s->wait_for_first_pps=0; // bring RX data into 12 LSBs for softmodem RX for (int i=0; i<cc; i++) { @@ -1271,7 +1259,7 @@ extern "C" { gain - gain_range.stop()); gain=gain_range.stop(); } - + s->usrp->set_rx_gain(gain,i); LOG_I(HW,"RX Gain %d %f (%f) => %f (max %f)\n",i, openair0_cfg[0].rx_gain[i],openair0_cfg[0].rx_gain_offset[i], @@ -1313,12 +1301,12 @@ extern "C" { LOG_I(HW,"rx_max_num_samps %zu\n", s->usrp->get_rx_stream(stream_args_rx)->get_max_num_samps()); - + for (int i = 0; i<openair0_cfg[0].rx_num_channels; i++) { LOG_I(HW,"setting rx channel %d\n",i); stream_args_rx.channels.push_back(i); } - + s->rx_stream = s->usrp->get_rx_stream(stream_args_rx); uhd::stream_args_t stream_args_tx("sc16", "sc16"); diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c index 3bd4285cffc12f59d8190ccad89d7abf6d26bdc3..354709faa1c3fe87c3f9834bc3ae56ce05722c2a 100644 --- a/targets/ARCH/rfsimulator/simulator.c +++ b/targets/ARCH/rfsimulator/simulator.c @@ -618,8 +618,8 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi } static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, void **samplesVoid, int nsamps, int nbAnt) { - if (nbAnt != 1) { - LOG_W(HW, "rfsimulator: only 1 antenna tested\n"); + if (nbAnt > 4) { + LOG_W(HW, "rfsimulator: only 4 antenna tested\n"); } rfsimulator_state_t *t = device->priv; @@ -736,14 +736,19 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest CirSize ); else { // no channel modeling + double H_awgn_mimo[4][4] ={{1.0, 0.5, 0.25, 0.125},//rx 0 + {0.5, 1.0, 0.5, 0.25}, //rx 1 + {0.25, 0.5, 1.0, 0.5}, //rx 2 + {0.125, 0.25, 0.5, 1.0}};//rx 3 + sample_t *out=(sample_t *)samplesVoid[a]; int nbAnt_tx = ptr->th.nbAnt;//number of Tx antennas //LOG_I(HW, "nbAnt_tx %d\n",nbAnt_tx); for (int i=0; i < nsamps; i++) {//loop over nsamps for (int a_tx=0; a_tx<nbAnt_tx; a_tx++) { //sum up signals from nbAnt_tx antennas - out[i].r+=ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].r; - out[i].i+=ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].i; + out[i].r += (short)(ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].r*H_awgn_mimo[a][a_tx]); + out[i].i += (short)(ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].i*H_awgn_mimo[a][a_tx]); } // end for a_tx } // end for i (number of samps) } // end of no channel modeling diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf index 00c92d75a224f124aa43268f6701cbb49cd3f5b8..ac1f36c8b753bafe14321adc0ceeec865f851f3d 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf @@ -1,4 +1,4 @@ -Active_gNBs = ( "gNB-Eurecom-DU"); +Active_gNBs = ( "gNB-Eurecom-5GNRBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -7,7 +7,7 @@ gNBs = { ////////// Identification parameters: gNB_ID = 0xe00; - gNB_name = "gNB-Eurecom-DU"; + gNB_name = "gNB-Eurecom-5GNRBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = 1; @@ -142,7 +142,7 @@ gNBs = initialULBWPk2_1 = 6; # used for mixed slot initialULBWPmappingType_1 = 1; - initialULBWPstartSymbolAndLength_1 = 69; # this is SS=0 L=12 + initialULBWPstartSymbolAndLength_1 = 52; # this is SS=10 L=4 initialULBWPk2_2 = 7; # used for Msg.3 during RA initialULBWPmappingType_2 = 1; @@ -225,11 +225,12 @@ gNBs = ); MACRLCs = ( - { - num_cc = 1; - tr_s_preference = "local_L1"; - tr_n_preference = "local_RRC"; - } + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + ulsch_max_slots_inactivity = 100; + } ); L1s = ( diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf index bd0678e344c5e37d7fb9ed4a711ff053af8c0bff..1bada161a1b26b3644b4ca414877604e420da50c 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf @@ -1,4 +1,4 @@ -Active_gNBs = ( "gNB-Eurecom-DU"); +Active_gNBs = ( "gNB-Eurecom-5GNRBox"); # Asn1_verbosity, choice in: none, info, annoying Asn1_verbosity = "none"; @@ -7,7 +7,7 @@ gNBs = { ////////// Identification parameters: gNB_ID = 0xe00; - gNB_name = "gNB-Eurecom-DU"; + gNB_name = "gNB-Eurecom-5GNRBox"; // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = 1; @@ -142,7 +142,7 @@ gNBs = initialULBWPk2_1 = 6; # used for mixed slot initialULBWPmappingType_1 = 1; - initialULBWPstartSymbolAndLength_1 = 69; # this is SS=0 L=12 + initialULBWPstartSymbolAndLength_1 = 52; # this is SS=10 L=4 initialULBWPk2_2 = 7; # used for Msg.3 during RA initialULBWPmappingType_2 = 1; @@ -225,11 +225,12 @@ gNBs = ); MACRLCs = ( - { - num_cc = 1; - tr_s_preference = "local_L1"; - tr_n_preference = "local_RRC"; - } + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + ulsch_max_slots_inactivity = 100; + } ); L1s = ( diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.sabox.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.sabox.conf new file mode 100644 index 0000000000000000000000000000000000000000..9402e354fe8741bdbd02b303b77bb9a465fbf8a9 --- /dev/null +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.sabox.conf @@ -0,0 +1,326 @@ +Active_gNBs = ( "gNB-Eurecom-5GNRBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + + cell_type = "CELL_MACRO_GNB"; + gNB_name = "gNB-Eurecom-5GNRBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ({ + mcc = 450; + mnc = 05; + mnc_length = 2; + snssaiList = ( + { + sst = 1; + sd = 0xd143a5; // 0 false, else true + } + ); + + }); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + ssb_SubcarrierOffset = 0; + pdsch_AntennaPorts = 1; + pusch_AntennaPorts = 1; + + pdcch_ConfigSIB1 = ( + { + controlResourceSetZero = 12; + searchSpaceZero = 0; + } + ); + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 641280; + dl_frequencyBand = 78; + # this is 3600 MHz + dl_absoluteFrequencyPointA = 640008; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 106; + #initialDownlinkBWP + #genericParameters + # this is RBstart=27,L=48 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 12952; # 6366 12925 12956 28875 12952 +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; + #pdsch-ConfigCommon + #pdschTimeDomainAllocationList (up to 16 entries) + initialDLBWPk0_0 = 0; + #initialULBWPmappingType + #0=typeA,1=typeB + initialDLBWPmappingType_0 = 0; + #this is SS=1,L=13 + initialDLBWPstartSymbolAndLength_0 = 40; + + initialDLBWPk0_1 = 0; + initialDLBWPmappingType_1 = 0; + #this is SS=2,L=12 + initialDLBWPstartSymbolAndLength_1 = 53; + + initialDLBWPk0_2 = 0; + initialDLBWPmappingType_2 = 0; + #this is SS=1,L=12 + initialDLBWPstartSymbolAndLength_2 = 54; + + initialDLBWPk0_3 = 0; + initialDLBWPmappingType_3 = 0; + #this is SS=1,L=5 + initialDLBWPstartSymbolAndLength_3 = 57; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 106; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 12952; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -96; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + + # pusch-ConfigCommon (up to 16 elements) + initialULBWPk2_0 = 6; + initialULBWPmappingType_0 = 1 + # this is SS=0 L=11 + initialULBWPstartSymbolAndLength_0 = 55; + + initialULBWPk2_1 = 6; + initialULBWPmappingType_1 = 1; + # this is SS=0 L=12 + initialULBWPstartSymbolAndLength_1 = 69; + + initialULBWPk2_2 = 7; + initialULBWPmappingType_2 = 1; + # this is SS=10 L=4 + initialULBWPstartSymbolAndLength_2 = 52; + + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; +# ssb_PositionsInBurs_BitmapPR +# 1=short, 2=medium, 3=long + ssb_PositionsInBurst_PR = 2; + ssb_PositionsInBurst_Bitmap = 1; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 1; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = -25; + } + + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + amf_ip_address = ( { ipv4 = "192.168.5.233"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + ///X2 + 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_FR1_CTL_ENB_IP_ADDR"; + ipv6 = "192:168:30::17"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + GNB_INTERFACE_NAME_FOR_NG_AMF = "eth0"; + GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.5.200/24"; + GNB_INTERFACE_NAME_FOR_NGU = "eth0"; + GNB_IPV4_ADDRESS_FOR_NGU = "192.168.5.200/24"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + GNB_IPV4_ADDRESS_FOR_X2C = "192.168.5.200/24"; + GNB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + pusch_proc_threads = 8; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 114; + eNB_instances = [0]; + #beamforming 1x4 matrix: + bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; + clock_src = "internal"; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_SINGLE_THREAD"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + +rfsimulator : +{ + serveraddr = "server"; + serverport = "4043"; + options = (); #("saviq"); or/and "chanmod" + modelname = "AWGN"; + IQfile = "/tmp/rfsimulator.iqs"; +}; + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + ngap_log_level ="debug"; + ngap_log_verbosity ="medium"; + }; +