From f5df7e17b0a0282f93f6f58371e8900019bc6048 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Tue, 15 Apr 2025 15:38:13 +0200 Subject: [PATCH 01/17] Add NAS Authentication Failure enc/dec lib and unit tests --- .../NAS/NR_UE/5GS/5GMM/MSG/CMakeLists.txt | 1 + .../5GMM/MSG/fgmm_authentication_failure.c | 101 ++++++++++++++++++ .../5GMM/MSG/fgmm_authentication_failure.h | 41 +++++++ openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_lib.c | 25 +++++ openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_lib.h | 2 + openair3/NAS/NR_UE/5GS/CMakeLists.txt | 1 + openair3/NAS/NR_UE/5GS/tests/nas_lib_test.c | 37 +++++++ openair3/NAS/NR_UE/CMakeLists.txt | 1 + 8 files changed, 209 insertions(+) create mode 100644 openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_authentication_failure.c create mode 100644 openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_authentication_failure.h diff --git a/openair3/NAS/NR_UE/5GS/5GMM/MSG/CMakeLists.txt b/openair3/NAS/NR_UE/5GS/5GMM/MSG/CMakeLists.txt index c1a28a18f3..3b51ec748c 100644 --- a/openair3/NAS/NR_UE/5GS/5GMM/MSG/CMakeLists.txt +++ b/openair3/NAS/NR_UE/5GS/5GMM/MSG/CMakeLists.txt @@ -11,6 +11,7 @@ add_library(fgs_5gmm_lib OBJECT RegistrationComplete.c FGSUplinkNasTransport.c FGSDeregistrationRequestUEOriginating.c + fgmm_authentication_failure.c ) target_link_libraries(fgs_5gmm_lib PUBLIC fgs_5gmm_ies_lib) diff --git a/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_authentication_failure.c b/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_authentication_failure.c new file mode 100644 index 0000000000..2dc865ab4c --- /dev/null +++ b/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_authentication_failure.c @@ -0,0 +1,101 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "fgmm_authentication_failure.h" +#include +#include // For htons and ntohs +#include // For malloc and free +#include "fgmm_lib.h" +#include "common/utils/ds/byte_array.h" +#include "common/utils/utils.h" + +#define MIN_AUTH_FAILURE_LEN 1 +#define AUTH_FAILURE_PARAM_LEN 16 +#define AUTH_FAIL_PARAM_IEI 0x30 + +/** @brief Encode Authentication Failure (8.2.4 of 3GPP TS 24.501) */ +int encode_fgmm_auth_failure(byte_array_t *buffer, const fgmm_auth_failure_t *msg) +{ + if (buffer->len < MIN_AUTH_FAILURE_LEN) { + PRINT_NAS_ERROR("Missing mandatory IE in Authentication Failure"); + return -1; // missing mandatory IE + } + // 5GMM cause (Mandatory) + int encoded = encode_fgs_nas_cause(buffer, &msg->cause); + // Authentication failure parameter (see 8.2.4.2 3GPP TS 24.501) + if (msg->cause == Synch_failure) { + // Authentication failure parameter shall be present with cause Synch Failure + if (msg->authentication_failure_param.len == 0) { + PRINT_NAS_ERROR("Authentication Failure Cause is synch failure but Authentication Failure Parameter is not available"); + return -1; + } + if (buffer->len - encoded < msg->authentication_failure_param.len + 2) { + PRINT_NAS_ERROR("Invalid buffer for encoding of Authentication Failure Parameter"); + return -1; + } + // Encode the IEI + buffer->buf[encoded++] = AUTH_FAIL_PARAM_IEI; + buffer->buf[encoded++] = msg->authentication_failure_param.len; + for (int i = 0; i < msg->authentication_failure_param.len; i++) { + buffer->buf[encoded++] = msg->authentication_failure_param.buf[i]; + } + } + return encoded; +} + +/** @brief Decode Authentication Failure (8.2.4 of 3GPP TS 24.501) */ +int decode_fgmm_auth_failure(fgmm_auth_failure_t *msg, const byte_array_t *buffer) +{ + if (buffer->len < MIN_AUTH_FAILURE_LEN) { + return -1; // missing mandatory IE + } + byte_array_t ba = *buffer; // Local copy of buffer + // 5GMM Cause (Mandatory) + uint32_t decoded = decode_fgs_nas_cause(&msg->cause, buffer); + // Authentication Failure Parameters (Optional) + if (msg->cause == Synch_failure) { + uint8_t iei = buffer->buf[decoded++]; + if (iei == AUTH_FAIL_PARAM_IEI) { + msg->authentication_failure_param.len = ba.buf[decoded++]; + if (msg->authentication_failure_param.len > AUTH_FAILURE_PARAM_LEN - 2) { // maximum length of contents is 14 octets + PRINT_NAS_ERROR("Length of Authentication Failure Parameter contents is too large"); + return -1; + } + msg->authentication_failure_param.buf = malloc_or_fail(msg->authentication_failure_param.len); + for (int i = 0; i < msg->authentication_failure_param.len; i++) { + msg->authentication_failure_param.buf[i] = buffer->buf[decoded++]; + } + } + } + return decoded; +} + +bool eq_fgmm_auth_failure(const fgmm_auth_failure_t *a, const fgmm_auth_failure_t *b) +{ + _NAS_EQ_CHECK_INT(a->cause, b->cause); + eq_byte_array(&a->authentication_failure_param, &b->authentication_failure_param); + return true; +} + +void free_fgmm_auth_failure(const fgmm_auth_failure_t *msg) +{ + free(msg->authentication_failure_param.buf); +} \ No newline at end of file diff --git a/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_authentication_failure.h b/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_authentication_failure.h new file mode 100644 index 0000000000..71d047b656 --- /dev/null +++ b/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_authentication_failure.h @@ -0,0 +1,41 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef FGMM_AUTH_FAILURE_H +#define FGMM_AUTH_FAILURE_H + +#include +#include "fgmm_lib.h" +#include "common/utils/ds/byte_array.h" + +typedef struct { + // 5GMM cause (Mandatory) + cause_id_t cause; + // Authentication failure parameter (Optional) + byte_array_t authentication_failure_param; +} fgmm_auth_failure_t; + +int decode_fgmm_auth_failure(fgmm_auth_failure_t *msg, const byte_array_t *buffer); +int encode_fgmm_auth_failure(byte_array_t *buffer, const fgmm_auth_failure_t *msg); +bool eq_fgmm_auth_failure(const fgmm_auth_failure_t *a, const fgmm_auth_failure_t *b); +void free_fgmm_auth_failure(const fgmm_auth_failure_t *msg); + +#endif /* FGMM_AUTH_FAILURE_H */ diff --git a/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_lib.c b/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_lib.c index 323cffe7e7..1b607589d9 100644 --- a/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_lib.c +++ b/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_lib.c @@ -26,6 +26,7 @@ #include "common/utils/ds/byte_array.h" #define GPRS_TIMER_LENGTH 3 // octets +#define FGS_NAS_CAUSE_LENGTH 1 /** * Encode PDU Session Status and PDU session reactivation result (optional IEs) @@ -158,3 +159,27 @@ int decode_eap_msg_ie(const byte_array_t *buffer) PRINT_NAS_ERROR("EAP message IE in NAS Service Reject is not handled\n"); return eap_msg_len + 2; // content length + 2 octets for the length IE } + +int encode_fgs_nas_cause(byte_array_t *buffer, const cause_id_t *cause) +{ + uint32_t encoded = 0; + + if (buffer->len < FGS_NAS_CAUSE_LENGTH) + return -1; + + buffer->buf[encoded++] = *cause; + + return encoded; +} + +int decode_fgs_nas_cause(cause_id_t *cause, const byte_array_t *buffer) +{ + int decoded = 0; + + if (buffer->len < FGS_NAS_CAUSE_LENGTH) + return -1; // nothing to decode + + *cause = buffer->buf[decoded++]; + + return decoded; +} diff --git a/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_lib.h b/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_lib.h index b757620506..25118f2742 100644 --- a/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_lib.h +++ b/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_lib.h @@ -165,5 +165,7 @@ int encode_gprs_timer_ie(byte_array_t *buffer, nas_service_IEI_t iei, const gprs int decode_gprs_timer_ie(gprs_timer_t *timer, const byte_array_t *buffer); bool eq_gprs_timer(const gprs_timer_t *a, const gprs_timer_t *b); int decode_eap_msg_ie(const byte_array_t *buffer); +int encode_fgs_nas_cause(byte_array_t *buffer, const cause_id_t *cause); +int decode_fgs_nas_cause(cause_id_t *cause, const byte_array_t *buffer); #endif /* FGS_LIB_H */ \ No newline at end of file diff --git a/openair3/NAS/NR_UE/5GS/CMakeLists.txt b/openair3/NAS/NR_UE/5GS/CMakeLists.txt index e04abb02db..9a7feabb72 100644 --- a/openair3/NAS/NR_UE/5GS/CMakeLists.txt +++ b/openair3/NAS/NR_UE/5GS/CMakeLists.txt @@ -12,6 +12,7 @@ target_link_libraries(fgs_lib PUBLIC fgs_5gsm_lib fgs_5gmm_ies_lib nas_common_ies_lib + ds ) target_include_directories(fgs_lib PUBLIC . 5GMM/MSG 5GMM/IES) diff --git a/openair3/NAS/NR_UE/5GS/tests/nas_lib_test.c b/openair3/NAS/NR_UE/5GS/tests/nas_lib_test.c index a73ee9b2be..faea1c8df0 100644 --- a/openair3/NAS/NR_UE/5GS/tests/nas_lib_test.c +++ b/openair3/NAS/NR_UE/5GS/tests/nas_lib_test.c @@ -6,6 +6,7 @@ #include "fgs_service_request.h" #include "fgmm_service_accept.h" #include "fgmm_service_reject.h" +#include "fgmm_authentication_failure.h" #include "nr_nas_msg.h" void exit_function(const char *file, const char *function, const int line, const char *s, const int assert) @@ -170,10 +171,46 @@ static void test_service_reject(void) free_fgs_service_reject(&orig); } +/** @brief Test NAS Authentication Failure enc/dec */ +static void test_auth_failure(void) +{ + // Dummy NAS Authentication Failure message + uint8_t afp[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06}; + const fgmm_auth_failure_t orig = { + .cause = Synch_failure, + .authentication_failure_param.len = 6, + .authentication_failure_param.buf = afp, + }; + + // Expected encoded data + uint8_t expected_enc[] = {0x15, 0x30, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06}; + + // Buffer + uint8_t buf[16] = {0}; + byte_array_t buffer = {.buf = buf, .len = sizeof(buf)}; + + // Encode + int encoded_length = encode_fgmm_auth_failure(&buffer, &orig); + AssertFatal(encoded_length == sizeofArray(expected_enc), "encode_fgmm_auth_failure() failed\n"); + + // Compare the raw encoded buffer with expected encoded data + AssertFatal(memcmp(buffer.buf, expected_enc, encoded_length) == 0, "Encoding mismatch!\n"); + + // Decode + fgmm_auth_failure_t dec = {0}; + int decoded_length = decode_fgmm_auth_failure(&dec, &buffer); + AssertFatal(decoded_length >= 0, "decode_fgmm_auth_failure() failed\n"); + + // Compare original and decoded messages + AssertFatal(eq_fgmm_auth_failure(&orig, &dec), "test_auth_failure() failed: original and decoded messages do not match\n"); + free_fgmm_auth_failure(&dec); +} + int main() { test_service_request(); test_service_accept(); test_service_reject(); + test_auth_failure(); return 0; } diff --git a/openair3/NAS/NR_UE/CMakeLists.txt b/openair3/NAS/NR_UE/CMakeLists.txt index 5e7d5da428..ec391092e5 100644 --- a/openair3/NAS/NR_UE/CMakeLists.txt +++ b/openair3/NAS/NR_UE/CMakeLists.txt @@ -10,6 +10,7 @@ target_link_libraries(nr_nas PUBLIC fgs_5gmm_ies_lib nas_common_ies_lib nas_utils + ds ) target_include_directories(nr_nas PUBLIC . 5GS/) From 9b4245d92193249e39358b8415a6c05ce005108f Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Tue, 15 Apr 2025 15:39:28 +0200 Subject: [PATCH 02/17] Add generation function and handler for NAS Authentication Failure --- openair3/NAS/NR_UE/5GS/NR_NAS_defs.h | 2 ++ openair3/NAS/NR_UE/5GS/fgs_nas_lib.c | 5 +++++ openair3/NAS/NR_UE/nr_nas_msg.c | 18 ++++++++++++++++++ 3 files changed, 25 insertions(+) diff --git a/openair3/NAS/NR_UE/5GS/NR_NAS_defs.h b/openair3/NAS/NR_UE/5GS/NR_NAS_defs.h index 94e7f38a57..ab94925f09 100644 --- a/openair3/NAS/NR_UE/5GS/NR_NAS_defs.h +++ b/openair3/NAS/NR_UE/5GS/NR_NAS_defs.h @@ -35,6 +35,7 @@ #include "RegistrationComplete.h" #include "RegistrationRequest.h" #include "fgs_service_request.h" +#include "fgmm_authentication_failure.h" /* Message types defintions for: (a) 5GS Mobility Management (5GMM) (IDs 0x41 - 0x68) @@ -222,6 +223,7 @@ typedef struct { fgs_service_request_msg_t service_request; fgmm_identity_response_msg fgs_identity_response; fgs_authentication_response_msg fgs_auth_response; + fgmm_auth_failure_t fgmm_auth_failure; fgs_deregistration_request_ue_originating_msg fgs_deregistration_request_ue_originating; fgs_security_mode_complete_msg fgs_security_mode_complete; registration_complete_msg registration_complete; diff --git a/openair3/NAS/NR_UE/5GS/fgs_nas_lib.c b/openair3/NAS/NR_UE/5GS/fgs_nas_lib.c index 16d84f3ad8..ca40131af6 100644 --- a/openair3/NAS/NR_UE/5GS/fgs_nas_lib.c +++ b/openair3/NAS/NR_UE/5GS/fgs_nas_lib.c @@ -73,6 +73,11 @@ int mm_msg_encode(const fgmm_nas_message_plain_t *p, uint8_t *buffer, uint32_t l case FGS_AUTHENTICATION_RESPONSE: enc_msg = encode_fgs_authentication_response(&p->mm_msg.fgs_auth_response, buffer, len); break; + case FGS_AUTHENTICATION_FAILURE: { + byte_array_t ba = {.buf = buffer, .len = len}; + enc_msg = encode_fgmm_auth_failure(&ba, &p->mm_msg.fgmm_auth_failure); + break; + } case FGS_SECURITY_MODE_COMPLETE: enc_msg = encode_fgs_security_mode_complete(&p->mm_msg.fgs_security_mode_complete, buffer, len); break; diff --git a/openair3/NAS/NR_UE/nr_nas_msg.c b/openair3/NAS/NR_UE/nr_nas_msg.c index 941e0d7cdc..3640c40aaa 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg.c +++ b/openair3/NAS/NR_UE/nr_nas_msg.c @@ -838,6 +838,24 @@ static void generateAuthenticationResp(nr_ue_nas_t *nas, as_nas_info_t *initialN free(res.value); } +/** @brief Send Authentication Failure message from the UE to the AMF to + * indicate that authentication of the network has failed */ +static void generateAuthenticationFailure(nr_ue_nas_t *nas, as_nas_info_t *initialNasMsg, cause_id_t cause) +{ + int size = sizeof(fgmm_msg_header_t); + fgmm_nas_message_plain_t plain = {0}; + + // Plain 5GMM header + plain.header = set_mm_header(FGS_AUTHENTICATION_FAILURE, PLAIN_5GS_MSG); + size += sizeof(plain.header); + // 5GMM Cause (Mandatory) + fgmm_auth_failure_t *mm_msg = &plain.mm_msg.fgmm_auth_failure; + mm_msg->cause = cause; + size += 1; + initialNasMsg->nas_data = malloc_or_fail(size * sizeof(*initialNasMsg->nas_data)); + initialNasMsg->length = mm_msg_encode(&plain, initialNasMsg->nas_data, size); +} + int nas_itti_kgnb_refresh_req(instance_t instance, const uint8_t kgnb[32]) { MessageDef *message_p; From f41c572aff4904a8700ddc562868b78d22894110 Mon Sep 17 00:00:00 2001 From: francescomani Date: Mon, 28 Apr 2025 18:09:59 +0200 Subject: [PATCH 03/17] fix for UE reception of PDCCH not starting from symbol 0 --- openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c | 3 +-- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 9 ++++----- 2 files changed, 5 insertions(+), 7 deletions(-) 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 d405e86263..0e186a3bc3 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -826,8 +826,7 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, unsigned short coreset_start_subcarrier = first_carrier_offset+(BWPStart + coreset_start_rb)*12; #ifdef DEBUG_PDCCH - printf("PDCCH Channel Estimation : gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, slot=%d, symbol %d\n", - gNB_id, + printf("PDCCH Channel Estimation : ch_offset %d, OFDM size %d, Ncp=%d, slot=%d, symbol %d\n", ch_offset, ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp, diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 5345d010f4..e52b5bed2e 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -977,7 +977,9 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH, VCD_FUNCTION_IN); uint8_t nb_symb_pdcch = phy_pdcch_config->nb_search_space > 0 ? phy_pdcch_config->pdcch_config[0].coreset.duration : 0; - for (uint16_t l=0; lnb_search_space > 0 ? phy_pdcch_config->pdcch_config[0].coreset.StartSymbolIndex : 0; + int last_symb_pdcch = first_symb_pdcch + nb_symb_pdcch; + for (int l = first_symb_pdcch; l < last_symb_pdcch; l++) { nr_slot_fep(ue, fp, proc->nr_slot_rx, l, rxdataF, link_type_dl, 0, ue->common_vars.rxdata); } @@ -987,10 +989,8 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_ uint8_t dci_cnt = 0; for(int n_ss = 0; n_ssnb_search_space; n_ss++) { - for (uint16_t l=0; l Date: Mon, 28 Apr 2025 18:29:25 +0200 Subject: [PATCH 04/17] scheduling pdcch structure in SIB1 depends on the associated SSB, can't be precomputed start symbol may depend on the associated SSB index --- openair2/LAYER2/NR_MAC_gNB/config.c | 2 -- .../LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c | 25 ++++++++++++------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index e22ad1fcdb..aacae2bea1 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -810,8 +810,6 @@ static void config_sched_ctrlCommon(gNB_MAC_INST *nr_mac) fill_coresetZero(sched_ctrlCommon->coreset, &type0_PDCCH_CSS_config); nr_mac->cset0_bwp_start = type0_PDCCH_CSS_config.cset_start_rb; nr_mac->cset0_bwp_size = type0_PDCCH_CSS_config.num_rbs; - sched_ctrlCommon->sched_pdcch = - set_pdcch_structure(NULL, sched_ctrlCommon->search_space, sched_ctrlCommon->coreset, scc, NULL, &type0_PDCCH_CSS_config); } void nr_mac_config_scc(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, const nr_mac_config_t *config) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 5213854a16..bb8aea43fe 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -344,6 +344,7 @@ static uint32_t get_tbs_bch(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config, static uint32_t schedule_control_sib1(gNB_MAC_INST *gNB_mac, int CC_id, + NR_sched_pdcch_t *pdcch, NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config, int time_domain_allocation, NR_pdsch_dmrs_t *dmrs_parms, @@ -374,7 +375,7 @@ static uint32_t schedule_control_sib1(gNB_MAC_INST *gNB_mac, gNB_mac->sched_ctrlCommon->aggregation_level, nr_of_candidates, beam, - &gNB_mac->sched_ctrlCommon->sched_pdcch, + pdcch, gNB_mac->sched_ctrlCommon->coreset, 0); @@ -388,7 +389,7 @@ static uint32_t schedule_control_sib1(gNB_MAC_INST *gNB_mac, // Mark the corresponding RBs as used fill_pdcch_vrb_map(gNB_mac, CC_id, - &gNB_mac->sched_ctrlCommon->sched_pdcch, + pdcch, gNB_mac->sched_ctrlCommon->cce_index, gNB_mac->sched_ctrlCommon->aggregation_level, beam); @@ -615,20 +616,26 @@ void schedule_nr_sib1(module_id_t module_idP, default_table_type_t table_type = get_default_table_type(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern); // assuming normal CP - NR_tda_info_t tda_info = get_info_from_tda_tables(table_type, time_domain_allocation, gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, true); + NR_tda_info_t tda_info = get_info_from_tda_tables(table_type, time_domain_allocation, scc->dmrs_TypeA_Position, true); - AssertFatal((tda_info.startSymbolIndex + tda_info.nrOfSymbols) < 14, "SIB1 TDA %d would cause overlap with CSI-RS. Please select a different SIB1 TDA.\n", time_domain_allocation); + AssertFatal((tda_info.startSymbolIndex + tda_info.nrOfSymbols) < 14, + "SIB1 TDA %d would cause overlap with CSI-RS. Please select a different SIB1 TDA.\n", + time_domain_allocation); - NR_pdsch_dmrs_t dmrs_parms = get_dl_dmrs_params(scc, - NULL, - &tda_info, - 1); + NR_pdsch_dmrs_t dmrs_parms = get_dl_dmrs_params(scc, NULL, &tda_info, 1); + NR_sched_pdcch_t sched_pdcch = set_pdcch_structure(NULL, + gNB_mac->sched_ctrlCommon->search_space, + gNB_mac->sched_ctrlCommon->coreset, + scc, + NULL, + type0_PDCCH_CSS_config); NR_COMMON_channels_t *cc = &gNB_mac->common_channels[0]; // Configure sched_ctrlCommon for SIB1 uint32_t TBS = schedule_control_sib1(gNB_mac, CC_id, + &sched_pdcch, type0_PDCCH_CSS_config, time_domain_allocation, &dmrs_parms, @@ -641,7 +648,7 @@ void schedule_nr_sib1(module_id_t module_idP, int pdu_index = gNB_mac->pdu_index[0]++; nr_fill_nfapi_dl_SIB_pdu(gNB_mac, &gNB_mac->sched_ctrlCommon->sched_pdsch, - &gNB_mac->sched_ctrlCommon->sched_pdcch, + &sched_pdcch, gNB_mac->sched_ctrlCommon->search_space, gNB_mac->sched_ctrlCommon->coreset, gNB_mac->sched_ctrlCommon->aggregation_level, From b6b43328095b638c5d6cdab30161c5dda0506016 Mon Sep 17 00:00:00 2001 From: francescomani Date: Tue, 6 May 2025 08:45:35 +0200 Subject: [PATCH 05/17] PRACH configuration index assertion to avoid PRACH in last symbol --- openair2/GNB_APP/gnb_config.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 281bda44ef..c673293e92 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -504,7 +504,8 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc, uint64_t ssbmap) } // fix SS0 and Coreset0 - NR_PDCCH_ConfigCommon_t *pdcch_cc = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup; + NR_DownlinkConfigCommon_t *dlcc = scc->downlinkConfigCommon; + NR_PDCCH_ConfigCommon_t *pdcch_cc = dlcc->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup; if((int)*pdcch_cc->searchSpaceZero == -1) { free(pdcch_cc->searchSpaceZero); pdcch_cc->searchSpaceZero = NULL; @@ -520,18 +521,26 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc, uint64_t ssbmap) scc->uplinkConfigCommon->frequencyInfoUL->absoluteFrequencyPointA = NULL; } + NR_RACH_ConfigCommon_t *rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; + long config_index = rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex; + frequency_range_t freq_range = get_freq_range_from_arfcn(dlcc->frequencyInfoDL->absoluteFrequencyPointA); + frame_type_t frame_type = get_frame_type((int)*dlcc->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing); + nr_prach_info_t prach_info = get_nr_prach_occasion_info_from_index(config_index, freq_range, frame_type); + AssertFatal(prach_info.start_symbol + prach_info.N_t_slot * prach_info.N_dur < 14, + "PRACH with configuration index %ld goes to the last symbol of the slot, for optimal performance pick another index. " + "See Tables 6.3.3.2-2 to 6.3.3.2-4 in 38.211\n", + config_index); // default value for msg3 precoder is NULL (0 means enabled) - if (*scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder!=0) { - free(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder); - scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder = NULL; + if (*rach_ConfigCommon->msg3_transformPrecoder != 0) { + free(rach_ConfigCommon->msg3_transformPrecoder); + rach_ConfigCommon->msg3_transformPrecoder = NULL; } - frame_type_t frame_type = get_frame_type((int)*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing); - // prepare DL Allocation lists - nr_rrc_config_dl_tda(scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList, - frame_type, scc->tdd_UL_DL_ConfigurationCommon, - scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); + nr_rrc_config_dl_tda(dlcc->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList, + frame_type, + scc->tdd_UL_DL_ConfigurationCommon, + dlcc->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth); if (frame_type == FDD) { ASN_STRUCT_FREE(asn_DEF_NR_TDD_UL_DL_ConfigCommon, scc->tdd_UL_DL_ConfigurationCommon); @@ -540,9 +549,9 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc, uint64_t ssbmap) fix_tdd_pattern(scc); } - if ((int)*scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing == -1) { - free(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing); - scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing=NULL; + if ((int)*rach_ConfigCommon->msg1_SubcarrierSpacing == -1) { + free(rach_ConfigCommon->msg1_SubcarrierSpacing); + rach_ConfigCommon->msg1_SubcarrierSpacing = NULL; } if (scc->uplinkConfigCommon->initialUplinkBWP->ext1 From f9b76dd2bf40710379b60bb9eb674b363e000ed2 Mon Sep 17 00:00:00 2001 From: francescomani Date: Wed, 7 May 2025 09:19:19 +0200 Subject: [PATCH 06/17] fix sim prach configuration index --- openair2/GNB_APP/gnb_config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index c673293e92..0f86ab31e1 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -379,7 +379,7 @@ void fill_scc_sim(NR_ServingCellConfigCommon_t *scc, uint64_t *ssb_bitmap, int N initialUplinkBWP->genericParameters.subcarrierSpacing = mu_ul; struct NR_SetupRelease_RACH_ConfigCommon *rach_ConfigCommon = initialUplinkBWP->rach_ConfigCommon; - rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex = 98; + rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex = mu_ul == 3 ? 52 : 98; rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM = NR_RACH_ConfigGeneric__msg1_FDM_one; rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart = 0; rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig = 13; From 51dfab0c56ce141b6d5c6489b8915cf1e1eb35ee Mon Sep 17 00:00:00 2001 From: rmagueta Date: Wed, 7 May 2025 15:55:36 +0100 Subject: [PATCH 07/17] Fix DMRS for PUCCH format 2 --- openair1/PHY/NR_TRANSPORT/pucch_rx.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index 79e39fa7c1..a66812b39e 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -930,12 +930,13 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, int l2 = pucch_pdu->start_symbol_index; int soffset = (slot % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size; + uint16_t starting_prb = pucch_pdu->prb_start + pucch_pdu->bwp_start; int re_offset[nb_symbols]; - re_offset[0] = - (12 * (pucch_pdu->prb_start + pucch_pdu->bwp_start) + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size; - if (nb_symbols==2) { - if (pucch_pdu->freq_hop_flag ) - re_offset[1] = (12*(pucch_pdu->second_hop_prb+pucch_pdu->bwp_start) + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size ; + re_offset[0] = (12 * starting_prb + frame_parms->first_carrier_offset) % frame_parms->ofdm_symbol_size; + if (nb_symbols == 2) { + if (pucch_pdu->freq_hop_flag) + re_offset[1] = (12 * (pucch_pdu->second_hop_prb + pucch_pdu->bwp_start) + frame_parms->first_carrier_offset) + % frame_parms->ofdm_symbol_size; else re_offset[1] = re_offset[0]; } @@ -1074,10 +1075,10 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, printf("slot %d, start_symbol_index %d, symbol %d, dmrs_scrambling_id %d\n", slot,pucch_pdu->start_symbol_index,symb,pucch_pdu->dmrs_scrambling_id); #endif - uint32_t *sGold = gold_cache(x2, pucch_pdu->prb_start / 4 + ngroup / 2); + uint32_t *sGold = gold_cache(x2, starting_prb / 4 + ngroup / 2); // Compute pilot conjugate c16_t pil_dmrs[nb_re_dmrs] __attribute__((aligned(32))); - uint8_t *sGold8 = (uint8_t *)(sGold + pucch_pdu->prb_start / 4); + uint8_t *sGold8 = (uint8_t *)(sGold + starting_prb / 4); for (int group = 0; group < nb_re_dmrs; group += 4) *(simde__m128i *)(pil_dmrs + group) = oai_mm_conj(byte2m128i[*sGold8++]); From 321df962d2e5535dfb53f6150115520735040924 Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 8 May 2025 15:05:13 +0200 Subject: [PATCH 08/17] make functions to create harq lists static --- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 110 +++++++++--------- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 4 - 2 files changed, 55 insertions(+), 59 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 7b9ad1ed3b..8d7e1674f9 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2208,6 +2208,61 @@ static void set_sched_pucch_list(NR_UE_sched_ctrl_t *sched_ctrl, } } +static void create_dl_harq_list(NR_UE_sched_ctrl_t *sched_ctrl, const NR_UE_ServingCell_Info_t *sc_info) +{ + const int nrofHARQ = get_nrofHARQ_ProcessesForPDSCH(sc_info); + // add all available DL HARQ processes for this UE + AssertFatal(sched_ctrl->available_dl_harq.len == sched_ctrl->feedback_dl_harq.len + && sched_ctrl->available_dl_harq.len == sched_ctrl->retrans_dl_harq.len, + "HARQ lists have different lengths (%d/%d/%d)\n", + sched_ctrl->available_dl_harq.len, + sched_ctrl->feedback_dl_harq.len, + sched_ctrl->retrans_dl_harq.len); + if (sched_ctrl->available_dl_harq.len == 0) { + create_nr_list(&sched_ctrl->available_dl_harq, nrofHARQ); + for (int harq = 0; harq < nrofHARQ; harq++) + add_tail_nr_list(&sched_ctrl->available_dl_harq, harq); + create_nr_list(&sched_ctrl->feedback_dl_harq, nrofHARQ); + create_nr_list(&sched_ctrl->retrans_dl_harq, nrofHARQ); + } else if (sched_ctrl->available_dl_harq.len == nrofHARQ) { + LOG_D(NR_MAC, "nrofHARQ %d already configured\n", nrofHARQ); + } else { + const int old_nrofHARQ = sched_ctrl->available_dl_harq.len; + AssertFatal(nrofHARQ > old_nrofHARQ, + "cannot resize HARQ list to be smaller (nrofHARQ %d, old_nrofHARQ %d)\n", + nrofHARQ, old_nrofHARQ); + resize_nr_list(&sched_ctrl->available_dl_harq, nrofHARQ); + for (int harq = old_nrofHARQ; harq < nrofHARQ; harq++) + add_tail_nr_list(&sched_ctrl->available_dl_harq, harq); + resize_nr_list(&sched_ctrl->feedback_dl_harq, nrofHARQ); + resize_nr_list(&sched_ctrl->retrans_dl_harq, nrofHARQ); + } +} + +static void create_ul_harq_list(NR_UE_sched_ctrl_t *sched_ctrl, const NR_UE_ServingCell_Info_t *sc_info) +{ + int nrofHARQ = get_nrofHARQ_ProcessesForPUSCH(sc_info); + if (sched_ctrl->available_ul_harq.len == 0) { + create_nr_list(&sched_ctrl->available_ul_harq, nrofHARQ); + for (int harq = 0; harq < nrofHARQ; harq++) + add_tail_nr_list(&sched_ctrl->available_ul_harq, harq); + create_nr_list(&sched_ctrl->feedback_ul_harq, nrofHARQ); + create_nr_list(&sched_ctrl->retrans_ul_harq, nrofHARQ); + } else if (sched_ctrl->available_ul_harq.len == nrofHARQ) { + LOG_D(NR_MAC, "nrofHARQ %d already configured\n", nrofHARQ); + } else { + const int old_nrofHARQ = sched_ctrl->available_ul_harq.len; + AssertFatal(nrofHARQ > old_nrofHARQ, + "cannot resize HARQ list to be smaller (nrofHARQ %d, old_nrofHARQ %d)\n", + nrofHARQ, old_nrofHARQ); + resize_nr_list(&sched_ctrl->available_ul_harq, nrofHARQ); + for (int harq = old_nrofHARQ; harq < nrofHARQ; harq++) + add_tail_nr_list(&sched_ctrl->available_ul_harq, harq); + resize_nr_list(&sched_ctrl->feedback_ul_harq, nrofHARQ); + resize_nr_list(&sched_ctrl->retrans_ul_harq, nrofHARQ); + } +} + // main function to configure parameters of current BWP void configure_UE_BWP(gNB_MAC_INST *nr_mac, NR_ServingCellConfigCommon_t *scc, @@ -2615,61 +2670,6 @@ void free_sched_pucch_list(NR_UE_sched_ctrl_t *sched_ctrl) free(sched_ctrl->sched_pucch); } -void create_dl_harq_list(NR_UE_sched_ctrl_t *sched_ctrl, const NR_UE_ServingCell_Info_t *sc_info) -{ - const int nrofHARQ = get_nrofHARQ_ProcessesForPDSCH(sc_info); - // add all available DL HARQ processes for this UE - AssertFatal(sched_ctrl->available_dl_harq.len == sched_ctrl->feedback_dl_harq.len - && sched_ctrl->available_dl_harq.len == sched_ctrl->retrans_dl_harq.len, - "HARQ lists have different lengths (%d/%d/%d)\n", - sched_ctrl->available_dl_harq.len, - sched_ctrl->feedback_dl_harq.len, - sched_ctrl->retrans_dl_harq.len); - if (sched_ctrl->available_dl_harq.len == 0) { - create_nr_list(&sched_ctrl->available_dl_harq, nrofHARQ); - for (int harq = 0; harq < nrofHARQ; harq++) - add_tail_nr_list(&sched_ctrl->available_dl_harq, harq); - create_nr_list(&sched_ctrl->feedback_dl_harq, nrofHARQ); - create_nr_list(&sched_ctrl->retrans_dl_harq, nrofHARQ); - } else if (sched_ctrl->available_dl_harq.len == nrofHARQ) { - LOG_D(NR_MAC, "nrofHARQ %d already configured\n", nrofHARQ); - } else { - const int old_nrofHARQ = sched_ctrl->available_dl_harq.len; - AssertFatal(nrofHARQ > old_nrofHARQ, - "cannot resize HARQ list to be smaller (nrofHARQ %d, old_nrofHARQ %d)\n", - nrofHARQ, old_nrofHARQ); - resize_nr_list(&sched_ctrl->available_dl_harq, nrofHARQ); - for (int harq = old_nrofHARQ; harq < nrofHARQ; harq++) - add_tail_nr_list(&sched_ctrl->available_dl_harq, harq); - resize_nr_list(&sched_ctrl->feedback_dl_harq, nrofHARQ); - resize_nr_list(&sched_ctrl->retrans_dl_harq, nrofHARQ); - } -} - -void create_ul_harq_list(NR_UE_sched_ctrl_t *sched_ctrl, const NR_UE_ServingCell_Info_t *sc_info) -{ - int nrofHARQ = get_nrofHARQ_ProcessesForPUSCH(sc_info); - if (sched_ctrl->available_ul_harq.len == 0) { - create_nr_list(&sched_ctrl->available_ul_harq, nrofHARQ); - for (int harq = 0; harq < nrofHARQ; harq++) - add_tail_nr_list(&sched_ctrl->available_ul_harq, harq); - create_nr_list(&sched_ctrl->feedback_ul_harq, nrofHARQ); - create_nr_list(&sched_ctrl->retrans_ul_harq, nrofHARQ); - } else if (sched_ctrl->available_ul_harq.len == nrofHARQ) { - LOG_D(NR_MAC, "nrofHARQ %d already configured\n", nrofHARQ); - } else { - const int old_nrofHARQ = sched_ctrl->available_ul_harq.len; - AssertFatal(nrofHARQ > old_nrofHARQ, - "cannot resize HARQ list to be smaller (nrofHARQ %d, old_nrofHARQ %d)\n", - nrofHARQ, old_nrofHARQ); - resize_nr_list(&sched_ctrl->available_ul_harq, nrofHARQ); - for (int harq = old_nrofHARQ; harq < nrofHARQ; harq++) - add_tail_nr_list(&sched_ctrl->available_ul_harq, harq); - resize_nr_list(&sched_ctrl->feedback_ul_harq, nrofHARQ); - resize_nr_list(&sched_ctrl->retrans_ul_harq, nrofHARQ); - } -} - void reset_dl_harq_list(NR_UE_sched_ctrl_t *sched_ctrl) { int harq; while ((harq = sched_ctrl->feedback_dl_harq.head) >= 0) { diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 3ac09ce98a..c78c061820 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -348,10 +348,6 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, const uint8_t ul_cqi, const uint16_t rssi); -void create_dl_harq_list(NR_UE_sched_ctrl_t *sched_ctrl, const NR_UE_ServingCell_Info_t *sc_info); - -void create_ul_harq_list(NR_UE_sched_ctrl_t *sched_ctrl, const NR_UE_ServingCell_Info_t *sc_info); - void reset_dl_harq_list(NR_UE_sched_ctrl_t *sched_ctrl); void reset_ul_harq_list(NR_UE_sched_ctrl_t *sched_ctrl); From 2f1dbed8ec479cff3ee18e18d057f3a0a664a649 Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 8 May 2025 15:26:24 +0200 Subject: [PATCH 09/17] limit the number of HARQ processes in lists for DCI 10 and 00 (also removed unnecessary call to create lists at UE init) --- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 8d7e1674f9..03ec701880 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2208,9 +2208,12 @@ static void set_sched_pucch_list(NR_UE_sched_ctrl_t *sched_ctrl, } } -static void create_dl_harq_list(NR_UE_sched_ctrl_t *sched_ctrl, const NR_UE_ServingCell_Info_t *sc_info) +static void create_dl_harq_list(NR_UE_sched_ctrl_t *sched_ctrl, const NR_UE_ServingCell_Info_t *sc_info, bool dci_00_10) { - const int nrofHARQ = get_nrofHARQ_ProcessesForPDSCH(sc_info); + int nrofHARQ = get_nrofHARQ_ProcessesForPDSCH(sc_info); + // limit the number of HARQ PIDs to 16 in case of common search space + if (dci_00_10 && nrofHARQ > 16) + nrofHARQ = 16; // add all available DL HARQ processes for this UE AssertFatal(sched_ctrl->available_dl_harq.len == sched_ctrl->feedback_dl_harq.len && sched_ctrl->available_dl_harq.len == sched_ctrl->retrans_dl_harq.len, @@ -2239,9 +2242,12 @@ static void create_dl_harq_list(NR_UE_sched_ctrl_t *sched_ctrl, const NR_UE_Serv } } -static void create_ul_harq_list(NR_UE_sched_ctrl_t *sched_ctrl, const NR_UE_ServingCell_Info_t *sc_info) +static void create_ul_harq_list(NR_UE_sched_ctrl_t *sched_ctrl, const NR_UE_ServingCell_Info_t *sc_info, bool dci_00_10) { int nrofHARQ = get_nrofHARQ_ProcessesForPUSCH(sc_info); + // limit the number of HARQ PIDs to 16 in case of common search space + if (dci_00_10 && nrofHARQ > 16) + nrofHARQ = 16; if (sched_ctrl->available_ul_harq.len == 0) { create_nr_list(&sched_ctrl->available_ul_harq, nrofHARQ); for (int harq = 0; harq < nrofHARQ; harq++) @@ -2452,8 +2458,6 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac, sc_info->nrofHARQ_ProcessesForPUSCH_r17 = pusch_servingcellconfig->ext3->nrofHARQ_ProcessesForPUSCH_r17; } } - create_dl_harq_list(sched_ctrl, sc_info); - create_ul_harq_list(sched_ctrl, sc_info); } if (CellGroup && CellGroup->physicalCellGroupConfig) @@ -2516,6 +2520,10 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac, DL_BWP->dci_format = NR_DL_DCI_FORMAT_1_0; } + bool format_00_10 = DL_BWP->dci_format == NR_DL_DCI_FORMAT_1_0; // if DL is 10 UL is surely 00 + create_dl_harq_list(sched_ctrl, sc_info, format_00_10); + create_ul_harq_list(sched_ctrl, sc_info, format_00_10); + set_max_fb_time(UL_BWP, DL_BWP); set_sched_pucch_list(sched_ctrl, UL_BWP, scc, &nr_mac->frame_structure); @@ -2577,11 +2585,6 @@ NR_UE_info_t *get_new_nr_ue_inst(uid_allocator_t *uia, rnti_t rnti, NR_CellGroup /* Set default BWPs */ AssertFatal(UE->sc_info.n_ul_bwp <= NR_MAX_NUM_BWP, "uplinkBWP_ToAddModList has %d BWP!\n", UE->sc_info.n_ul_bwp); - /* get Number of HARQ processes for this UE */ - // pdsch_servingcellconfig == NULL in SA -> will create default (8) number of HARQ processes - create_dl_harq_list(sched_ctrl, &UE->sc_info); - create_ul_harq_list(sched_ctrl, &UE->sc_info); - // initialize LCID structure seq_arr_init(&sched_ctrl->lc_config, sizeof(nr_lc_config_t)); return UE; From 7d8658f5ef9fbdf2bd0d914aefa9a419c3838612 Mon Sep 17 00:00:00 2001 From: Nick Hedberg Date: Mon, 27 Jan 2025 17:38:03 +0100 Subject: [PATCH 10/17] Correct ULSCH minimum RB condition Assume the minimum grant (min_rb) size to be the bandwidth part size. As an example: rbStart 0, min_rb=bwpSize=106. This should pass, hence modify these two conditions. Co-authored-by: Robert Schmidt --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 258f3c8c76..c554dc7cea 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -1968,7 +1968,7 @@ static void pf_ul(module_id_t module_id, const uint16_t slbitmap = SL_to_bitmap(sched_pusch->tda_info.startSymbolIndex, sched_pusch->tda_info.nrOfSymbols); while (rbStart < bwpSize && (rballoc_mask[rbStart + bwpStart] & slbitmap)) rbStart++; - if (rbStart + min_rb >= bwpSize) { + if (rbStart + min_rb > bwpSize) { LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate continuous UL data: no resources (rbStart %d, min_rb %d, bwpSize %d)\n", UE->rnti, @@ -2121,7 +2121,7 @@ static void pf_ul(module_id_t module_id, while (rbStart + max_rbSize < bwpSize && !(rballoc_mask[rbStart + bwpStart + max_rbSize] & slbitmap)) max_rbSize++; - if (rbStart + min_rb >= bwpSize || max_rbSize < min_rb) { + if (rbStart + min_rb > bwpSize || max_rbSize < min_rb) { reset_beam_status(&nrmac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame, dci_beam.new_beam); reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, iterator->UE->UE_beam_index, slots_per_frame, beam.new_beam); LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate UL data: no resources (rbStart %d, min_rb %d, bwpSize %d)\n", From d8b67af15619fae2becd0c00e6d737ca113a472f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 27 Jan 2025 17:39:31 +0100 Subject: [PATCH 11/17] Respect minimum grant condition for Msg3 --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index edddd535b0..a9d8b542a1 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -1047,7 +1047,7 @@ static bool nr_get_Msg3alloc(gNB_MAC_INST *mac, int CC_id, int current_slot, fra NR_RA_t *ra = UE->ra; DevAssert(ra->Msg3_tda_id >= 0 && ra->Msg3_tda_id < 16); - uint16_t msg3_nb_rb = 8; // sdu has 6 or 8 bytes + uint16_t msg3_nb_rb = max(8, mac->min_grant_prb); // sdu has 6 or 8 bytes NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; NR_UE_ServingCell_Info_t *sc_info = &UE->sc_info; From 34ee9ffd29dd981d48d72998ec4568b1bafe72cd Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 27 Jan 2025 17:39:53 +0100 Subject: [PATCH 12/17] Move log for Msg3 allocation done Move this message down, at the end of the function, if no code path exists under which msg3 allocation might fail despite this log having been printed. --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index a9d8b542a1..e1e9bfd982 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -1057,14 +1057,6 @@ static bool nr_get_Msg3alloc(gNB_MAC_INST *mac, int CC_id, int current_slot, fra int startSymbolAndLength = pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength; SLIV2SL(startSymbolAndLength, &ra->msg3_startsymb, &ra->msg3_nbSymb); - LOG_I(NR_MAC, - "UE %04x: Msg3 scheduled at %d.%d (%d.%d TDA %u)\n", - UE->rnti, - ra->Msg3_frame, - ra->Msg3_slot, - current_frame, - current_slot, - ra->Msg3_tda_id); const int buffer_index = ul_buffer_index(ra->Msg3_frame, ra->Msg3_slot, mac->frame_structure.numb_slots_frame, @@ -1099,6 +1091,16 @@ static bool nr_get_Msg3alloc(gNB_MAC_INST *mac, int CC_id, int current_slot, fra ra->msg3_nb_rb = msg3_nb_rb; ra->msg3_first_rb = rbStart; ra->msg3_bwp_start = bwpStart; + LOG_I(NR_MAC, + "UE %04x: Msg3 scheduled at %d.%d (%d.%d TDA %u) start %d RBs %d\n", + UE->rnti, + ra->Msg3_frame, + ra->Msg3_slot, + current_frame, + current_slot, + ra->Msg3_tda_id, + ra->msg3_first_rb, + ra->msg3_nb_rb); return true; } From d55bcecdc3363c35be0a7618061a97ea39efbedd Mon Sep 17 00:00:00 2001 From: Nick Hedberg Date: Mon, 27 Jan 2025 17:58:51 +0100 Subject: [PATCH 13/17] Use u16 for minimum grant option, could be 273PRBs --- openair2/GNB_APP/MACRLC_nr_paramdef.h | 2 +- openair2/GNB_APP/gnb_config.c | 2 +- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/openair2/GNB_APP/MACRLC_nr_paramdef.h b/openair2/GNB_APP/MACRLC_nr_paramdef.h index e4eaa52804..e682c559fa 100644 --- a/openair2/GNB_APP/MACRLC_nr_paramdef.h +++ b/openair2/GNB_APP/MACRLC_nr_paramdef.h @@ -135,7 +135,7 @@ {CONFIG_STRING_MACRLC_UL_MAX_MCS, HLP_MACRLC_UL_MAX_MCS, 0, .u8ptr=NULL, .defintval=28, TYPE_UINT8, 0}, \ {CONFIG_STRING_MACRLC_DL_HARQ_ROUND_MAX, HLP_MACRLC_DL_HARQ_MAX, 0, .u8ptr=NULL, .defintval=4, TYPE_UINT8, 0}, \ {CONFIG_STRING_MACRLC_UL_HARQ_ROUND_MAX, HLP_MACRLC_UL_HARQ_MAX, 0, .u8ptr=NULL, .defintval=4, TYPE_UINT8, 0}, \ - {CONFIG_STRING_MACRLC_MIN_GRANT_PRB, HLP_MACRLC_MIN_GRANT_PRB, 0, .u8ptr=NULL, .defintval=5, TYPE_UINT8, 0}, \ + {CONFIG_STRING_MACRLC_MIN_GRANT_PRB, HLP_MACRLC_MIN_GRANT_PRB, 0, .u16ptr=NULL, .defintval=5, TYPE_UINT16, 0}, \ {CONFIG_STRING_MACRLC_IDENTITY_PM, HLP_MACRLC_IDENTITY_PM, PARAMFLAG_BOOL, .u8ptr=NULL, .defintval=0, TYPE_UINT8, 0}, \ {CONFIG_STRING_MACRLC_LOCAL_N_ADDRESS_F1U, NULL, 0, .strptr=NULL, .defstrval=NULL, TYPE_STRING, 0}, \ {CONFIG_STRING_MACRLC_TRANSPORT_S_SHM_PREFIX, NULL, 0, .strptr=NULL, .defstrval="nvipc", TYPE_STRING, 0}, \ diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 281bda44ef..13a75451b8 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -1685,7 +1685,7 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg) ul_bler_options->harq_round_max = 1; else ul_bler_options->harq_round_max = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_HARQ_ROUND_MAX_IDX].u8ptr); - RC.nrmac[j]->min_grant_prb = *(MacRLC_ParamList.paramarray[j][MACRLC_MIN_GRANT_PRB_IDX].u8ptr); + RC.nrmac[j]->min_grant_prb = *(MacRLC_ParamList.paramarray[j][MACRLC_MIN_GRANT_PRB_IDX].u16ptr); RC.nrmac[j]->identity_pm = *(MacRLC_ParamList.paramarray[j][MACRLC_IDENTITY_PM_IDX].u8ptr); // PRB Blacklist uint16_t prbbl[MAX_BWP_SIZE] = {0}; diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 561f55339c..1e7ac572ef 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -908,7 +908,7 @@ typedef struct gNB_MAC_INST_s { bool first_MIB; NR_bler_options_t dl_bler; NR_bler_options_t ul_bler; - uint8_t min_grant_prb; + uint16_t min_grant_prb; bool identity_pm; int precoding_matrix_size[NR_MAX_NB_LAYERS]; int fapi_beam_index[MAX_NUM_OF_SSB]; From 44716febce5e24faeecd3b54178aa18f6038695e Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Thu, 21 Nov 2024 16:04:11 +0100 Subject: [PATCH 14/17] ue txData more contextual, but still global as it is entangled with usrp driver --- executables/nr-ue.c | 29 +++-- openair1/PHY/INIT/nr_parms.c | 2 +- openair1/PHY/NR_UE_TRANSPORT/nr_prach.c | 28 ++--- .../NR_UE_TRANSPORT/nr_transport_proto_ue.h | 3 +- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 33 ++--- openair1/PHY/defs_nr_UE.h | 1 - openair1/SCHED_NR_UE/defs.h | 6 +- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 9 +- .../SCHED_NR_UE/phy_procedures_nr_ue_sl.c | 4 +- openair1/SIMULATION/NR_PHY/prachsim.c | 31 +++-- openair1/SIMULATION/NR_PHY/psbchsim.c | 7 +- openair1/SIMULATION/NR_PHY/ulsim.c | 118 +++++++++++------- 12 files changed, 147 insertions(+), 124 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 60196320c9..d026b4f44a 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -504,7 +504,7 @@ static int nr_ue_slot_select(const fapi_nr_config_request_t *cfg, int nr_slot) return NR_DOWNLINK_SLOT; } -static void RU_write(nr_rxtx_thread_data_t *rxtxD, bool sl_tx_action) +static void RU_write(nr_rxtx_thread_data_t *rxtxD, bool sl_tx_action, c16_t **txp) { PHY_VARS_NR_UE *UE = rxtxD->UE; const fapi_nr_config_request_t *cfg = &UE->nrUE_config; @@ -514,10 +514,7 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD, bool sl_tx_action) if (UE->sl_mode == 2) fp = &UE->SL_UE_PHY_PARAMS.sl_frame_params; - void *txp[NB_ANTENNAS_TX]; int slot = proc->nr_slot_tx; - for (int i = 0; i < fp->nb_antennas_tx; i++) - txp[i] = (void *)&UE->common_vars.txData[i][fp->get_samples_slot_timestamp(slot, fp, 0)]; radio_tx_burst_flag_t flags = TX_BURST_INVALID; @@ -551,7 +548,7 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD, bool sl_tx_action) const int maxWriteBlockSize = fp->get_samples_per_slot(proc->nr_slot_tx, fp); while (writeBlockSize > maxWriteBlockSize) { const int dummyBlockSize = min(writeBlockSize - maxWriteBlockSize, maxWriteBlockSize); - int tmp = openair0_write_reorder(&UE->rfdevice, writeTimestamp, txp, dummyBlockSize, fp->nb_antennas_tx, flags); + int tmp = openair0_write_reorder(&UE->rfdevice, writeTimestamp, (void **)txp, dummyBlockSize, fp->nb_antennas_tx, flags); AssertFatal(tmp == dummyBlockSize, ""); writeTimestamp += dummyBlockSize; @@ -567,7 +564,7 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD, bool sl_tx_action) nr_fo_compensation(ul_freq_offset, fp->samples_per_subframe, writeTimestamp, txp[i], txp[i], writeBlockSize); } - int tmp = openair0_write_reorder(&UE->rfdevice, writeTimestamp, txp, writeBlockSize, fp->nb_antennas_tx, flags); + int tmp = openair0_write_reorder(&UE->rfdevice, writeTimestamp, (void **)txp, writeBlockSize, fp->nb_antennas_tx, flags); AssertFatal(tmp == writeBlockSize, ""); } @@ -583,6 +580,17 @@ void processSlotTX(void *arg) if (UE->if_inst) UE->if_inst->slot_indication(UE->Mod_id, true); + LOG_D(PHY, "SlotTx %d.%d => slot type %d\n", proc->frame_tx, proc->nr_slot_tx, proc->tx_slot_type); + + NR_DL_FRAME_PARMS *fp = &UE->frame_parms; + c16_t *txp[fp->nb_antennas_tx]; + for (int i = 0; i < fp->nb_antennas_tx; i++) { + txp[i] = UE->common_vars.txData[i] + fp->get_samples_slot_timestamp(proc->nr_slot_tx, fp, 0); + // We should not need to set it to 0 + // but in mixed slots, in TDD continuous tx (should not exist), ... we don't know the parts to ignore + memset(txp[i], 0, fp->get_samples_per_slot(proc->nr_slot_tx, fp) * sizeof(**txp)); + } + if (proc->tx_slot_type == NR_UPLINK_SLOT || proc->tx_slot_type == NR_MIXED_SLOT) { if (UE->sl_mode == 2 && proc->tx_slot_type == NR_SIDELINK_SLOT) { // trigger L2 to run ue_sidelink_scheduler thru IF module @@ -608,7 +616,7 @@ void processSlotTX(void *arg) AssertFatal((phy_data.sl_tx_action >= SL_NR_CONFIG_TYPE_TX_PSBCH && phy_data.sl_tx_action < SL_NR_CONFIG_TYPE_TX_MAXIMUM), "Incorrect SL TX Action Scheduled\n"); - phy_procedures_nrUE_SL_TX(UE, proc, &phy_data); + phy_procedures_nrUE_SL_TX(UE, proc, &phy_data, txp); sl_tx_action = true; } @@ -630,12 +638,12 @@ void processSlotTX(void *arg) } dynamic_barrier_join(rxtxD->next_barrier); - phy_procedures_nrUE_TX(UE, proc, &phy_data); + phy_procedures_nrUE_TX(UE, proc, &phy_data, txp); } } else { dynamic_barrier_join(rxtxD->next_barrier); } - RU_write(rxtxD, sl_tx_action); + RU_write(rxtxD, sl_tx_action, txp); TracyCZoneEnd(ctx); } @@ -723,7 +731,7 @@ static int UE_dl_preprocessing(PHY_VARS_NR_UE *UE, if (phy_data->dlsch[0].active && phy_data->dlsch[0].rnti_type == TYPE_C_RNTI_) { // indicate to tx thread to wait for DLSCH decoding if (phy_data->dlsch[0].dlsch_config.k1_feedback) { // if feedback is 0 there is no HARQ associated with this DLSCH - const int ack_nack_slot = (proc->nr_slot_rx + phy_data->dlsch[0].dlsch_config.k1_feedback) % UE->frame_parms.slots_per_frame; + const int ack_nack_slot = (proc->nr_slot_rx + phy_data->dlsch[0].dlsch_config.k1_feedback) % fp->slots_per_frame; tx_wait_for_dlsch[ack_nack_slot]++; } } @@ -1020,7 +1028,6 @@ void *UE_thread(void *arg) notifiedFIFO_elt_t *Msg = newNotifiedFIFO_elt(sizeof(syncData_t), 0, &nf, UE_synch); syncData_t *syncMsg = (syncData_t *)NotifiedFifoData(Msg); *syncMsg = (syncData_t){0}; - NR_DL_FRAME_PARMS *fp = &UE->frame_parms; if (UE->UE_scan_carrier) { // Get list of GSCN in this band for UE's bandwidth and center frequency. LOG_W(PHY, "UE set to scan all GSCN in current bandwidth\n"); diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index 5163ab3bb8..aa1eba0822 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -275,7 +275,7 @@ uint32_t get_samples_slot_timestamp(int slot, const NR_DL_FRAME_PARMS *fp, unsig for(unsigned int idx_slot = 0; idx_slot < slot; idx_slot++) samp_count += fp->get_samples_per_slot(idx_slot, fp); } else { - for(unsigned int idx_slot = slot; idx_slot < slot+sl_ahead; idx_slot++) + for (unsigned int idx_slot = slot; idx_slot < slot + sl_ahead; idx_slot++) samp_count += fp->get_samples_per_slot(idx_slot, fp); } return samp_count; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c index f0ee943817..9405315e04 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c @@ -52,8 +52,8 @@ // - idft for short sequence assumes we are transmitting starting in symbol 0 of a PRACH slot // - Assumes that PRACH SCS is same as PUSCH SCS @ 30 kHz, take values for formats 0-2 and adjust for others below // - Preamble index different from 0 is not detected by gNB -int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t slot){ - +int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t slot, c16_t **txData) +{ NR_DL_FRAME_PARMS *fp=&ue->frame_parms; fapi_nr_config_request_t *nrUE_config = &ue->nrUE_config; fapi_nr_ul_config_prach_pdu *prach_pdu = &ue->prach_vars[gNB_id]->prach_pdu; @@ -66,7 +66,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t c16_t prachF_tmp[(4688 + 4 * 24576) * 4] __attribute__((aligned(32))) = {0}; int Ncp = 0; - int prach_start, prach_sequence_length, prach_len, dftlen, mu, n_ra_prb, k, prachStartSymbol, sample_offset_slot; + int prach_start, prach_sequence_length, prach_len, dftlen, mu, n_ra_prb, k, prachStartSymbol; fd_occasion = prach_pdu->num_ra; prach_len = 0; @@ -98,23 +98,22 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t } if (prachStartSymbol == 0) { - sample_offset_slot = 0; + prach_start = 0; } else if (fp->slots_per_subframe == 1) { if (prachStartSymbol <= 7) - sample_offset_slot = (fp->ofdm_symbol_size + fp->nb_prefix_samples) * (prachStartSymbol - 1) + (fp->ofdm_symbol_size + fp->nb_prefix_samples0); + prach_start = + (fp->ofdm_symbol_size + fp->nb_prefix_samples) * (prachStartSymbol - 1) + (fp->ofdm_symbol_size + fp->nb_prefix_samples0); else - sample_offset_slot = (fp->ofdm_symbol_size + fp->nb_prefix_samples) * (prachStartSymbol - 2) + (fp->ofdm_symbol_size + fp->nb_prefix_samples0) * 2; + prach_start = (fp->ofdm_symbol_size + fp->nb_prefix_samples) * (prachStartSymbol - 2) + + (fp->ofdm_symbol_size + fp->nb_prefix_samples0) * 2; } else { if (slot % (fp->slots_per_subframe / 2) == 0) - sample_offset_slot = (fp->ofdm_symbol_size + fp->nb_prefix_samples) * (prachStartSymbol - 1) + (fp->ofdm_symbol_size + fp->nb_prefix_samples0); + prach_start = + (fp->ofdm_symbol_size + fp->nb_prefix_samples) * (prachStartSymbol - 1) + (fp->ofdm_symbol_size + fp->nb_prefix_samples0); else - sample_offset_slot = (fp->ofdm_symbol_size + fp->nb_prefix_samples) * prachStartSymbol; + prach_start = (fp->ofdm_symbol_size + fp->nb_prefix_samples) * prachStartSymbol; } - prach_start = fp->get_samples_slot_timestamp(slot, fp, 0) + sample_offset_slot; - - //printf("prachstartsymbold %d, sample_offset_slot %d, prach_start %d\n",prachStartSymbol, sample_offset_slot, prach_start); - // First compute physical root sequence /************************************************************************ * 4G and NR NCS tables are slightly different and depend on prach format @@ -506,13 +505,12 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t LOG_I(PHY, "PRACH [UE %d] N_RB_UL %d prach_start %d, prach_len %d\n", Mod_id, fp->N_RB_UL, prach_start, prach_len); #endif - memcpy(ue->common_vars.txData[0] + prach_start, prach, sizeof(c16_t) * prach_len); + memcpy(txData[0] + prach_start, prach, sizeof(c16_t) * prach_len); #ifdef PRACH_WRITE_OUTPUT_DEBUG LOG_M("prach_tx0.m", "prachtx0", prach + (Ncp << 1), prach_len - Ncp, 1, 1); - LOG_M("Prach_txsig.m", "txs", (int16_t *)(&ue->common_vars.txdata[0][prach_start]), 2 * (prach_start + prach_len), 1, 1) + LOG_M("Prach_txsig.m", "txs", (int16_t *)(&txdata[0][prach_start]), 2 * (prach_start + prach_len), 1, 1) #endif return signal_energy((int *)prach, 256); } - 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 fee1f4cabb..9c6e0c1454 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -151,6 +151,7 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE, const NR_DL_FRAME_PARMS *frame_parms, const uint8_t n_antenna_ports, c16_t **txdataF, + c16_t **txdata, uint32_t linktype, bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT]); @@ -315,7 +316,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, int G, uint32_t nvar); -int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t slot); +int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t slot, c16_t **txData); void dump_nrdlsch(PHY_VARS_NR_UE *ue,uint8_t gNB_id,uint8_t nr_slot_rx,unsigned int *coded_bits_per_codeword,int round, unsigned char harq_pid); void nr_a_sum_b(c16_t *input_x, c16_t *input_y, unsigned short nb_rb); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 72fac53825..e8217ee5aa 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -828,25 +828,17 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE, const NR_DL_FRAME_PARMS *frame_parms, const uint8_t n_antenna_ports, c16_t **txdataF, + c16_t **txdata, uint32_t linktype, bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT]) { - const int tx_offset = frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0); - int N_RB = (linktype == link_type_sl) ? frame_parms->N_RB_SL : frame_parms->N_RB_UL; - c16_t **txdata = UE->common_vars.txData; for (int i = 0; i < NR_NUMBER_OF_SYMBOLS_PER_SLOT; i++) { if (was_symbol_used[i] == false) continue; - for(int ap = 0; ap < n_antenna_ports; ap++) { - apply_nr_rotation_TX(frame_parms, - txdataF[ap], - frame_parms->symbol_rotation[linktype], - slot, - N_RB, - i, - 1); + for (int ap = 0; ap < n_antenna_ports; ap++) { + apply_nr_rotation_TX(frame_parms, txdataF[ap], frame_parms->symbol_rotation[linktype], slot, N_RB, i, 1); } } @@ -855,25 +847,20 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE, if (frame_parms->Ncp == 1) { // extended cyclic prefix for (int i = 0; i < NR_NUMBER_OF_SYMBOLS_PER_SLOT_EXTENDED_CP; i++) { if (was_symbol_used[i] == false) { - memset(&txdata[ap][tx_offset + (frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples) * i], + memset(&txdata[ap][(frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples) * i], 0, (frame_parms->nb_prefix_samples + frame_parms->ofdm_symbol_size) * sizeof(int32_t)); continue; } PHY_ofdm_mod((int *)&txdataF[ap][frame_parms->ofdm_symbol_size * i], - (int *)&txdata[ap][tx_offset + frame_parms->ofdm_symbol_size * i], - frame_parms->ofdm_symbol_size, - 1, - frame_parms->nb_prefix_samples, - CYCLIC_PREFIX); + (int *)&txdata[ap][frame_parms->ofdm_symbol_size * i], + frame_parms->ofdm_symbol_size, + 1, + frame_parms->nb_prefix_samples, + CYCLIC_PREFIX); } } else { // normal cyclic prefix - nr_normal_prefix_mod(txdataF[ap], - &txdata[ap][tx_offset], - NR_NUMBER_OF_SYMBOLS_PER_SLOT, - frame_parms, - slot, - was_symbol_used); + nr_normal_prefix_mod(txdataF[ap], txdata[ap], NR_NUMBER_OF_SYMBOLS_PER_SLOT, frame_parms, slot, was_symbol_used); } } diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index f724861e2d..a78840e662 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -578,7 +578,6 @@ typedef struct nr_phy_data_tx_s { // Sidelink Rx action decided by MAC sl_nr_tx_config_type_enum_t sl_tx_action; sl_nr_tx_config_psbch_pdu_t psbch_vars; - } nr_phy_data_tx_t; typedef struct nr_phy_data_s { diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h index 7ae4bb6a70..da885d3a83 100644 --- a/openair1/SCHED_NR_UE/defs.h +++ b/openair1/SCHED_NR_UE/defs.h @@ -90,7 +90,7 @@ @param proc Pointer to RXn-TXnp4 proc information @param phy_data */ -void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data); +void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data, c16_t **txp); int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data); @@ -100,7 +100,7 @@ void processSlotTX(void *arg); /*! \brief UE PRACH procedures. */ -void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc); +void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, c16_t **txData); int8_t nr_find_ue(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB); @@ -160,7 +160,7 @@ void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu); int psbch_pscch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data); -void phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data); +void phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data, c16_t **txp); /*! \brief This function prepares the sl indication to pass to the MAC */ void nr_fill_sl_indication(nr_sidelink_indication_t *sl_ind, diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 5345d010f4..baa6d10449 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -268,7 +268,7 @@ void ue_ta_procedures(PHY_VARS_NR_UE *ue, int slot_tx, int frame_tx) } } -void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data) +void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data, c16_t **txp) { const int slot_tx = proc->nr_slot_tx; const int frame_tx = proc->frame_tx; @@ -306,12 +306,13 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, n &ue->frame_parms, ue->frame_parms.nb_antennas_tx, (c16_t **)txdataF, + txp, link_type_ul, was_symbol_used); stop_meas_nr_ue_phy(ue, OFDM_MOD_STATS); } - nr_ue_prach_procedures(ue, proc); + nr_ue_prach_procedures(ue, proc, txp); LOG_D(PHY, "****** end TX-Chain for AbsSubframe %d.%d ******\n", proc->frame_tx, proc->nr_slot_tx); @@ -1179,7 +1180,7 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_ // todo: // - power control as per 38.213 ch 7.4 -void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc) +void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, c16_t **txData) { int gNB_id = proc->gNB_id; int frame_tx = proc->frame_tx, nr_slot_tx = proc->nr_slot_tx, prach_power; // tx_amp @@ -1208,7 +1209,7 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_IN); start_meas_nr_ue_phy(ue, PRACH_GEN_STATS); - prach_power = generate_nr_prach(ue, gNB_id, frame_tx, nr_slot_tx); + prach_power = generate_nr_prach(ue, gNB_id, frame_tx, nr_slot_tx, txData); stop_meas_nr_ue_phy(ue, PRACH_GEN_STATS); if (cpumeas(CPUMEAS_GETSTATE)) { LOG_D(PHY, diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c index 19a4449c11..13b081385d 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue_sl.c @@ -264,7 +264,7 @@ int psbch_pscch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr return sampleShift; } -void phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data) +void phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data, c16_t **txp) { int slot_tx = proc->nr_slot_tx; int frame_tx = proc->frame_tx; @@ -313,7 +313,7 @@ void phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc was_symbol_used[i] = true; if (tx_action) { LOG_D(NR_PHY, "Sending Uplink data \n"); - nr_ue_pusch_common_procedures(ue, proc->nr_slot_tx, fp, fp->nb_antennas_tx, txdataF, link_type_sl, was_symbol_used); + nr_ue_pusch_common_procedures(ue, proc->nr_slot_tx, fp, fp->nb_antennas_tx, txdataF, txp, link_type_sl, was_symbol_used); } LOG_D(NR_PHY, "****** end Sidelink TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx); diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 8095dc4b51..aebfe4997f 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -134,7 +134,7 @@ int main(int argc, char **argv){ get_softmodem_params()->sl_mode = 0; double sigma2, sigma2_dB = 0, SNR, snr0 = -2.0, snr1 = 0.0, ue_speed0 = 0.0, ue_speed1 = 0.0; double **s_re, **s_im, **r_re, **r_im, iqim = 0.0, delay_avg = 0, ue_speed = 0, fs=-1, bw; - int i, l, aa, aarx, trial, n_frames = 1, prach_start, rx_prach_start; //, ntrials=1; + int i, l, aa, aarx, trial, n_frames = 1, rx_prach_start; //, ntrials=1; c16_t **txdata; int N_RB_UL = 106, delay = 0, NCS_config = 13, rootSequenceIndex = 1, threequarter_fs = 0, mu = 1, fd_occasion = 0, loglvl = OAILOG_INFO, numRA = 0, prachStartSymbol = 0; uint8_t snr1set = 0, ue_speed1set = 0, transmission_mode = 1, n_tx = 1, n_rx = 1, awgn_flag = 0, msg1_frequencystart = 0, num_prach_fd_occasions = 1, prach_format=0; @@ -666,14 +666,17 @@ int main(int argc, char **argv){ ue_prach_config->num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index, UE->X_u); - generate_nr_prach(UE, 0, frame, slot); + int prach_start = subframe * frame_parms->samples_per_subframe; + int slot_start = frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0); + c16_t *tx[frame_parms->nb_antennas_rx]; + for (int i = 0; i < frame_parms->nb_antennas_rx; i++) + tx[i] = txdata[i] + slot_start; + generate_nr_prach(UE, 0, frame, slot, tx); /* tx_lev_dB not used later, no need to set */ //tx_lev_dB = (unsigned int) dB_fixed(tx_lev); - prach_start = subframe*frame_parms->samples_per_subframe; - - #ifdef NR_PRACH_DEBUG +#ifdef NR_PRACH_DEBUG LOG_M("txsig0.m", "txs0", &txdata[0][subframe*frame_parms->samples_per_subframe], frame_parms->samples_per_subframe, 1, 1); LOG_M("txsig0_frame.m","txs0", txdata[0],frame_parms->samples_per_frame,1,1); #endif @@ -750,8 +753,9 @@ int main(int argc, char **argv){ for (i = 0; i< frame_parms->samples_per_subframe; i++) { for (aa = 0; aa < frame_parms->nb_antennas_rx; aa++) { - ((short*) &ru->common.rxdata[aa][rx_prach_start])[2*i] = (short) (.167*(r_re[aa][i] +sqrt(sigma2/2)*gaussdouble(0.0,1.0))); - ((short*) &ru->common.rxdata[aa][rx_prach_start])[2*i+1] = (short) (.167*(r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + c16_t *tmp = (c16_t *)ru->common.rxdata[aa] + rx_prach_start + i; + tmp->r = (short)(.167 * (r_re[aa][i] + sqrt(sigma2 / 2) * gaussdouble(0.0, 1.0))); + tmp->i = (short)(.167 * (r_im[aa][i] + (iqim * r_re[aa][i]) + sqrt(sigma2 / 2) * gaussdouble(0.0, 1.0))); } } } else { @@ -765,15 +769,10 @@ int main(int argc, char **argv){ for (l = 0; l < frame_parms->symbols_per_slot; l++) { for (aa = 0; aa < frame_parms->nb_antennas_rx; aa++) { - nr_slot_fep_ul(frame_parms, - (int32_t *)ru->common.rxdata[aa], - (int32_t *)ru->common.rxdataF[aa], - l, - slot, - ru->N_TA_offset); - } - } - + nr_slot_fep_ul(frame_parms, ru->common.rxdata[aa], ru->common.rxdataF[aa], l, slot, ru->N_TA_offset); + } + } + rx_nr_prach_ru(ru, prach_format, numRA, prachStartSymbol, slot, prachOccasion, frame, slot); for (int i = 0; i < ru->nb_rx; ++i) diff --git a/openair1/SIMULATION/NR_PHY/psbchsim.c b/openair1/SIMULATION/NR_PHY/psbchsim.c index d7b01da756..17c3473eb8 100644 --- a/openair1/SIMULATION/NR_PHY/psbchsim.c +++ b/openair1/SIMULATION/NR_PHY/psbchsim.c @@ -576,8 +576,11 @@ int main(int argc, char **argv) proc.frame_rx, proc.nr_slot_rx, sl_uerx->sl_config.sl_sync_source.rx_slss_id); - - phy_procedures_nrUE_SL_TX(UE_TX, &proc, &phy_data_tx); + int slot_start = frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0); + c16_t *tx[frame_parms->nb_antennas_rx]; + for (int i = 0; i < frame_parms->nb_antennas_rx; i++) + tx[i] = UE_TX->common_vars.txData[i] + slot_start; + phy_procedures_nrUE_SL_TX(UE_TX, &proc, &phy_data_tx, tx); for (SNR = snr0; SNR >= snr1 && !stop; SNR -= 1) { for (int trial = 0; trial < n_trials && !stop; trial++) { diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 83c1c31826..2ca025865f 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -190,8 +190,7 @@ int main(int argc, char *argv[]) corr_level_t corr_level = CORR_LEVEL_LOW; uint16_t N_RB_DL = 106, N_RB_UL = 106, mu = 1; - //unsigned char frame_type = 0; - NR_DL_FRAME_PARMS *frame_parms; + // unsigned char frame_type = 0; int loglvl = OAILOG_WARNING; uint16_t nb_symb_sch = 12; int start_symbol = 0; @@ -612,11 +611,9 @@ int main(int argc, char *argv[]) UL_INFO.crc_ind.number_crcs = 0; gNB->max_ldpc_iterations = max_ldpc_iterations; gNB->pusch_thres = -20; - frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH) - - frame_parms->N_RB_DL = N_RB_DL; - frame_parms->N_RB_UL = N_RB_UL; - frame_parms->Ncp = extended_prefix_flag ? EXTENDED : NORMAL; + gNB->frame_parms.N_RB_DL = N_RB_DL; + gNB->frame_parms.N_RB_UL = N_RB_UL; + gNB->frame_parms.Ncp = extended_prefix_flag ? EXTENDED : NORMAL; AssertFatal((gNB->if_inst = NR_IF_Module_init(0)) != NULL, "Cannot register interface"); gNB->if_inst->NR_PHY_config_req = nr_phy_config_request; @@ -682,8 +679,8 @@ int main(int argc, char *argv[]) // UE dedicated configuration nr_mac_add_test_ue(RC.nrmac[0], rnti, secondaryCellGroup); - frame_parms->nb_antennas_tx = 1; - frame_parms->nb_antennas_rx = n_rx; + gNB->frame_parms.nb_antennas_tx = 1; + gNB->frame_parms.nb_antennas_rx = n_rx; nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; cfg->carrier_config.num_tx_ant.value = 1; cfg->carrier_config.num_rx_ant.value = n_rx; @@ -712,7 +709,7 @@ int main(int argc, char *argv[]) n_rx, channel_model, sampling_frequency / 1e6, - frame_parms->ul_CarrierFreq, + gNB->frame_parms.ul_CarrierFreq, tx_bandwidth, DS_TDL, maxDoppler, @@ -732,7 +729,7 @@ int main(int argc, char *argv[]) PHY_vars_UE_g = malloc(sizeof(PHY_VARS_NR_UE**)); PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_NR_UE*)); PHY_vars_UE_g[0][0] = UE; - memcpy(&UE->frame_parms, frame_parms, sizeof(NR_DL_FRAME_PARMS)); + UE->frame_parms = gNB->frame_parms; UE->frame_parms.nb_antennas_tx = n_tx; UE->frame_parms.nb_antennas_rx = 0; UE->nrLDPC_coding_interface = gNB->nrLDPC_coding_interface; @@ -865,7 +862,7 @@ int main(int argc, char *argv[]) uint8_t ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, Imcs, mcs_table); uint8_t ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, nb_rb); - double ts = 1.0/(frame_parms->subcarrier_spacing * frame_parms->ofdm_symbol_size); + double ts = 1.0 / (gNB->frame_parms.subcarrier_spacing * gNB->frame_parms.ofdm_symbol_size); /* -T option enable PTRS */ if(enable_ptrs) { @@ -897,7 +894,7 @@ int main(int argc, char *argv[]) unsigned int available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, number_dmrs_symbols, unav_res, mod_order, precod_nbr_layers); printf("[ULSIM]: VALUE OF G: %u, TBS: %u\n", available_bits, TBS); - int frame_length_complex_samples = frame_parms->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME; + int frame_length_complex_samples = gNB->frame_parms.samples_per_subframe * NR_NUMBER_OF_SUBFRAMES_PER_FRAME; for (int aatx=0; aatxget_samples_slot_timestamp(slot,frame_parms,0); - int slot_length = slot_offset - frame_parms->get_samples_slot_timestamp(slot-1,frame_parms,0); + int slot_offset = gNB->frame_parms.get_samples_slot_timestamp(slot, &gNB->frame_parms, 0); + int slot_length = slot_offset - gNB->frame_parms.get_samples_slot_timestamp(slot - 1, &gNB->frame_parms, 0); if (input_fd != NULL) { // 800 samples is N_TA_OFFSET for FR1 @ 30.72 Ms/s, - AssertFatal(frame_parms->subcarrier_spacing==30000,"only 30 kHz for file input for now (%d)\n",frame_parms->subcarrier_spacing); - + AssertFatal(gNB->frame_parms.subcarrier_spacing == 30000, + "only 30 kHz for file input for now (%d)\n", + gNB->frame_parms.subcarrier_spacing); + if (params_from_file) { fseek(input_fd,file_offset*((slot_length<<2)+4000+16),SEEK_SET); read_errors+=fread((void*)&n_rnti,sizeof(int16_t),1,input_fd); @@ -942,7 +941,7 @@ int main(int argc, char *argv[]) printf("harq_pid %d\n",harq_pid); } fseek(input_fd,file_offset*sizeof(int16_t)*2,SEEK_SET); - for (int irx=0; irxnb_antennas_rx; irx++) { + for (int irx = 0; irx < gNB->frame_parms.nb_antennas_rx; irx++) { fseek(input_fd,irx*(slot_length+15)*sizeof(int16_t)*2,SEEK_SET); // matlab adds samlples to the end to emulate channel delay read_errors += fread((void *)&rxdata[irx][slot_offset-delay], sizeof(int16_t), slot_length<<1, input_fd); if (read_errors==0) { @@ -1115,10 +1114,10 @@ int main(int argc, char *argv[]) srs_pdu->rnti = n_rnti; srs_pdu->bwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, 275); srs_pdu->bwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth, 275); - srs_pdu->subcarrier_spacing = frame_parms->subcarrier_spacing; + srs_pdu->subcarrier_spacing = gNB->frame_parms.subcarrier_spacing; srs_pdu->num_ant_ports = n_tx == 4 ? 2 : n_tx == 2 ? 1 : 0; srs_pdu->sequence_id = 40; - srs_pdu->time_start_position = frame_parms->symbols_per_slot - 1; + srs_pdu->time_start_position = gNB->frame_parms.symbols_per_slot - 1; srs_pdu->config_index = rrc_get_max_nr_csrs(srs_pdu->bwp_size, srs_pdu->bandwidth_index); srs_pdu->resource_type = NR_SRS_Resource__resourceType_PR_periodic; srs_pdu->t_srs = 1; @@ -1197,7 +1196,7 @@ int main(int argc, char *argv[]) srs_config_pdu->rnti = n_rnti; srs_config_pdu->bwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, 275); srs_config_pdu->bwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth, 275); - srs_config_pdu->subcarrier_spacing = frame_parms->subcarrier_spacing; + srs_config_pdu->subcarrier_spacing = gNB->frame_parms.subcarrier_spacing; srs_config_pdu->num_ant_ports = n_tx == 4 ? 2 : n_tx == 2 ? 1 : 0; srs_config_pdu->config_index = rrc_get_max_nr_csrs(srs_config_pdu->bwp_size, srs_config_pdu->bandwidth_index); srs_config_pdu->sequence_id = 40; @@ -1214,8 +1213,11 @@ int main(int argc, char *argv[]) /////////////////////////phy_procedures_nr_ue_TX/////////////////////// /////////// - - phy_procedures_nrUE_TX(UE, &UE_proc, &phy_data); + int slot_start = UE->frame_parms.get_samples_slot_timestamp(slot, &UE->frame_parms, 0); + c16_t *tx[UE->frame_parms.nb_antennas_tx]; + for (int i = 0; i < UE->frame_parms.nb_antennas_tx; i++) + tx[i] = UE->common_vars.txData[i] + slot_start; + phy_procedures_nrUE_TX(UE, &UE_proc, &phy_data, tx); if (n_trials == 1) { LOG_M("txsig0.m", "txs0", &UE->common_vars.txData[0][slot_offset], slot_length, 1, 1 | log_format); @@ -1229,13 +1231,14 @@ int main(int argc, char *argv[]) } /////////// //////////////////////////////////////////////////// - tx_offset = frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0); + tx_offset = gNB->frame_parms.get_samples_slot_timestamp(slot, &gNB->frame_parms, 0); txlev_sum = 0; for (int aa = 0; aa < UE->frame_parms.nb_antennas_tx; aa++) { - atxlev[aa] = signal_energy( - (int32_t *)&UE->common_vars.txData[aa][tx_offset + 5 * frame_parms->ofdm_symbol_size - + 4 * frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0], - frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples); + atxlev[aa] = + signal_energy((int32_t *)&UE->common_vars + .txData[aa][tx_offset + 5 * gNB->frame_parms.ofdm_symbol_size + + 4 * gNB->frame_parms.nb_prefix_samples + gNB->frame_parms.nb_prefix_samples0], + gNB->frame_parms.ofdm_symbol_size + gNB->frame_parms.nb_prefix_samples); txlev_sum += atxlev[aa]; @@ -1248,11 +1251,16 @@ int main(int argc, char *argv[]) if (input_fd == NULL) { // Justification of division by precod_nbr_layers: // When the channel is the identity matrix, the results in terms of SNR should be almost equal for 2x2 and 4x4. - sigma_dB = 10 * log10((double)txlev_sum / precod_nbr_layers * ((double)frame_parms->ofdm_symbol_size / (12 * nb_rb))) - SNR; + sigma_dB = + 10 * log10((double)txlev_sum / precod_nbr_layers * ((double)gNB->frame_parms.ofdm_symbol_size / (12 * nb_rb))) - SNR; sigma = pow(10, sigma_dB / 10); if (n_trials == 1) - printf("sigma %f (%f dB), txlev_sum %f (factor %f)\n", sigma, sigma_dB, 10 * log10((double)txlev_sum), (double)(double)frame_parms->ofdm_symbol_size / (12 * nb_rb)); + printf("sigma %f (%f dB), txlev_sum %f (factor %f)\n", + sigma, + sigma_dB, + 10 * log10((double)txlev_sum), + (double)(double)gNB->frame_parms.ofdm_symbol_size / (12 * nb_rb)); for (i = 0; i < slot_length; i++) { for (int aa = 0; aa < UE->frame_parms.nb_antennas_tx; aa++) { @@ -1262,7 +1270,17 @@ int main(int argc, char *argv[]) } multipath_channel(UE2gNB, s_re, s_im, r_re, r_im, slot_length, 0, (n_trials == 1) ? 1 : 0); - add_noise(rxdata, (const double **) r_re, (const double **) r_im, sigma, slot_length, slot_offset, ts, delay, pdu_bit_map, PUSCH_PDU_BITMAP_PUSCH_PTRS, frame_parms->nb_antennas_rx); + add_noise(rxdata, + (const double **)r_re, + (const double **)r_im, + sigma, + slot_length, + slot_offset, + ts, + delay, + pdu_bit_map, + PUSCH_PDU_BITMAP_PUSCH_PTRS, + gNB->frame_parms.nb_antennas_rx); } /*End input_fd */ @@ -1298,15 +1316,25 @@ int main(int argc, char *argv[]) if (n_trials == 1 && round == 0) { LOG_M("rxsig0.m", "rx0", &rxdata[0][slot_offset], slot_length, 1, 1 | log_format); - LOG_M("rxsigF0.m", "rxsF0", gNB->common_vars.rxdataF[0][0], 14 * frame_parms->ofdm_symbol_size, 1, 1 | log_format); + LOG_M("rxsigF0.m", "rxsF0", gNB->common_vars.rxdataF[0][0], 14 * gNB->frame_parms.ofdm_symbol_size, 1, 1 | log_format); if (precod_nbr_layers > 1) { LOG_M("rxsig1.m", "rx1", &rxdata[1][slot_offset], slot_length, 1, 1); - LOG_M("rxsigF1.m", "rxsF1", gNB->common_vars.rxdataF[0][1], 14 * frame_parms->ofdm_symbol_size, 1, 1 | log_format); + LOG_M("rxsigF1.m", "rxsF1", gNB->common_vars.rxdataF[0][1], 14 * gNB->frame_parms.ofdm_symbol_size, 1, 1 | log_format); if (precod_nbr_layers == 4) { LOG_M("rxsig2.m", "rx2", &rxdata[2][slot_offset], slot_length, 1, 1); LOG_M("rxsig3.m", "rx3", &rxdata[3][slot_offset], slot_length, 1, 1); - LOG_M("rxsigF2.m", "rxsF2", gNB->common_vars.rxdataF[0][2], 14 * frame_parms->ofdm_symbol_size, 1, 1 | log_format); - LOG_M("rxsigF3.m", "rxsF3", gNB->common_vars.rxdataF[0][3], 14 * frame_parms->ofdm_symbol_size, 1, 1 | log_format); + LOG_M("rxsigF2.m", + "rxsF2", + gNB->common_vars.rxdataF[0][2], + 14 * gNB->frame_parms.ofdm_symbol_size, + 1, + 1 | log_format); + LOG_M("rxsigF3.m", + "rxsF3", + gNB->common_vars.rxdataF[0][3], + 14 * gNB->frame_parms.ofdm_symbol_size, + 1, + 1 | log_format); } } } @@ -1317,8 +1345,8 @@ int main(int argc, char *argv[]) LOG_M("chestF0.m", "chF0", - &pusch_vars->ul_ch_estimates[0][start_symbol * frame_parms->ofdm_symbol_size], - frame_parms->ofdm_symbol_size, + &pusch_vars->ul_ch_estimates[0][start_symbol * gNB->frame_parms.ofdm_symbol_size], + gNB->frame_parms.ofdm_symbol_size, 1, 1 | log_format); @@ -1332,8 +1360,8 @@ int main(int argc, char *argv[]) if (precod_nbr_layers == 2) { LOG_M("chestF3.m", "chF3", - &pusch_vars->ul_ch_estimates[3][start_symbol * frame_parms->ofdm_symbol_size], - frame_parms->ofdm_symbol_size, + &pusch_vars->ul_ch_estimates[3][start_symbol * gNB->frame_parms.ofdm_symbol_size], + gNB->frame_parms.ofdm_symbol_size, 1, 1 | log_format); @@ -1348,20 +1376,20 @@ int main(int argc, char *argv[]) if (precod_nbr_layers == 4) { LOG_M("chestF5.m", "chF5", - &pusch_vars->ul_ch_estimates[5][start_symbol * frame_parms->ofdm_symbol_size], - frame_parms->ofdm_symbol_size, + &pusch_vars->ul_ch_estimates[5][start_symbol * gNB->frame_parms.ofdm_symbol_size], + gNB->frame_parms.ofdm_symbol_size, 1, 1 | log_format); LOG_M("chestF10.m", "chF10", - &pusch_vars->ul_ch_estimates[10][start_symbol * frame_parms->ofdm_symbol_size], - frame_parms->ofdm_symbol_size, + &pusch_vars->ul_ch_estimates[10][start_symbol * gNB->frame_parms.ofdm_symbol_size], + gNB->frame_parms.ofdm_symbol_size, 1, 1 | log_format); LOG_M("chestF15.m", "chF15", - &pusch_vars->ul_ch_estimates[15][start_symbol * frame_parms->ofdm_symbol_size], - frame_parms->ofdm_symbol_size, + &pusch_vars->ul_ch_estimates[15][start_symbol * gNB->frame_parms.ofdm_symbol_size], + gNB->frame_parms.ofdm_symbol_size, 1, 1 | log_format); From 33d72f6080a6740034178671c03ac5ab97a15e23 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Wed, 27 Nov 2024 18:10:19 +0100 Subject: [PATCH 15/17] fix C style, unefficient and complex --- executables/nr-ue.c | 3 --- openair1/SCHED_NR_UE/defs.h | 4 ---- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 4 +++- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index d026b4f44a..5a30900c3d 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -586,9 +586,6 @@ void processSlotTX(void *arg) c16_t *txp[fp->nb_antennas_tx]; for (int i = 0; i < fp->nb_antennas_tx; i++) { txp[i] = UE->common_vars.txData[i] + fp->get_samples_slot_timestamp(proc->nr_slot_tx, fp, 0); - // We should not need to set it to 0 - // but in mixed slots, in TDD continuous tx (should not exist), ... we don't know the parts to ignore - memset(txp[i], 0, fp->get_samples_per_slot(proc->nr_slot_tx, fp) * sizeof(**txp)); } if (proc->tx_slot_type == NR_UPLINK_SLOT || proc->tx_slot_type == NR_MIXED_SLOT) { diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h index da885d3a83..222788bce1 100644 --- a/openair1/SCHED_NR_UE/defs.h +++ b/openair1/SCHED_NR_UE/defs.h @@ -98,10 +98,6 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_ void processSlotTX(void *arg); -/*! \brief UE PRACH procedures. - */ -void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, c16_t **txData); - int8_t nr_find_ue(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB); /*! \brief UL time alignment procedures for TA application diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index baa6d10449..7fbfa11790 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -81,6 +81,8 @@ static const unsigned int gain_table[31] = {100, 112, 126, 141, 158, 178, 359, 398, 447, 501, 562, 631, 708, 794, 891, 1000, 1122, 1258, 1412, 1585, 1778, 1995, 2239, 2512, 2818, 3162}; +static void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, c16_t **txData); + void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind, fapi_nr_dci_indication_t *dci_ind, fapi_nr_rx_indication_t *rx_ind, @@ -1180,7 +1182,7 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_ // todo: // - power control as per 38.213 ch 7.4 -void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, c16_t **txData) +static void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, c16_t **txData) { int gNB_id = proc->gNB_id; int frame_tx = proc->frame_tx, nr_slot_tx = proc->nr_slot_tx, prach_power; // tx_amp From e7d91b8a04a3b0b1cb14fdf838b563b18fda6079 Mon Sep 17 00:00:00 2001 From: Reem Bahsoun Date: Fri, 9 May 2025 16:14:31 +0200 Subject: [PATCH 16/17] Set packet length with -l option to 1428 for the UL iperf command line to avoid packet fragmentation. *Packet fragmentation results in packet drops, leading to zero packets being received from the gNB to the UPF* --- ci-scripts/xml_files/container_sa_aerial_quectel.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-scripts/xml_files/container_sa_aerial_quectel.xml b/ci-scripts/xml_files/container_sa_aerial_quectel.xml index ccb9500a91..8f524550da 100644 --- a/ci-scripts/xml_files/container_sa_aerial_quectel.xml +++ b/ci-scripts/xml_files/container_sa_aerial_quectel.xml @@ -108,7 +108,7 @@ Iperf iperf (UL/UDP/40M)(30 sec)(single-ue profile) - -u -b 40M -t 30 + -u -b 40M -t 30 -l 1428 oc-cn5g-20897-aerial up2-aerial 25 From 4587210384e24d3ecb2dcc1173e2dd430abdc76a Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Tue, 15 Apr 2025 15:39:55 +0200 Subject: [PATCH 17/17] Add handler for Authentication Request * store ngKSI * send Authentication Failure if ngKSI is already associated with one of the 5G security contexts stored in the UE --- .../5GMM/MSG/fgmm_authentication_request.h | 37 +++++++++++++++++ openair3/NAS/NR_UE/nr_nas_msg.c | 41 ++++++++++++++++++- openair3/NAS/NR_UE/nr_nas_msg.h | 2 + 3 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_authentication_request.h diff --git a/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_authentication_request.h b/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_authentication_request.h new file mode 100644 index 0000000000..3735974889 --- /dev/null +++ b/openair3/NAS/NR_UE/5GS/5GMM/MSG/fgmm_authentication_request.h @@ -0,0 +1,37 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include +#include +#include +#include "NasKeySetIdentifier.h" + +#ifndef FGS_AUTHENTICATION_REQUEST_H_ +#define FGS_AUTHENTICATION_REQUEST_H_ + +typedef struct { + // NAS key set identifier (Mandatory) + NasKeySetIdentifier ngKSI; + // ABBA (Mandatory) + int abba; +} fgs_authentication_request_t; + +#endif /* ! defined(FGS_AUTHENTICATION_REQUEST_H_) */ diff --git a/openair3/NAS/NR_UE/nr_nas_msg.c b/openair3/NAS/NR_UE/nr_nas_msg.c index 3640c40aaa..a8c8f54ed7 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg.c +++ b/openair3/NAS/NR_UE/nr_nas_msg.c @@ -49,6 +49,7 @@ #include "RegistrationAccept.h" #include "SORTransparentContainer.h" #include "FGSIdentityResponse.h" +#include "fgmm_authentication_request.h" #include "T.h" #include "aka_functions.h" #include "assertions.h" @@ -856,6 +857,40 @@ static void generateAuthenticationFailure(nr_ue_nas_t *nas, as_nas_info_t *initi initialNasMsg->length = mm_msg_encode(&plain, initialNasMsg->nas_data, size); } +static void handle_fgmm_authentication_request(nr_ue_nas_t *nas, as_nas_info_t *initialNasMsg, byte_array_t *buffer) +{ + LOG_D(NAS, "Received NAS Authentication Request\n"); + fgs_authentication_request_t msg = {0}; + int size = 0; + int decoded = 0; + + // decode plain 5GMM message header + fgmm_msg_header_t mm_header = {0}; + if ((decoded = decode_5gmm_msg_header(&mm_header, buffer->buf + size, buffer->len - size)) < 0) { + LOG_E(NAS, "decode_5gmm_msg_header failure in NAS Authentication Request handling\n"); + return; + } + size += decoded; + // NAS key set identifier (Mandatory) + if ((decoded = decode_nas_key_set_identifier(&msg.ngKSI, 0, buffer->buf[decoded])) < 0) { + LOG_E(NAS, "decode_nas_key_set_identifier failure in NAS Authentication Request handling\n"); + return; + } + size += decoded; + if (!nas->ksi) { + nas->ksi = malloc_or_fail(sizeof(*nas->ksi)); + *nas->ksi = msg.ngKSI.naskeysetidentifier; + LOG_D(NAS, "Stored NAS Key Set Identifier %d\n", *nas->ksi); + } else if (*nas->ksi == msg.ngKSI.naskeysetidentifier) { + /* If the ngKSI value received is already associated with one + of the 5G security contexts stored in the UE, send failure message */ + LOG_E(NAS, "Invalid NAS Key Set Identifier: send Authentication Failure\n"); + generateAuthenticationFailure(nas, initialNasMsg, ngKSI_already_in_use); + return; + } + generateAuthenticationResp(nas, initialNasMsg, buffer->buf); +} + int nas_itti_kgnb_refresh_req(instance_t instance, const uint8_t kgnb[32]) { MessageDef *message_p; @@ -1735,9 +1770,11 @@ void *nas_nrue(void *args_p) case FGS_IDENTITY_REQUEST: generateIdentityResponse(&initialNasMsg, *(pdu_buffer + 3), nas->uicc); break; - case FGS_AUTHENTICATION_REQUEST: - generateAuthenticationResp(nas, &initialNasMsg, pdu_buffer); + case FGS_AUTHENTICATION_REQUEST: { + byte_array_t buffer = {.buf = pdu_buffer, .len = pdu_length}; + handle_fgmm_authentication_request(nas, &initialNasMsg, &buffer); break; + } case FGS_SECURITY_MODE_COMMAND: handle_security_mode_command(nas, &initialNasMsg, pdu_buffer, pdu_length); break; diff --git a/openair3/NAS/NR_UE/nr_nas_msg.h b/openair3/NAS/NR_UE/nr_nas_msg.h index c4f1d04e28..4be7222920 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg.h +++ b/openair3/NAS/NR_UE/nr_nas_msg.h @@ -102,6 +102,8 @@ typedef struct { int t3448; // Timer t3446 in seconds (-1 = disabled) int t3446; + /* NAS Key Set Identifier associated to the security context */ + uint8_t *ksi; } nr_ue_nas_t; nr_ue_nas_t *get_ue_nas_info(module_id_t module_id);